Monday, March 26, 2012

Wilcos ProgressBar Demo

I've been looking overWilco's ProgressBar demo and fixed it up to work with the current version of ATLAS. It's running and I can call methods on the control doing the updating of the progress info, but I can't get the timer to fire on it.

Looking over the code I can't find anything wrong with - the interval is set and assigned to the timer, but the timer simply isn't firing - I see nothing with Fiddler and the internal onTimerTick event is never actually hit.

I have been testing the control with a little bit of JavaScript code to fire the timer and that works fine, but I can't seem to get the internal timer to fire and ping back to the Web Service. Anybody have any idea, why the timer isn't firing in the below code?

I'm hooking things up through code rather than using XmlScript for now.

+++ Rick --

<scripttype="text/javascript">

Sys.UI.ProgressBar =function(associatedElement) {

Sys.UI.ProgressBar.initializeBase(this, [associatedElement]);

this.element = associatedElement;

var _timer =new Sys.Timer();

var _progress = 0;

var _showPercentage =true;

var _serviceURL;

var _serviceMethod;

var _responsePending;

var _tickHandler;

this.get_progress =function() {

return _progress;

}

this.set_progress =function(value) {

if (value >= 100) {

_timer.set_enabled(false);

}

_progress = value;

this.element.style.width = value.toString() +"%";

if (_showPercentage && value > 5)

this.element.innerHTML = value +"% ";

}

this.set_showPercentage =function(value) {

_showPercentage = value;

}

this.get_showPercentage =function() {

return _showPercentage;

}

this.get_interval =function() {

return _timer.get_interval();

}

this.set_interval =function(value) {

_timer.set_interval(value);

}

this.get_serviceURL =function() {

return _serviceURL;

}

this.set_serviceURL =function(value) {

_serviceURL = value;

}

this.get_serviceMethod =function() {

return _serviceMethod;

}

this.set_serviceMethod =function(value) {

_serviceMethod = value;

}

this.getDescriptor =function() {

var td = Sys.UI.ProgressBar.callBaseMethod(this,'getDescriptor');

td.addProperty('interval', Number);

td.addProperty('progress', Number);

td.addProperty('serviceURL', String);

td.addProperty('serviceMethod', String);

td.addMethod('start');

td.addMethod('stop');

return td;

}

this.initialize =function() {

Sys.UI.ProgressBar.callBaseMethod(this,'initialize');

_tickHandler = Function.createDelegate(this,this._onTimerTick);

_timer.tick.add(_tickHandler);

this.set_progress(0);

}

this.dispose =function() {

if (_timer) {

_timer.tick.remove(_tickHandler);

_tickHandler =null;

_timer.dispose();

}

_timer =null;

Sys.UI.ProgressBar.callBaseMethod(this,'dispose');

}

this.start =function() {

_timer.set_enabled(true);

}

this.stop =function() {

_timer.set_enabled(false);

}

this._onTimerTick =function(sender, eventArgs) {

alert('timer tick');

if (!_responsePending) {

_responsePending =true;

Sys.Net.ServiceMethodRequest.callMethod(_serviceURL, _serviceMethod,null, _onMethodComplete,null,null, [this]);

}

}

function _onMethodComplete(result, response, context) {

var behavior = context[0];

behavior.set_progress(result);

_responsePending =false;

}

}

Type.registerSealedClass('Sys.UI.ProgressBar', Sys.UI.Control);

Sys.TypeDescriptor.addType('script','progressBar', Sys.UI.ProgressBar);

</script>

<scripttype="text/javascript">

var Progress =new Sys.UI.ProgressBar($('ProgressBar'));

function ShowProgress()

{

SimpleService.InitializeProgressInfo(0);

Progress.set_interval(2000);

Progress.set_serviceURL("atlas/simpleservice.asmx");

Progress.set_serviceMethod("ProgressInfo");

Progress.start();

Progress.set_progress(5);

//StartProcessing();

}

function StartProcessing()

{

SimpleService.ProgressInfo(-1,StartProcessingCallback);

}

function StartProcessingCallback(Result)

{

Progress.set_progress(Result);

if (Result < 100)

window.setTimeout('StartProcessing();',1000);

}

</script>

Duh...

The code is missing a call to Initialize() to start the timer and other initialization going. It seems kinda silly that Initialize() isn't called automatically when in construct the object.

The progress stuff works, but I can't get the Web Service stuff to work - the ServiceMethodRequest object has changed and no longer supports calling the Web Service with simple parameters.

If anybody has any idea on that that'd be great.

The docs still suck - without knowing what parameters mean they're not terribly useful.

+++ Rick --


The way you invoke service methods has changed a little. The new signature looks like this:

invoke = function(url, methodName, params, onMethodComplete, onMethodTimeout, onMethodError, onMethodAborted, userContext, timeoutInterval, priority, useGetMethod)

Therefore, you should try to change

'Sys.Net.ServiceMethodRequest.callMethod(_serviceURL, _serviceMethod, null, _onMethodComplete, null, null, [this]);'

into

'Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, null, _onMethodComplete, null, null, null, [this]);'

Hey! This is just what I need, but how do I set the whole thing ablaze? I've created an upload page, which works fine. And I have a webservice which, based on the client IP, returns the current status of the process.

I've put the javascript progressbar directly in the aspx file, a div (class="progressBar") within a div (class="progressBarContainer") and the stylesheet classes from Wilcob's example. Furthermore I've set the serviceUrl to my webservice, and the servicemethod to my servicemethod.

When I run the page, the process runs thrugh just fine and uploads files, but I get an error on the page (in IE) refering to this line (marked with:*):

this

.set_progress =function(value)

{

*if (value >= 100)

{

_timer.set_enabled(

false);

}

_progress = value;

this.element.style.width = value.toString() +"%";if (_showPercentage && value > 5)this.element.innerHTML = value +"% ";

}

I've put the Initialize() in there like this:

Sys.UI.ProgressBar =

function(associatedElement)

{

Sys.UI.ProgressBar.initializeBase(

this, [associatedElement]);this.element = associatedElement;var _timer =new Sys.Timer();var _progress = 0;var _showPercentage =true;var _serviceURL;var _serviceMethod;var _responsePending;var _tickHandler;

_timer.Initialize()

And I've changed the Sys.Net.ServiceMethodRequest.callMethod as WilcoB mentioned above.

Any idea? Please help..

No comments:

Post a Comment