Clear/stop a periodic javascript process using Seaside?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Clear/stop a periodic javascript process using Seaside?

Paul DeBruicker
Hi -

Using jQuery/AJAX & Seaside 3.0.3 I'm trying to check for the results of
a calculation and when its complete update a div and then stop checking
without doing a full page refresh.  I can do everything but stop the
periodic process without doing a refresh

If I have an inst var named 'count' and do this:

renderContentOn: html
        (html div)
                id: 'replace';
                script:  ((html jQuery id:'replace')
                                        load html: [ :h |
                                                count := count + 1.
                                                (html div)
                                                id: 'replace';
                                                with: [ html render: 'count: ' , count greaseString ] ] ;
                                        interval: 2 seconds).

every two seconds the count is increased and then displayed.   If I use
replaceWith: I have the same problem.  The only thing I know to stop the
periodic process is to refresh the page and just render the results I
had been waiting on.

I would like to use AJAX, rather than refresh so I can do this in
several places on a single page.

Its my understanding that the setInterval function has an id that can be
sent to clearInterval but I don't know how to get the function id
through Seaside.  Is there a way to get that id and send it to
clearInterval or another way to do what I want?

Thanks


Paul
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Clear/stop a periodic javascript process using Seaside?

tfleig
+1

I would like to know the answer to this as ell.

TF

On Mon, Jan 31, 2011 at 12:44 PM, Paul DeBruicker <[hidden email]> wrote:

> Hi -
>
> Using jQuery/AJAX & Seaside 3.0.3 I'm trying to check for the results of a
> calculation and when its complete update a div and then stop checking
> without doing a full page refresh.  I can do everything but stop the
> periodic process without doing a refresh
>
> If I have an inst var named 'count' and do this:
>
> renderContentOn: html
>        (html div)
>                id: 'replace';
>                script:  ((html jQuery id:'replace')
>                                        load html: [ :h |
>                                                count := count + 1.
>                                                (html div)
>                                                id: 'replace';
>                                                with: [ html render: 'count:
> ' , count greaseString ] ] ;
>                                        interval: 2 seconds).
>
> every two seconds the count is increased and then displayed.   If I use
> replaceWith: I have the same problem.  The only thing I know to stop the
> periodic process is to refresh the page and just render the results I had
> been waiting on.
>
> I would like to use AJAX, rather than refresh so I can do this in several
> places on a single page.
>
> Its my understanding that the setInterval function has an id that can be
> sent to clearInterval but I don't know how to get the function id through
> Seaside.  Is there a way to get that id and send it to clearInterval or
> another way to do what I want?
>
> Thanks
>
>
> Paul
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
>
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Clear/stop a periodic javascript process using Seaside?

Johan Brichau-2
In reply to this post by Paul DeBruicker
You can assign the id that is returned by setInterval() to a global variable and call clearInterval() whenever you want to.

The best thing to do in this case is use an external javascript file where you declare the (global) variable that should keep the reference id (at least) and also the functions that will register the id and cancel the periodic update. You then call these functions from within the Seaside-generated javascripts. Although you can probably make it work without the external javascript file, it's better practice imho. Here's what I would do:

var updateId;
function registerAndSetInterval(aLambda,ms) {
        updateId = setInterval(aLambda,ms);
}
function unregisterInterval(){
        clearInterval(updateId);
}

Next, I'm a bit puzzled with your Seaside code. Doesn't that create a nested div inside the already existing div every 2 seconds? Since the load block creates another div with the same id, you will run into problems. You also need to use the canvas object that is passed to the html load block instead. Here is what I make of it:

renderContentOn: html
        (html div)
                id: 'replace';
                script:  (JSStream on: 'registerAndSetInterval')
                                        call: ''
                                        with: ((html jQuery id:'replace')
                                                                load html: [ :h |
                                                                                        count := count + 1.
                                                                                        h render: 'count: ' , count greaseString ]) asFunction
                                        with: 2000

Calling a javascript function from Seaside-generated javascript is a bit awkward using the #call:with: because it was designed to be sent to a receiver object (such as jQuery instance). But I don't think there's another way to call them from Seaside-generated javascript.

Hope it works, if not: please let me know ;-)

Johan

On 31 Jan 2011, at 21:44, Paul DeBruicker wrote:

> Hi -
>
> Using jQuery/AJAX & Seaside 3.0.3 I'm trying to check for the results of a calculation and when its complete update a div and then stop checking without doing a full page refresh.  I can do everything but stop the periodic process without doing a refresh
>
> If I have an inst var named 'count' and do this:
>
> renderContentOn: html
> (html div)
> id: 'replace';
> script:  ((html jQuery id:'replace')
> load html: [ :h |
> count := count + 1.
> (html div)
> id: 'replace';
> with: [ html render: 'count: ' , count greaseString ] ] ;
> interval: 2 seconds).
>
> every two seconds the count is increased and then displayed.   If I use replaceWith: I have the same problem.  The only thing I know to stop the periodic process is to refresh the page and just render the results I had been waiting on.
>
> I would like to use AJAX, rather than refresh so I can do this in several places on a single page.
>
> Its my understanding that the setInterval function has an id that can be sent to clearInterval but I don't know how to get the function id through Seaside.  Is there a way to get that id and send it to clearInterval or another way to do what I want?
>
> Thanks
>
>
> Paul
> _______________________________________________
> seaside mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Clear/stop a periodic javascript process using Seaside?

Paul DeBruicker
In reply to this post by Paul DeBruicker
Thanks Johan.

I hadn't considered using an external javascript file.  In your example
js file I'd have to call unregisterInterval() to clear the interval.  If
I created multiple intervals on the same page, would the correct one get
cleared without passing unregisterInterval the correct value for
updateId?  My knowledge of JS is less than Smalltalk.


I think I can figure out how to store the updateId using the
jQuery.data() function on the DOM element that is updating then send the
clearInterval with the result of the calculation and have it get the
updateId from the DOM element.

       
I think it'd be something like this:

function registerAndSetInterval(aLambda, ms, anElement){
        var updateId;
        updateId := setInterval(aLambda, ms);
        $.data(anElement, "intervalId", updateId);
}

funtion unregisterInterval(anElement){
        var clearId;
        clearId:= $.data(anElement, "intervalId");
        clearInterval(clearId);
}

But I'd probably want some kind of timeout in the first function so it
stops if the connection drops or something goes haywire.


Thanks for the heads up on the renderContentOn: method I posted.  I had
it in the email using replaceWith: and switched to load html: in an
attempt to simplify the problem illustration.


Paul


On 02/01/2011 07:00 AM, [hidden email] wrote:

> Message: 4
> Date: Tue, 1 Feb 2011 08:34:46 +0100
> From: Johan Brichau<[hidden email]>
> Subject: Re: [Seaside] Clear/stop a periodic javascript process using
> Seaside?
> To: Seaside - general discussion<[hidden email]>
> Message-ID:<[hidden email]>
> Content-Type: text/plain; charset=us-ascii
>
> You can assign the id that is returned by setInterval() to a global variable and call clearInterval() whenever you want to.
>
> The best thing to do in this case is use an external javascript file where you declare the (global) variable that should keep the reference id (at least) and also the functions that will register the id and cancel the periodic update. You then call these functions from within the Seaside-generated javascripts. Although you can probably make it work without the external javascript file, it's better practice imho. Here's what I would do:
>
> var updateId;
> function registerAndSetInterval(aLambda,ms) {
> updateId = setInterval(aLambda,ms);
> }
> function unregisterInterval(){
> clearInterval(updateId);
> }
>
> Next, I'm a bit puzzled with your Seaside code. Doesn't that create a nested div inside the already existing div every 2 seconds? Since the load block creates another div with the same id, you will run into problems. You also need to use the canvas object that is passed to the html load block instead. Here is what I make of it:
>
> renderContentOn: html
> (html div)
> id: 'replace';
> script:  (JSStream on: 'registerAndSetInterval')
> call: ''
> with: ((html jQuery id:'replace')
> load html: [ :h |
> count := count + 1.
> h render: 'count: ' , count greaseString ]) asFunction
> with: 2000
>
> Calling a javascript function from Seaside-generated javascript is a bit awkward using the #call:with: because it was designed to be sent to a receiver object (such as jQuery instance). But I don't think there's another way to call them from Seaside-generated javascript.
>
> Hope it works, if not: please let me know;-)
>
> Johan

