jQuery Document Ready…the sequel

My previous post jQuery Document Ready, the saga continues… got me thinking. Why not write a jQuery plugin which simulates a ready handler tied to an AJAX success handler. Let me explain.

Consider test1.html, view1.html and test1.js from the previous post:
test1.html

<html>
    <head>
        <title>Document Ready Demo</title>

        <script src = "jquery-1.4.2.js"></script>
        <script src = "test1.js"></script>

        <script>
            $(document).ready(function () {
                //make sure there is no caching to avoid confusion
                $.ajaxSetup({cache: false});

                $('#fetchView1').click(function () {
                    $.get('view1.html', function (data) {
                        $('#viewText1').html(data);
                    });
                });
            });
        </script>
    </head>

    <body>
        <button id = "fetchView1">Fetch View1</button>

        <div id = "viewText1">
            View1 content goes here
        </div>
    </body>
</html>

view1.html

<div>
   <input type="text" id="inputView1" value="Click button to fill with 1111" size="50" />
   <button id="buttonView1">Fill Input with number 1111</button>
</div>

test1.js

(function($) {
   $(document).ready(function(event) {

   console.log('test1.js document.ready executed');

   $('#buttonView1').click(function() {
        console.log('buttonView1 view clicked');
        $('#inputView1').val('1111');
   });
   console.log('buttonView1 button bound now');

//possibily more processing code and bindings

   });
})(jQuery);

Like I discussed, the intent of having the document.ready is that somehow it attaches itself to view1.html. Well it attaches itself to test1.html and because of this programmers resort to using live or liverquery. Again, nothing wrong with these tools but the penalty of freedom is performance overhead.

Ideally it would be nice if we could execute the JS code on AJAX success, rather automatically. Taking a cue and inspiration from the livequery plugin this is what I came up with:

jquery.jready.js

/*!
 * jQuery plugin jReady v1.0
 * https://phptouch.com/
 *
 * Copyright 2011, Jayesh Wadhwani
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: 31-July-2011
 */
(function($) {
    $.fn.jready = function(jreadyId, fn) {
        var j;
        //make a jready object
        j = new $.jready(this, jreadyId, fn);
        return this;
    };
    
    //jready function. Objects are made of this
    $.jready = function(context, jreadyId, fn) {
//        this.selector = selector;
        this.jreadyId = jreadyId;
        this.context = context || document;
        this.fn = fn;
        this.id = $.jready.fns.push(this) - 1;

        return this;
    };
    
    //function prototype
    $.jready.prototype = {
        //execute attached functions
        execute: function() { 
         var that = this; 
         this.context.each(function(){
            that.fn.apply(this);   
         })
         
        }
    };

    $.extend($.jready, {
        fns: [], //jready objects collection
        //jready handler
        execute: function(event, xhr, settings) {
            //check if there is a jready id present in the url
            var match = /.+?jready=(\w+)[\?\&]?/ig.exec(settings.url);

            if (match !== null) {
                var jreadyId = match[1] || null;
                //if there is a jready toke/id present then 
                //check if in the collection and execute the handler
                //in the object
                if (jreadyId) {
                    $.each($.jready.fns, function(index, fn) {
                        if (fn.jreadyId == jreadyId) {
                            fn.execute();
                            return false;
                        };
                    });
                }
            }
        },
        //bind the global ajax success
        bind: function() { $(document).ajaxSuccess($.jready.execute); }
    });
    // //bind the global ajax success when dom is ready
    $(function() { $.jready.bind(); });
})(jQuery);

I will explain the internals of the plugin in a minute.

Using this plugin test1.js now contains:

(function($) {
   $(document).jready('view1', function(event) {
      console.log('test1.js-view1 jready executed');    
      
      $('#buttonView1').click(function(){
         console.log('buttonView1 view clicked');
         $('#inputView1').val('1111');
      });
      console.log('buttonView1 button bound now');
      //event bidings
      
      //processing code
      
   });
})(jQuery);

Finally test1.html now contains:

<html>
    <head>
        <title>Document Ready Demo</title>

        <script src = "jquery-1.4.2.js"></script>
        <script src = "jquery.jready.js"></script>
        <script src = "test1.js"></script>

        <script>
            $(document).ready(function () {
                //make sure there is no caching to avoid confusion
                $.ajaxSetup({cache: false});

                $('#fetchView1').click(function () {
                    $.get('view1.html?jready=view1', function (data) {
                        $('#viewText1').html(data);
                    });
                });
            });
        </script>
    </head>

    <body>
        <button id = "fetchView1">Fetch View1</button>

        <div id = "viewText1">
            View1 content goes here
        </div>
    </body>
</html>

If I now run test1.html, no binding takes place. It only takes place when the AJAX call completes. Let me explain how that happens.

1. In the URL I have attached an identifying token, ‘view1.html?jready=view1. This token can be any alpha-numeric characters.

