Saturday, August 7, 2010

smartupdater (jQuery periodicalupdater)

Smartupdater jQuery plugin performs periodical updating functionality and can be used in all sorts of applications which need “polling” mechanisms.

Features

Actions:
  • stop updating.
  • restart updating after stop.
  • dynamically reprogram current timeout
  • remotely set timeout ( server controls polling period )
Monitor:
  • state attribute shows current state ( ON | OFF | undefined )
  • timeout attribute shows current timeout
Smart Behavior:
  • smart updateing - updates only if new data is different from the old one (text or json only.)
  • multiplies polling interval - multiplies polling interval each time data is not changed (text or json only.)
  • handle ajax failures - stop to request data after "maxFailedRequests".

List of available functions

  • smartupdaterStop() - to stop polling
  • smartupdaterRestart() to run polling again
  • smartupdaterSetTimeout() - to set a new polling interval

List of available attributes

  • smartupdaterStatus.state current state ( ON | OFF | undefined )
  • smartupdaterStatus.timeout current timeout

List of available options

  • url - URL for the ajax request. (Required!)
  • type - Can be either GET or POST (see jQuery.ajax for details)
  • data - Array of values to be passed to the page (see jQuery.ajax for details)
  • dataType - Response type – can be text, xml, json etc. (see jQuery.ajax for details)
  • minTimeout - Starting value for the timeout in milliseconds.
  • maxTimeout - Maximum length of time between requests.
  • multiplier - Sets the amount of decay between ajax requests. If this is set to 2, the length of time between each request will double while the response doesn’t change.
  • maxFailedRequests - smartupdater stops after this number of consecutive ajax failures;

See demo at 

get source of smartupdater2 from:


Any questions, comments or suggestions are welcome :)