_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Clear/stop a periodic javascript process using Seaside?

Johan Brichau-2
Hi Paul,

On 01 Feb 2011, at 15:18, Paul DeBruicker wrote:

> If I created multiple intervals on the same page, would the correct one get cleared without passing unregisterInterval the correct value for updateId?  My knowledge of JS is less than Smalltalk.

No, because the id is in a global variable, there can only be one. But you can use a javascript array as a dictionary where the key is the id of the DOM element and the value is the interval id.

> I think I can figure out how to store the updateId using the jQuery.data() function on the DOM element that is updating then send the clearInterval with the result of the calculation and have it get the updateId from the DOM element.

Yes, that would probably work too, and maybe is even cleaner.

cheers
Johan_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Clear/stop a periodic javascript process using Seaside?

Intrader Intrader
In reply to this post by Paul DeBruicker
Seems to me that the solution lies with AJAX and ajaxComplete.

With AJAX get the request going to compute whatever (in your example the next
value of count). This request is asynchronous and your UI continues as normal.
When the AJAX request finishes, ajaxComplete is executed.
This event handler can update count in the UI as appropriate.
For completeness your should also have a ajaxError handler.
I have done this sort of coding with jQuery and javascript.

I have not found a simple example using Seaside; section 21.6.2 still says
'TODO'.

I don't think there is a need for the interval timer; this sort of pattern
may be needed to implement something like a stock follower. Another way,
would be to use Comet.


_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: Clear/stop a periodic javascript process using Seaside?

Paul DeBruicker
In reply to this post by Paul DeBruicker
Thanks for the replies and pointers.  I went ahead and made this jQuery
plugin:

http://plugins.jquery.com/project/Registered-Interval

and then added it to the jQuery Widget Box on squeaksource.com.  It
stores the interval ID in the .data() function of a DOM element and then
retrieves from the DOM element when you want to clear the interval.

In the example I uploaded to SqueakSource there are three counters that
update independently of each other at different speeds using
setInterval.  Each can be started and stopped independently.  It does
what I want for now.

I wanted to have this as I'm using Futures for some stuff and need to
poll for results from multiple tabs on the same page and didn't want to
do a full page refresh when each tab had results.  It seems to work for
that purpose. I need to poll for results rather than let the Futures
block because I want to port what I've done to Gemstone and Dale's
recommendation was to poll for results rather than block.


I think the javascript code could be made more reliable and from what
I've read it'd be a better idea to use setTimeout recursively rather
than setInterval but I haven't gotten my head around that yet.

Thanks again

Paul
_______________________________________________
seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside