RobertFischer / JQuery-PeriodicalUpdater

A port of Prototype's PeriodicalUpdater to JQuery
282 stars 50 forks source link

Formatting issue #25

Closed k1mgy closed 12 years ago

k1mgy commented 12 years ago

In jquery.periodicalupdater.js: line 75: looks like this closing brace should be moved to just after the return handle call.

In the current version, without this mod, I get a brace matching error and settings cannot be found below boostPeriod.

Well. here's my mod (untested):

/**
* PeriodicalUpdater - jQuery plugin for timed, decaying ajax calls
*
* http://www.360innovate.co.uk/blog/2009/03/periodicalupdater-for-jquery/
* http://enfranchisedmind.com/blog/posts/jquery-periodicalupdater-ajax-polling/
*
* Copyright (c) 2009-2012 by the following:
*  Frank White (http://customcode.info)
*  Robert Fischer (http://smokejumperit.com)
*  360innovate (http://www.360innovate.co.uk)
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/

(function ($) {
    var pu_log = function (msg) {
        try {
            console.log(msg);
        } catch (err) { }
    };

    // Now back to our regularly scheduled work
    $.PeriodicalUpdater = function(url, options, callback, autoStopCallback){
        var settings = jQuery.extend(true, {
                url: url,         // URL of ajax request
                cache: false,     // By default, don't allow caching
                method: 'GET',    // method; get or post
                data: '',         // array of values to be passed to the page - e.g. {name: "John", greeting: "hello"}
                minTimeout: 1000, // starting value for the timeout in milliseconds
                maxTimeout: 8000, // maximum length of time between requests
                multiplier: 2,    // if set to 2, timerInterval will double each time the response hasn't changed (up to maxTimeout)
                maxCalls: 0,      // maximum number of calls. 0 = no limit.
                autoStop: 0,       // automatically stop requests after this many returns of the same data. 0 = disabled
                verbose: 0
            }, options);

        // set some initial values, then begin
        var timer = null;
        var timerInterval = settings.minTimeout;
        var maxCalls = settings.maxCalls;
        var autoStop = settings.autoStop;
        var calls = 0;
        var noChange = 0;
        var originalMaxCalls = maxCalls;

        var reset_timer = function (interval) {
            if (timer !== null) {
                clearTimeout(timer);
            }
            timerInterval = interval;
            // pu_log('resetting timer to ' + timerInterval + '.');
            timer = setTimeout(getdata, timerInterval);
        };

        // Function to boost the timer
        var boostPeriod = function () {
            if (settings.multiplier >= 1) {
                before = timerInterval;
                timerInterval = timerInterval * settings.multiplier;

                if (timerInterval > settings.maxTimeout) {
                    timerInterval = settings.maxTimeout;
                }
                after = timerInterval;
                // pu_log('adjusting timer from ' + before + ' to ' + after + '.');
                reset_timer(timerInterval);
            }
            after = timerInterval;
            pu_log('adjusting timer from '+ before +' to '+ after +'.',1);
            reset_timer(timerInterval);
        };

        // Construct the settings for $.ajax based on settings
        var ajaxSettings = jQuery.extend(true, {}, settings);
        if (settings.type && !ajaxSettings.dataType) { ajaxSettings.dataType = settings.type; }
        if (settings.sendData) { ajaxSettings.data = settings.sendData; }
        ajaxSettings.type = settings.method; // 'type' is used internally for jQuery.  Who knew?
        ajaxSettings.ifModified = true;

        var handle = {
            restart: function () {
                maxCalls = originalMaxCalls;
                calls = 0;
                reset_timer(timerInterval);
                return;
            },
            stop: function () {
                maxCalls = -1;
                return;
            }
        };      

        // Create the function to get data
        // TODO It'd be nice to do the options.data check once (a la boostPeriod)
        function getdata() 
        {
            var toSend = jQuery.extend(true, {}, ajaxSettings); // jQuery screws with what you pass in
            if (typeof (options.data) == 'function') {
                toSend.data = options.data();
                if (toSend.data) {
                    // Handle transformations (only strings and objects are understood)
                    if (typeof (toSend.data) == "number") {
                        toSend.data = toSend.data.toString();
                    }
                }
            }

            if (maxCalls === 0) {
                $.ajax(toSend);
            } else if (maxCalls > 0 && calls < maxCalls) {
                $.ajax(toSend);
                calls++;
            }
        };

        // Implement the tricky behind logic
        var remoteData = null;
        var prevData = null;

        ajaxSettings.success = function (data) {
            // pu_log("Successful run! (In 'success')");
            remoteData = data;
            // timerInterval   = settings.minTimeout;
        };

        ajaxSettings.complete = function (xhr, success) 
        {
            // pu_log("Status of call: " + success + " (In 'complete')");
            if (maxCalls === -1) { return; }
            if (success == "success" || success == "notmodified") {
                var rawData = $.trim(xhr.responseText);
                if (rawData == 'STOP_AJAX_CALLS') {
                    handle.stop();
                    return;
                }
                if (prevData == rawData) {
                    if (autoStop > 0) {
                        noChange++;
                        if (noChange == autoStop) {
                            handle.stop();
                            if (autoStopCallback) { autoStopCallback(noChange); }
                            return;
                        }
                    }
                    boostPeriod();
                } else {
                    noChange = 0;
                    reset_timer(settings.minTimeout);
                    prevData = rawData;
                    if (remoteData === null) { remoteData = rawData; }
                    // jQuery 1.4+ $.ajax() automatically converts "data" into a JS Object for "type:json" requests now
                    // For compatibility with 1.4+ and pre1.4 jQuery only try to parse actual strings, skip when remoteData is already an Object
                    if ((ajaxSettings.dataType === 'json') && (typeof (remoteData) === 'string') && (success == "success")) {
                        remoteData = JSON.parse(remoteData);
                    }
                    if (settings.success) { settings.success(remoteData, success, xhr, handle); }
                    if (callback) { callback(remoteData, success, xhr, handle); }
                }
            }
            if (settings.complete) { settings.complete(xhr, success); }
            remoteData = null;
        };      
        ajaxSettings.error = function (xhr, textStatus) 
        {
            pu_log("Error message: " + textStatus + " (In 'error')", 2);
            if(textStatus != "notmodified") {
                prevData = null;
                reset_timer(settings.minTimeout);
            }
            if(settings.error) { settings.error(xhr, textStatus); }
        };

        // Make the first call
        $(function () {
                if (settings.runatonce) {
                    getdata();
                } else {
                    reset_timer(timerInterval);
                }
        });

        return handle;
    };
})(jQuery);
RobertFischer commented 12 years ago

For real? Weird.

~~ Robert.

On Thu, Apr 12, 2012 at 10:07 AM, Mark Richards reply@reply.github.com wrote:

In jquery.periodicalupdater.js: line 75: looks like this closing brace should be moved to just after the return handle call.

In the current version, without this mod, I get a brace matching error and settings cannot be found below boostPeriod.


Reply to this email directly or view it on GitHub: https://github.com/RobertFischer/JQuery-PeriodicalUpdater/issues/25

k1mgy commented 12 years ago

On 4/12/2012 11:16 AM, Robert Fischer wrote:

For real? Weird.

~~ Robert.

Yes. Unless it's something else.

The modified code I posted works in testing here.

Very sweet stuff.

I am able to instantiate multiple instance of the updater, one for each data element to update, and they crank on nicely.

However, I am considering bundling an update event into a single call as I suspect my multiple approach will be a resource hog.

/m

RobertFischer commented 12 years ago

Fixed 93838d3