Wednesday, November 13, 2013

Mockjax and jQuery UI Progressbars

The Mockjax jQuery plugin let's us mock Ajax requests. It's really simply to use too. For example, I can use regular expressions to define URL paths for individual API requests, or I can define a catchall that returns a static response for every Ajax call made. What'ts also really interesting about Mockjax is that I have the freedom to dynamically generate my own responses for a given request. Writing jQuery UI applications usually means interacting with an API — and so this is an ideal too given it's simplicity. If your experiments go well, we need only replace the mock requests with a real back-end API.

Here's an example setup that updates a progressbar widget based on an API response. We setup a mock handler that simply increments the returned value with each subsequent call. Let's look at how this works.

var progress = 0;
    
$.mockjax({
    url: "/api/progress",
    responseTime: 250,
    dataType: "json",
    response: function( settings ) {
        progress += 5;
        this.responseText = { progress: progress };
    }
});

With approximately ten lines of code, we have a mock API. Here, the progress variable represents "server" data, that the UI will poll for. Each request increments the value before it is returned.

$( "#progressbar" ).progressbar({

    value: false,

    change: function( e, ui ) {
        var $this = $( this );   
        $this.find( ".progress-label" )
             .text( $this.progressbar( "value" ) + "%" );
    },
      
    complete: function () {
        $( this ).find( ".progress-label" )
                 .text( "Complete!" );
    }
       
});

Here's our progressbar widget. We give it a couple callbacks to update the label text.

function poll() {

    var deferred = $.ajax({
        url: "/api/progress",
        dataType: "json",
    });
        
    deferred.done(function( data ) {

        var value = data.progress,
            $progressbar = $( "#progressbar" );
           
        if ( value >= 100 ) {
            value = 100;
            $progressbar.progressbar( "value", value );
        } else {
            $progressbar.progressbar( "value", value );
            poll();
        }
            
    });

}

Last but not least comes our polling function, used to call our mock API for progress reports. The deferred variable represents the deferred promise object, returned from making a $.ajax() call. The done callback function is setup next, and this simply updates the progressbar value. Notice too that we explicitly check for values greater than 100, and normalize to 100, ensuring the complete event fires on the progressbar widget.