2. In test1.js I have replaced $(document).ready(function(event) with $(document).jready(‘view1’, function(event) . Note that the “event type” here is identical to the identifying token in the URL

3. When $(document).jready(‘view1’, function(event) is executed, all the plugin does is to store away the handler function in a function object which in turn is stored in an array.

4. Also note that the global handler ajaxSuccess at the end of the plugin code. The function attached to this event checks for a valid identifying token. If a valid token is detected then it iterates over all function objects looking for a match. If a match is found then it executes the jready handler.

I still have to work on the plugin, particularly in the area of error handling. But for now it should be enough to get you going.

Elementary I believe:-)

Happy Computing!

jQuery Document Ready, the saga continues…

Further to my earlier post jQuery Document Ready…use it wisely! one reader pointed out a different kind of architecture:

The html, test1.html:

<html>
    <head>
        <title>Document Ready Demo</title>

        <script src = "jquery-1.4.2.js"></script>
        <script src = "test1.js"></script>

        <script>
            $(document).ready(function () {
                //make sure there is no caching to avoid confusion
                $.ajaxSetup({cache: false});
                
                $('#fetchView1').click(function () {
                    $.get('view1.html', function (data) {
                        $('#viewText1').html(data);
                    });
                });
            });
        </script>
    </head>

    <body>
        <button id = "fetchView1">Fetch View1</button>

        <div id = "viewText1">
            View1 content goes here
        </div>
    </body>
</html>

When the button is clicked, an AJAX call is made. This call fetches the contents of view1.html and puts it in the div with id viewText1. Now let’s look at the view:

view1.html:

<div>
   <input type="text" id="inputView1" value="Click button to fill with 1111" size="50" />
   <button id="buttonView1">Fill Input with number 1111</button>
</div>


A very simple view file indeed. Just an input text field and a button. The objective being that when this button is clicked the event handler will fill the input field with '1111'. So where is the event binding and handler? That is in the included test1.js.

The included test1.js looks like this:

(function($) { 
   $(document).ready(function(event) {

   console.log('test1.js document.ready executed');

   $('#buttonView1').click(function() {
        console.log('buttonView1 view clicked');
        $('#inputView1').val('1111');
   });
   console.log('buttonView1 button bound now');

//possibily more processing code and bindings

   });
    
})(jQuery);

Note here that the button is attached to the click event handler which fills the input with '1111'. There is also a document.ready binding and its handler which will fire when the document is good and ready. The question is which document. The answer in a minute:-)

When I run test.html1 in a browser the console displays the following:

Console [1]= test1.js document.ready executed

Console [2]= buttonView1 button bound now

Now if I were to click on the button titled "Fetch View1" the AJAX call fires and the browser output should look something like this:

If you now click the button you probably expect to see the input box filled with '1111'. But when you do, nothing happens. However the console statement above does indicate that the button was bound!

The problem is that the binding in test1.js took place when the document.ready fired which was when test1.html was loaded. At this time view1 did not exist and obviously neither did the input field and the button. So the binding in test1.js was ineffective and of no use. Imagine 55 JS included files with an average of 5 binding in each and each file with a document.ready handler. Every handler firing when the outer document is loaded. Waste of resources!

The binding should actually take place after view1.html is loaded. Not fully understanding this concept programmers resort to using live event binding or the livequery plugin. Mind you, both these are superb tools but if used without proper understanding your application will suffer from severe performance issues.

Two simple solutions come to mind.

1. Put the JS code in view1.html wrapped in document ready.

<script>
 $(document).ready(function(event) {

   console.log('test1.js document.ready executed');

   $('#buttonView1').click(function() {
        console.log('buttonView1 view clicked');
        $('#inputView1').val('1111');
   });
   console.log('buttonView1 button bound now');


//possibily more processing code and bindings

   });
</script>
<div>
   <input type="text" id="inputView1" value="Click button to fill with 1111" size="50" />
   <button id="buttonView1">Fill Input with number 1111</button>
</div>

Remove the test1.js include from test1.html:

<html>
    <head>
        <title>Document Ready Demo</title>

        <script src = "jquery-1.4.2.js"></script>

        <script>
            $(document).ready(function () {
                //make sure there is no caching to avoid confusion
                $.ajaxSetup({cache: false});

                $('#fetchView1').click(function () {
                    $.get('view1.html', function (data) {
                        $('#viewText1').html(data);
                    });
                });
            });
        </script>
    </head>

    <body>
        <button id = "fetchView1">Fetch View1</button>

        <div id = "viewText1">
            View1 content goes here
        </div>
    </body>
</html>

If you run this, you will see that the bindings work fine and the input field is filled with '1111' when the button is clicked. Reason being that jQuery considers view1.html as a document and fires the document.ready event when the view1.html DOM has loaded. Remember this will only work if you are using jQuery methods such as html, append etc. It will not work if you use core dom methods/properties such as innerHTML.

2. Make test1.js a function call.

You could also change test1.js as a function and call it after the AJAX call completes like so:

test1.js will now contain:

function test1(){ 
   console.log('test1.js function executed');

   $('#buttonView1').click(function() {
        console.log('buttonView1 view clicked');
        $('#inputView1').val('1111');
   });
   console.log('buttonView1 button bound now');

//possibily more processing code and bindings
}

test1.html will now become:

<html>
    <head>
        <title>Document Ready Demo</title>

        <script src = "jquery-1.4.2.js"></script>
        <script src = "test1.js"></script>

        <script>
            $(document).ready(function () {
               $.ajaxSetup({cache: false});
               
                $('#fetchView1').click(function () {
                    $.get('view1.html', function (data) {
                        $('#viewText1').html(data);
                        test1();
                    });
                });
            });
        </script>
    </head>

    <body>
        <button id = "fetchView1">Fetch View1</button>

        <div id = "viewText1">
            View1 content goes here
        </div>
    </body>
</html>

and finally view1.html will go back to its original form:

<div>
   <input type="text" id="inputView1" value="Click button to fill with 1111" size="50" />
   <button id="buttonView1">Fill Input with number 1111</button>
</div>

If you now run test1.html it will work as expected. Note the function call test1.js() after the AJAX call completes.

This is only the beginning. I am sure you have thought of other ways of doing this. My main purpose however of writing this post is to emphasize not to use document.ready, live bindings or livequery before fully understanding as to what is involved. For everything there is a purpose and a matching tool. Be prudent and pragmatic.

Happy programming!

Regular Expressions, the Faster, Simpler Alternative

Sometime back I came across the following snippet:

function containsBadChars(str){
      if ((str.indexOf("\#") != -1) ||
          (str.indexOf("\&") != -1) ||
          (str.indexOf("\=") != -1) ||
          (str.indexOf("\\") != -1) ||
          (str.indexOf("\?") != -1) ||
          (str.indexOf("\:") != -1) ||
          (str.indexOf("\;") != -1) ||
          (str.indexOf("\'") != -1) ||
          (str.indexOf("\"") != -1) ||
          (str.indexOf("\[") != -1) ||
          (str.indexOf("\]") != -1) ||
          (str.indexOf("\{") != -1) ||
          (str.indexOf("\}") != -1)){
              return true;
          } else{
              return false;
          }
       };

This functions checks the existence of any of the following characters ‘#’, ‘&’, ‘=’, ‘\\’, ‘?’, ‘:’, ‘;’, ‘\”, ‘”‘, ‘[‘, ‘]’, ‘{‘, ‘}’ and returns true if found.

Using Regular Expressions we can modify this function in a more elegant one like this:

function containsBadCharsRegex(str){
      return /[\#\&\=\\\?\:\;\'\"\[\]\{\}]/.test(str);
};

Every time I talk about elegance with programmers they point out the performance gain/loss issue. A valid concern. So I did a performance test. Here is the code I used:

<html>
<head>
<title>Regex Demo</title>
<head>
   
<script>
    //in-elegant but functionally operational function
    function containsBadChars(str){
      if ((str.indexOf("\#") != -1) || 
          (str.indexOf("\&") != -1) || 
          (str.indexOf("\=") != -1) || 
          (str.indexOf("\\") != -1) ||
          (str.indexOf("\?") != -1) || 
          (str.indexOf("\:") != -1) || 
          (str.indexOf("\;") != -1) || 
          (str.indexOf("\'") != -1) || 
          (str.indexOf("\"") != -1) || 
          (str.indexOf("\[") != -1) || 
          (str.indexOf("\]") != -1) || 
          (str.indexOf("\{") != -1) || 
          (str.indexOf("\}") != -1)){
              return true; 
          } else{ 
              return false;
          }
       };
       
    //elegant and functionally operational function   
    function containsBadCharsRegex(str){
      return /[\#\&\=\\\?\:\;\'\"\[\]\{\}]/.test(str);
    };
    
    //List of test characters
    //Last four are valid characters
    //first 13 bad characters
    var testCharacters = ['#', '&', '=', '\\', '?', ':', ';', '\'', '"', '[', ']', '{', '}', '$', 'H', '1', '*']; 
   
    console.log('Testing the long way:');
    console.profile() 
    //check each character
    for(var i in testCharacters){
      //create the test string
      var str = "The quick brown fox quickly jumped over the lazy dog. This is the " + testCharacters[i] + " for testing";
      var isValid = containsBadChars(str);
      //comment for profiling
      console.log('Long Way. Character: ' + testCharacters[i] + ' isValid: ' + isValid);
    }
    console.profileEnd()
    
    console.log('Testing the short(regex) way');
    console.profile() 
    for(var i in testCharacters){
      var str = "The quick brown fox quickly jumped over the lazy dog. This is the " + testCharacters[i] + " for testing";
      var isValid = containsBadCharsRegex(str);
      //comment for profiling
      console.log('Short(Regex) Way. Character: ' + testCharacters[i] + ' isValid: ' + isValid);
    }
    console.profileEnd()
    
</script>
</head>
<body>
</body>
</html>

First we need to make sure that they are functionally identical.

Running the program gives the following console log output:

Testing the long way:
Long Way. Character: # isValid: true
Long Way. Character: & isValid: true
Long Way. Character: = isValid: true
Long Way. Character: \ isValid: true
Long Way. Character: ? isValid: true
Long Way. Character: : isValid: true
Long Way. Character: ; isValid: true
Long Way. Character: ‘ isValid: true
Long Way. Character: ” isValid: true
Long Way. Character: [ isValid: true
Long Way. Character: ] isValid: true
Long Way. Character: { isValid: true
Long Way. Character: } isValid: true
Long Way. Character: $ isValid: false
Long Way. Character: H isValid: false
Long Way. Character: 1 isValid: false
Long Way. Character: * isValid: false

Testing the short(regex) way:
Short(Regex) Way. Character: # isValid: true
Short(Regex) Way. Character: & isValid: true
Short(Regex) Way. Character: = isValid: true
Short(Regex) Way. Character: \ isValid: true
Short(Regex) Way. Character: ? isValid: true
Short(Regex) Way. Character: : isValid: true
Short(Regex) Way. Character: ; isValid: true
Short(Regex) Way. Character: ‘ isValid: true
Short(Regex) Way. Character: ” isValid: true
Short(Regex) Way. Character: [ isValid: true
Short(Regex) Way. Character: ] isValid: true
Short(Regex) Way. Character: { isValid: true
Short(Regex) Way. Character: } isValid: true
Short(Regex) Way. Character: $ isValid: false
Short(Regex) Way. Character: H isValid: false
Short(Regex) Way. Character: 1 isValid: false
Short(Regex) Way. Character: * isValid: false

They are functionally equivalent. Now on to performance.

After commenting out the console.log statements the profiler gives the following output:

Testing the long way:
Profile (0.143ms, 17 calls)
containsBadChars 17 100% 0.143ms 0.143ms 0.008ms 0.002ms 0.067ms

Testing the short(regex) way:
Profile (0.047ms, 17 calls)
containsBadCharsRegex 17 100% 0.047ms 0.047ms 0.003ms 0.002ms 0.006ms

As you can see the Regex way is about 3 times faster.

Happy programming!

jQuery Document Ready…use it wisely!

jQuery has done an excellent job with the document .ready() function which allows us to accurately know when the DOM has been loaded so that we can begin processing our JavaScript code. Prior to this we had to rely on the windows onLoad event which tends to occur much later in the load cycle.

Usually, one ready handler per page or view is used as the document ready handler will parse/execute the code once the DOM has loaded. Having this handler process code not relevant to the document at hand would be wasting resources.

Unfortunately I have noticed that this facility is used freely and loosely, even when sometimes it is not required, under the guise of “just to be on the safe side”. Not using this function properly has an impact on the performance of the application.

Consider a very simple example. We have two JS files test1.js and test2.js which are respectively included in test1.php and test2.php. These files are shown below:

test1.php

<html>
<head>
   <title>Test 1</title>
   
   <script src="jquery-1.4.2.js"></script>   
   <script src="test1.js"></script>
</head>
<body>

<div id="testDiv1">
<?php
$rows = 100;
echo    '<table>';
for($i = 0; $i < $rows; $i++){
	echo "<tr>";
	echo " <td>{$i}</td>";
	echo "</tr>";
}
echo '</table>';
?>
</div>
</body>
</html>

and the JS include file test1.js:

(function($) {
   $(document).ready(function(event) {
      console.log('test1.js - Number of tr elements: ' + $('#testDiv1 table tr').length);    
      
      //assume event bindings
      
      //assume processing code
      
   });
})(jQuery);

When run, the php file prints out a table structure with 100 rows. When the DOM is loaded(the table structure in our case) the ready event fires and prints out a message on the console:
test1.js – Number of tr elements: 100

test2.php and test2.js are similar, except this one prints out the number of ‘td’ elements instead of tr.

test2.php

<html>
<head>
    <title>Test 2</title>
   
   <script src="jquery-1.4.2.js"></script>   
   <script src="test2.js"></script>
</head>
<body>

<div id="testDiv2">
<?php
$rows = 100;
echo    '<table>';
for($i = 0; $i < $rows; $i++){
	echo "<tr>";
	echo " <td>{$i}</td>";
	echo "</tr>";
}
echo '</table>';
?>
</div>
</body>
</html>

and the JS include file test2.js:

(function($) {
   $(document).ready(function(event) {
      console.log('test2.js - Number of td elements: ' + $('#testDiv2 table td').length);    
      
      //assume event bindings
      
      //assume processing code
      
   });
})(jQuery);

When run the console prints out:
test2.js – Number of td elements: 100

As long as each JS file with the ready function is included in its respective host file or view everything works as it should without any overlap or conflict. But life is not so simple.

To reduce page load times it is customary to join many files into one and then minify the resulting file. This takes away the performance degradation due to latency issues as only one file is loaded compared to many.

By the same token it is also advisable that JS code specific to a view or a page be loaded per page while common code be bundled together and minified. This leads to a highly efficient load which does not tax the resources and also keeps the latency issues to a minimum.

Recently I came across an open source project based on the MVC pattern which joined 55 JS files, with each file having its document ready function. This bundle included common and specific files. Let me illustrate to you how much of a performance impact this can make. Let’s join test1.js and test2.js into one file and call it test.js. I have not minified this file for the sake of clarity.

test.js

(function($) {
   $(document).ready(function(event) {
      console.log('test1.js - Number of tr elements: ' + $('#testDiv1 table tr').length);    
      
      //assume event bindings
      
      //assume processing code
      
   });
})(jQuery);

(function($) {
   $(document).ready(function(event) {
      console.log('test2.js - Number of td elements: ' + $('#testDiv2 table td').length);    
      
      //assume event bindings
      
      //assume processing code
      
   });
})(jQuery);

Also let’s modify test1.php to include this file:
test1.php

<html>
<head>
   <title>Test with joined JS file</title>
   
   <script src="jquery-1.4.2.js"></script>   
   <script src="test.js"></script>
</head>
<body>

<div id="testDiv1">
<?php
$rows = 100;
echo    '<table>';
for($i = 0; $i < $rows; $i++){
	echo "<tr>";
	echo " <td>{$i}</td>";
	echo "</tr>";
}
echo '</table>';
?>
</div>
</body>
</html>

If we now run this we get the following on the console:
Console [5]=
test1.js – Number of tr elements: 100

Console [6]=
test2.js – Number of td elements: 0

Notice that there are two document ready handlers in test.js, and both ran. This is because when the DOM loads they cannot distinguish a relevant file from an irrelevant one. The first message is valid as it relates to test1.php but the second is not, as it relates to test2.php. This means the effort put in by the JS engine for the second handler was a waste.

Usually the document ready handler does not contain a simple log message, but a slew of event bindings and other JS code. Some of the files in the aforementioned project had close to a dozen event bindings. Even if we were to assume an average of five event bindings per file, that’s 275 bindings. Take into account event bubbling, live bindings and we are talking serious performance problems.

In such circumstances we cannot rescue everything but we can inject a little saving grace.

Here is the same test1.php and test.js with changes, which I will explain in a minute:

test1.php

<html>
<head>
   <title>Test with joined JS file</title>
   
   <script src="jquery-1.4.2.js"></script>   
   <script src="test.js"></script>
</head>
<!-- Note the new title attribute -->
<body title="test1">

<div id="testDiv1">
<?php
$rows = 100;
echo    '<table>';
for($i = 0; $i < $rows; $i++){
	echo "<tr>";
	echo " <td>{$i}</td>";
	echo "</tr>";
}
echo '</table>';
?>
</div>
</body>
</html>

Notice that in the body tag I have added a title attribute.

test.js

(function($) {
   $(document).ready(function(event) {
      //check if for this handler ***NEW****
      var title = $('body').attr('title');
      if(title !== 'test1'){
         return false;
      };
      console.log('test1.js - Number of tr elements: ' + $('#testDiv1 table tr').length);    
      
      //assume event bindings
      
      //assume processing code
      
   });
})(jQuery);

(function($) {
   $(document).ready(function(event) {
      //check if for this handler ***NEW***
      var title = $('body').attr('title');
      if(title !== 'test2'){
         return false;
      };
      console.log('test2.js - Number of td elements: ' + $('#testDiv2 table td').length);    
      
      //assume event bindings
      
      //assume processing code
      
   });
})(jQuery);

If you run this now you will get the following in the console:
test1.js – Number of tr elements: 100

Let me explain why.

In test.php I have added a title attribute which identifies this file

In the JS file I have added the following code in the document ready handler:
//check if for this handler
var title = $(‘body’).attr(‘title’);
if(title !== ‘test1’){
return false;
};

It only continues to processes the handler code if the title attribute matches “test1”. So the handler connected with test2 never continues which saves resources.

The crux of the idea is to make processing relevant to the document at hand. This is only one way of doing it. Many other ways come to mind and I leave them to your imagination.

I hope this helps you and I look forward to your feedback.

Option to select specific tab after removal in jQuery UI.TABS

One of the problems with the remove method of jquery ui.tabs is that after deleting the tab it either selects the tab on the right or if it is the last tab it selects one on the left.

My initial impression was that I could change this behavior by calling the select method in the ‘tabsremove’ event. But that does not work as the default selection takes place before the event is fired as indicated in the source below:

    remove: function( index ) {
                index = this._getIndex( index );
                var o = this.options,
                    $li = this.lis.eq( index ).remove(),
                    $panel = this.panels.eq( index ).remove();
              //DEFAULT SELECTION TAKES PLACE HERE
                // If selected tab was removed focus tab to the right or
                // in case the last tab was removed the tab to the left.
                if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
                    this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
                }
                o.disabled = $.map(
                    $.grep( o.disabled, function(n, i) {
                        return n != index;
                    }),
                    function( n, i ) {
                        return n >= index ? --n : n;
                    });
                this._tabify();
              //EVENT FIRED HERE
                this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
                return this;
            },

So that I could better control as to what was selected after tab removal I over-rode the remove function like so:

$.extend( $.ui.tabs.prototype, {
        remove: function( index, nextIndex) {
              var o = this.options;
         
             index = this._getIndex( index );
         
          //if nextIndex passed use it or use use the default which is follows:
          //If selected tab was removed focus tab to the right or
            //in case the last tab was removed the tab to the left.
          if(nextIndex !== undefined){
             nextIndex = this._getIndex(nextIndex);
          }else{
             if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
                   nextIndex = index + ( index + 1 < this.anchors.length ? 1 : -1 );
             }
          };
        
            //remove this tab
          $li = this.lis.eq( index ).remove();
            $panel = this.panels.eq( index ).remove();
         
        
          //select the next tab
          this.select(nextIndex);
          //make sure to remove the removed tab index
          //from the disabled list
            o.disabled = $.map(
                $.grep( o.disabled, function(n, i) {
                    return n != index;
                }),
                function( n, i ) {
                    return n >= index ? --n : n;
                });
          this._tabify();
            this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
         
            return this;
        }
});

USAGE:
.tabs( “remove” , index, nextIndex )
Example:
$tabs.tab(“remove”, 2, 5); //This would remove tab at index 2 and then select tab at index 5

I hope it helps someone and I look forward to everyone’s feedback.

Also replicated on the jQuery Forum:
http://forum.jquery.com/topic/ui-tabs-remove-method-additional-option-to-select-sepecific-tab-after-removal

Multiple replacements with JavaScript Regular Expressions

Recently I came across a piece of code using the replace command. Looking at the code I got the feeling that the author was not very comfortable with Regex replacements. Here is the snippet which I have modified slightly to explain my point.

<!DOCTYPE html>
<html>
<head>
<script src="jquery-1.4.2.js"></script>
<script language = "JavaScript" type = "text/javascript">

  $(document).ready(function (){
      
      var text = [];
      text.push('Suddenly, the wolf appeared beside her. "What are you doing out here, little girl?"\n');
      text.push('the wolf asked in a voice as friendly as he could muster.\n');
      text.push('I\'m on my way to see my Grandma who lives through the forest, near the brook,"  Little Red Riding Hood replied.');
      
      var postdata = [];   
      var re = new RegExp("\n");
      var re1 = new RegExp("[.]", "g");
      var re2 = new RegExp("[,]", "g");
      var re3 = new RegExp("[?]", "g");
      var re4 = new RegExp("[!]", "g");
      var re5 = new RegExp("[:]", "g");
      var re6 = new RegExp("[;]", "g");
      var re7 = new RegExp("[']", "g");
      var re8 = new RegExp('["]', "g");

      $.each(text, function(){
         var content = this.replace(re, ' ');
         content = content.replace(re1, '').replace(re2, '').replace(re3, '').replace(re4, '')
            .replace(re5, '').replace(re6, '').replace(re7, '').replace(re8, '');
         
         postdata.push(content);
      });

      //print it out
      for(var i in postdata){
         console.log('OLD: ' + postdata[i]);
      }
            
  });
</script>
</head>
<body>
<!-- some stuff -->
</body>
</html>

As is obvious all the above code does is replaces the character ‘\n’ with a space and characters dot, comma, question mark, exclamation, colon, semi-colon, single and double quotes with an empty string.

If you were to run this the output would be:
Console [7]=
OLD: Suddenly the wolf appeared beside her What are you doing out here little girl

Console [8]=
OLD: the wolf asked in a voice as friendly as he could muster

Console [9]=
OLD: Im on my way to see my Grandma who lives through the forest near the brook Little Red Riding Hood replied

Fortunately JavaScript’s Regex engine is quite robust and flexible and can pretty much take on any other Regex engines. So the above code can be written as follows:

<!DOCTYPE html>
<html>
<head>
<script src="jquery-1.4.2.js"></script>
<script language = "JavaScript" type = "text/javascript">

  $(document).ready(function (){
      
      var text = [];
      text.push('Suddenly, the wolf appeared beside her. "What are you doing out here, little girl?"\n');
      text.push('the wolf asked in a voice as friendly as he could muster.\n');
      text.push('I\'m on my way to see my Grandma who lives through the forest, near the brook,"  Little Red Riding Hood replied.');

      var postdata = [];
      var re = /['\n']/g;
      var re1 = /[\.\,\?\!\:\;\'\"\']/g;
      
      for(var i in text){
         var content = text[i].replace(re, ' ').replace(re1, '');
         postdata.push(content);
      };

       for(var i in postdata){
         console.log('NEW: ' + postdata[i]);
      }
      
  });
</script>
</head>
<body>
<!-- some stuff -->
</body>
</html>

The output is:

Console [10]=
NEW: Suddenly the wolf appeared beside her What are you doing out here little girl

Console [11]=
NEW: the wolf asked in a voice as friendly as he could muster

Console [12]=
NEW: I m on my way to see my Grandma who lives through the forest near the brook Little Red Riding Hood replied

As you can see it is much more elegant and many times faster. Also notice that instead of using the jQuery $.each iterator I have use the JavaScript for…in. This is much faster than $.each. I recommend that you use this whenever possible.

Detached…not quite!

jQuery 1.4 has a very helpful function ‘detach’ where I can detach a section and keep it away for later use. The best part is that it keeps all my bindings intact. But like anything else you need to watch out for caveats.

Consider the following example:


$(document).ready(function (){           

   //detach and keep the reference
   var $a = $('#div-abcde').detach();

   //try to change the value of one of the detached elements
   $('#abcde').val('5678');
   
   //attach it back
   $('#div-abcd').after($a);
   
   //output
   alert($('#abcde').val());
  });
<form id = "grid-3762" name = "grid" action = "">
     <div id="div-abcd"><input type="text" id="abcd" class="abcd" value="abcd" /> </div>
      <div id="div-abcde"><input type="text" id="abcde" class="abcd" value="abcde" /> </div>
</form>

This works as expected. The statement ‘$(‘#abcde’).val(‘5678′);’ has no effect as this element has been detached. So the output is as expected, that is ‘abcde’.

Now lets do the same example a little differently. Consider this:


$(document).ready(function (){           
    //keep a reference to the element.
    //remember this element wil be part of the detach
    var $r = $('#abcde');
   
   //detach and keep the reference
   var $a = $('#div-abcde').detach();

   //try to change the value using the reference
    $r.val('5678');
   
   //attach it back
   $('#div-abcd').after($a);
   
   //output
   alert($('#abcde').val());
  });

So what we are doing here that we are changing the value of the element by using a reference to the element. This is reference $r to the element.

Now the output is ‘5678’!

So even though it is detached it still maintains its references.

For everything there is a function!

JavaScript as you know is a functional language, meaning that functions are treated as ‘first class’ objects. They can be used as plain old functions, assigned to variables, passed in a parameters, created on the fly, extended and act and work as objects.

A PHP programmer who has been treating JavaScript as a supplementary language finds this variety of function construction and invocation a bit frustrating. To ease the pain here is a short essay.

There are three common ways of defining and invoking a JavaScript function.

The most common is the ‘Named function’ that we all know and love.

    //named or declarative function
    function myFn(someVar){
        alert('myFn executed - ' + someVar); 
   };
   
   //To invoke
    myFn(77);

The output is as expected: myFn executed – 77

Just to whet your appetite this simple function can have properties and methods and can be augmented using the prototype property.

The next method of declaring a function is as an expression or literal. Consider the following example:

//function expression or function literal
   var myFn2 = function(someVar){
      alert('Function executed - ' + someVar); 
   };
//to invoke
   myFn2(88);

The output in this case will be ‘Function executed – 88’

As you can see there is nothing special about this except that the variable myFn2 holds the reference to the function.

The third way of defining and invoking is using the constructor pattern.

//using the constructor
   function myFn3(someVar){
      alert('Function executed - ' + someVar); 
   };
//to invoke
   var myFnInstance = new myFn3(99);

The output in this case will be ‘Function executed – 99’

But, all said and done, these various function incarnations begs us the question…where should we be using each type, how and why?

One of my favorites is to pass a function as a parameter. This is something very powerful and its applications are only restricted by your imagination. Consider the following example:

 //Main function which accepts a function reference as an argument
   var myMainFn = function(someFunc){
      someFunc();
   };
  
   //A simple function expression
   var myFn1 = function(){
      alert('myFn1 executed');
       
   };
   
   myMainFn(myFn1);

The output is ‘myFn1 executed’!

Think about it. A main dispatch function which receives a function reference as an argument. We now have a dynamic function dispatch table.

My next favorite type is ‘Returning Functions’. Consider the following example:

//the main function
 var myReturningFn1 = function(someVar){
      alert(someVar);
      //returning function
      return function(){
         alert(++someVar);
      };
   }
   
   var returnFn = myReturningFn1(111);
   returnFn();

In this function rather than returning a variable it returns a reference to the function. In other words if I were to do this:

myReturningFn1(111);

the output would be ‘111’.

But by doing:
var returnFn = myReturningFn1(111);
we are getting a reference to the return function. And to execute all we do
returnFn() and the output would be 112.

I could have written the function like so:

 var myReturningFn1 = function(someVar){
      alert(someVar);
      
      var returnFn = function(){
         alert(++someVar);
      }; 
      return returnFn; 
   }
   
   var returnFn = myReturningFn1(111);
   returnFn();

However you must realize that the first way of writing is more in vogue.

Getting back to the first way of writing the function an astute reader will have realized that after doing:

var returnFn = myReturningFn1(111);

The function myReturningFn1 has finished and gone out of scope and so has the variable someVar! But when you now do

returnFn() it actaully increments someVar. Which means that even if the outer function has gone out of scope the inner function still has access to its variables. This is called a ‘closure’, one of the most important concepts of a functional language and a very powerful feature of JavaScript. In this case the outer function myReturnFn1 closes over the inner function resulting in a closure.

More than that, one of the most valuable qualities of the returning functions is that you on the outside do not have any access to the variables of the outer function. Only the returning or the inner function does. You may say they are private variables:-)

One typical pattern I love to use in my programs is:

var myReturningFn1 = function(someVar){
      alert(someVar);
      var someObj = {
        init: function(){
         alert('Init! - ' + ++someVar);
        } 
      };
      return someObj;
   }
   
   var returnFn = myReturningFn1(111);
   returnFn.init();

The output in this case is ‘Init! – 112’

This way I have my methods neatly tucked away and my private variable safeguarded from accidental changes.

Finally my next favorite is the ‘immediate functions’. Consider the following:

 (function myImmediateFn(){
      alert('Executed!');
   })();

The output will be ‘Executed!’

The beauty of this is that the function is declared, executed and then destroyed, all in in go. If you wanted to pass in a parameter then we could write this as:

Finally my next favorite is the ‘immediate functions’. Consider the following:

 (function myImmediateFn(someVar){
      alert('Executed! - ' + someVar);
   })(88);

The output will be ‘Executed! – 88’

This pattern is also called the (function(){})(); pattern.

This is used very often in plugins.

(function($) {
  //your plugin code
})(jQuery);

I tend to use this pattern quite a bit when I want my libraries to be initialized on load.

I hope this essay has created an appetite for more functional exploration.

If you plan to go ahead I must recommend these three books by JavaScript gurus!

1. Secrets of the JavaScript Ninja – John Resig
2. JavaScript Patterns – Stoyan Stefanov
3. JavaScript: The Good Parts – Douglas Crockford

A live binding fun fact

jQuery allows event delegation using .live().

When using jQuery there are instances where I have to bind my events to the document root, i.e. $(document). My impression was that ‘live’ should also work with this root. But it does not. Consider the following example.

<script language = "JavaScript" type = "text/javascript">
  $(document).ready(function (){

  $(document).bind('custom_event.am', function(){
      alert('Bind works with document root!');
   });
   
   $(document).trigger('custom_event.am');
  
  $(document).live('custom_event1.am', function(){
      alert('Live does not work with document root!');
   });
   
   $('#am_wrapper').trigger('custom_event1.am');
   
  });
  
</script>

But if we use anything other than the document root, there is no problem. Consider the following example.

<script language = "JavaScript" type = "text/javascript">
  $(document).ready(function (){

  $('#am_wrapper').live('custom_event1.am', function(){
      alert('Live now works!');
   });
   
   $('#am_wrapper').trigger('custom_event1.am');
   
  });
  

</script>
<div id = "am_wrapper">  </div>

To unravel the mystery I delved into the jQuery source code and concluded the following.

Live events are bound to the document root. So when a ‘live’ event fires it bubbles up to the document root. A special handler function first called(‘liveHandler’). Before it executes the custom(your) handler it makes an attempt to gather all the binding for the the said event. To do this it runs this statement:

match = jQuery( event.target ).closest( selectors, event.currentTarget );

This fails because ‘closest’ starts from the current element and moves upwards. As the target and current target both are the document root there is no where to go. As there are no matches(match.length === 0) the function exits without doing much.

Even if it wasn’t for this caveat I am not a big fan of binding my events to the root. Would prefer to reserve a top level element to store all my bindings.

Undefined is a special value not a string!

Recently I came across this statement

 if (val != 'undefined' && val != null && val != 'null') {
//some statements
}

undefined and null are simple types and not literal strings!

alert(null === ‘null’); will return false so will alert(undefined === ‘undefined’);

So the statement should be:

 if (val !== undefined && val !== null) {
//some statements
}