32 comments:

  1. Wow! This is just great :)

    ReplyDelete
  2. Hi Vadim,

    I reported an issue some weeks ago on the google code page. I don't know if you still maintain this project, or if you have abandoned it.
    It would be nice to know if I can hope for some assistance on this problem or if I must look for another solution.

    Best regards
    Mike

    ReplyDelete
  3. Hi Mike,
    sorry for delay.

    I noted your issue just a few days ago. Yes, still maintain this project, but my problem is: I have trouble with IE9 itself :) I wasn't able to install IE9 on my Windows computer and had to uninstall it. And obviously I can't fix it on my Linux system :) I'll fix it as soon as I find any computer with IE9. Sorry again

    ReplyDelete
  4. Hi

    Nice plugin!

    (1) Is there a way to suspend the automatic decay when the server's answer is always the same? I try multiplier = 1 but that did not work well.
    (2) what is the default value for maxFailedRequests? Would 0 disable the feature?
    thanks!

    Jean

    ReplyDelete
  5. Hi
    Are there any issues with having several smartupdaters on the same page?

    ReplyDelete
  6. to Jean:

    Thank you for good words, Jean:)

    1. multiplier=1 should work (which means polling interval doesn't depend on data from server). Please check syntax, maybe there is an error. You also can open the plugin source and set default multiplier to 1 (line #50: multiplier : 2, )

    2. Default maxFailedRequests=10; What do you mean "disable"? If you want to stop polling after thefirst error, set it to 0. If you don't want to stop poling even if you get error message from server, set it to max int (which is 2^31−1 for javascript) It's long enough :)

    To Anonymous (November 13, 2010 8:17 AM):

    It's OK to use several smartupdaters on the same page. I use such configuration in my project.

    ReplyDelete
  7. Hello Vadimk,

    About question 1.
    If you set multiplier to 1 and have the server return the same stuff, for instance nothing, then smartupdater stops sending requests to the server, which is not the expected behavior.
    I added this:
    93 else
    94 {
    95 es.periodicalUpdater = setTimeout(start, es.minTimeout);
    96 elem.smartupdaterStatus.timeout = es.minTimeout;
    97 callback(data);
    98 }

    What do you think?

    Jean

    ReplyDelete
  8. Thank you very much for your smart work which helps me a lot.

    Nathan.

    ReplyDelete
  9. To Anonymous (November 28, 2010 8:16 PM)

    Thank you for letting me know about this bug. Your solution works, but in case of multiplier=1 and data not changed we don't need to call callback function. I've fixed this bug for ver. smartupdater2_0_03.js this way:

    } else if (es.multiplier <= 1) {
    es.minTimeout = es.originalMinTimeout;
    elem.smartupdaterStatus.timeout = es.minTimeout;
    es.periodicalUpdater = setTimeout(start, es.minTimeout);
    }

    again, thank you for your help.

    ReplyDelete
  10. Fantastic, I've been looking for something like this.

    One question: for me, the ideal behaviour would be to configure intervals like this:

    1st poll: 5 seconds after page load
    2nd poll: 30 seconds after page load
    3rd poll: 90 seconds after page load
    4th poll: 300 seconds after page load

    etc. Maybe after the final delay there could be a set interval, such as "and every 300 seconds thereafter".

    Would that be possible with Smartupdater?

    ReplyDelete
  11. Hi. I have wrote something similar but your version is better :)

    Thanks :)

    ReplyDelete
  12. Hi,

    I needed to be able to update the "data" param of the ajax call in between updates without resetting the poller, in order to send a different variable to my server based on the data returned. So, I added the following function to the end of the file (before the ending jquery statement of course). Thought I'd share it:

    /* Updates the data of the smartupdater object
    * USAGE:
    * $("#myObject").smartupdater({
    * url : "demo.php",
    * data: variable,
    * minTimeout : 60000
    * }, function (data) {
    * //process data here;
    * //NEW: update the data;
    * $("#myObject").smartupdaterSetData(newVariable);
    * }
    * );
    */
    jQuery.fn.smartupdaterSetData = function (data) {
    return this.each(function() {
    var elem = this;
    this.settings.data = data;
    });
    };

    ReplyDelete
  13. To: Anonymous @ January 4, 2011 5:59 AM

    I'm afraid it's not possible to organize this pattern without redesigning code. But maybe I'll add "predefined pattern" feature in the near future. Not sure yet. I don't want to make this plugin too complex as people like simplicity :))

    ReplyDelete
  14. To Wesoła:

    I'm sure your version worked fine for you and you simply didn't need most of Smartupdater's features :)

    ReplyDelete
  15. To: Gabe Stein

    Thank you for sharing.

    ReplyDelete
  16. Is it possible to add a 'beforeSend' and 'complete' function as options?

    ReplyDelete
  17. Hi netcelli,
    sorry for delay.

    Yes, it's possible. I'll think about it. Thank you for your question.

    ReplyDelete
  18. For some reason I keep getting "xhr is undefined" error on line 80. Any ideas why this would be undefined?

    ReplyDelete
  19. As I don't see your code I can't answer the question, but my guess is: you may get the error if you use jsonp interface.

    ReplyDelete
  20. Hello vadim,

    "For some reason I keep getting "xhr is undefined" error on line 80. Any ideas why this would be undefined?"


    I have the same error.

    $("#newRecent").smartupdater({
    url : 'newest.php',
    minTimeout: 1000 // 10 seconds
    }, function (html) {
    alert(html);
    }
    );

    This is the function concerned

    in the file newest.php, i only do an echo "test";

    Do you have an idea of the solution of this error?

    And thanks for this plugin.

    JC from France

    ReplyDelete
  21. Sorry JC, I have no idea. I've searched google to find something similar, but with no success. It would be helpful if you provide more information about this bug: jQuery version, browser type, ajax setting, etc. which can help me to reproduce the bug. I've seen a few similar complains related to IE6/IE7, but again, very few ones.

    ReplyDelete
  22. Hi vadimk, I'm using your script and it goes good.
    I have just this problem:
    when I call smartupdaterStop();

    and restart the cicle using

    smartupdaterRestart();

    more then once,

    it seems that the cicle get a new instance, so I see not one polling but two subsequence polling.

    could you help me ?
    regards

    ReplyDelete
  23. Hi Anonymous,

    It can happen if smartupdaterStop() command is issued at the very moment when smartupdater is processing response. The issue is resolved in the latest version of smartupdater-3.0.01beta ( http://www.eslinstructor.net/smartupdater3/ )
    I would recommend to use this version. If you want to keep your current version, open source https://code.google.com/p/smartupdater/source/browse/trunk/smartupdater3/smartupdater-3.0.beta.js and make search on "stopFlag" to see how it's done in v.3.0.01 to prevent this problem.

    ReplyDelete
  24. HI vadim,

    I try to use the beta library, but the the flags semmes dont prevent the error:

    On click event I stop the process and then
    when ajax is complete, I restart the process.
    It works if I use it slow , but when I click very fast the process append two or more polling.

    The flag it necessary use as "false" ?
    I use as true in the library directly but the smartupdate dont start.

    Thanks in advance.
    ghena.


    $("#tg").smartupdaterStop();

    this.xhr = $.ajax({
    type: "GET",
    url: "../bidding/test.php",
    data:""
    dataType:'json',
    timeout:8000,
    complete :function(){

    $("#tg").smartupdaterRestart();

    }

    });

    ReplyDelete
  25. Hi ghena,

    here is your case:

    suppose your ajax takes 1 second, and your click events come in 0.5 sec.

    ------- 0 sec -------

    * click #1 comes.
    * smartupdaterStop() destroys current polling cycle ( clearTimeout(this.settings.h); )
    * ajax #1 is run

    ------- 0.5 sec -------

    * click #2 comes.
    * smartupdaterStop() tries to destroy current polling cycle ( clearTimeout(this.settings.h); ), but timeout handler this.settings.h already invalid and there is no polling cycle there.
    * ajax #2 is run.

    ------- 1.0 sec -------

    * ajax #1 callback calls smartupdaterRestart() which starts polling cycle #1

    ------- 1.5 sec -------

    * ajax #2 callback calls smartupdaterRestart() which starts polling cycle #2

    -------------------------

    hope this helps :)

    ReplyDelete
  26. Hi vadim , thanks for you reply.
    Now it works.

    Now I need to abort all request processing but not completed starts before my request ajax.

    for example:

    process0 done
    process1 done
    process2 called not completed
    ---- here I call ajax request on click and stop the process with smartupdaterStop() method.

    but process2 is still working

    I need to abort this process (process2).
    Infact smartupdaterStop() , stop the cicle but the previouse request are waiting to complete.

    sorry for "semmes" it was just " seems " :)

    ghena

    ReplyDelete
  27. You can customize this plugin:

    var xhr = $.ajax({...});

    and apply xhr.abort(); within smartupdaterStop() function or at any step you need to abort ajax.

    ReplyDelete
  28. it works but as a global variable.
    thanks.

    ghena

    ReplyDelete
  29. hey ghena,
    it should not be a global! Example above is just idea how to abort ajax, not actual implementation how to do it in this plugin.
    There is "es" object. Use it to keep and access this xhr object. See source how it's done for other vars in the plugin.

    good luck :)

    ReplyDelete