Wednesday, January 26, 2011

jQuery : Creating a tag cloud widget

Tag clouds are pretty common these days on most of the websites that we come across. Tag clouds are useful because not only are they better organised as compared to displaying plain lists, but they also provide visual cues to the user of the frequency of the a particular keyword relative to the other keywords in the cloud.

In this post, I am going to create a simple jQuery widget to create a tag cloud.

Lets look at the requirements first
For any dom element, we need to display a list of anchor elements.
For each anchor element, the relative font size should be directly proportional to the frequency of occurence of the element.

Here is how the requirements will translate into technical terms.

  1. Create an unordered list such that each list item represents a tag.
  2. The unordered list should be placed inside the selected container.
  3. The font-size of each list item is based upon the relative frequency of the tag. The tag with the minimum frequency should have a minimum font size of 1. The Tag of the maximum frequency should have a font size of 2em.

Lets look at the HTML markup first. In fact, since this is a cloud widget, we dont actualy need anu html except for a container that can hold he contents of the cloud.


Ok, that was simple. Thats because all the logic of building the list and its corresponding elements lies in widget.

Lets start with our standard way of creating a widget

(function($){
var tagcloudPrototype={
 options:{
 },
 _create:function(){
  console.log('create');
  var widget=this;
  var $domElement=widget.element;
  var options=widget.options;
 }
};

$.widget('ui.tagcloud',tagcloudPrototype);
})(jQuery);

As can be seen in the above code, all the functionality of the widget lies in the _create function itself which will be called once during widget initialization.

Let us create a few options for the user of our widget, such as providing the css styles for the links in the cloud. our widget basically requires as an argument, an array 'tag' objects that have a particular structure. We will define the structure of the tag in the options element so that it can be configured by the user as per his requirement.

As per our design, we will require that for each tag, three things must be given

  1. name : The name of the tag as it will appear as an anchor.
  2. freq : The number denoting the frequency of the tag.
  3. uri : The uri to which the user will be redirected to once he clicks on the tag anchor.

The values in the array can be obtained via an ajax query or any other way. Here is a sample array

var cloudtags = [
   { name: "Java", freq: "50" , url:"#"},
   { name: "CSS", freq: "53" , url:"#"},
   { name: "XHTML", freq: "27" , url:"#"},
   { name: "jQuery", freq: "71" , url:"#"},
   { name: "MySQL", freq: "35" , url:"#"}
   ];

And here is our options object.

options:{
  tagStructure:{name:'name',freq:'freq',url:'url'},
  linkClass:'tag-static',
  linkHoverClass:'tag-hover',
  tags:[]
 }

As you can see, each tag in the array follows the same structure. Ill show later how you can use the widget if the names in your tag sructure are different from the default. The default are 'name','freq' and 'url'.

Now, lets see what needs to be done in the create function. Sicne we need the size of the tags to be dependent upon the value of the frequency, we will simply scale down the maximum and minimum frequeny between 1 and 2. ie. in our sample cloudtag array, the min value is 27 and the max value is 71. So, we need to use 1em as the font size of the tag with name 'XHTML' and 2em as the font size of the tag with name 'jQuery'.

Once computed, for each element in teh array, we will store the value of the fontSize as a property of that particular tag object array and then we will use it later to set the value of the font-size css property of the anchors.

Here is the code in the _create() function that we will use to scale down the frequency values and store it on the tag object.

var widget=this;
  var $domElement=widget.element;
  var options=widget.options;
  
  var tags=options.tags;
  var name=options.tagStructure.name;
  var freq=options.tagStructure.freq;
  var url=options.tagStructure.url;
  
  var max=0,min;
  $.each(tags,function(index, tag){
   max = Math.max(max,tag[freq]);
  });
  min=max;
  $.each(tags,function(index, tag){
   min = Math.min(min,tag[freq]); 
  });
  
  
  var divisionUnit=(max-min)/10;
  
  $.each(tags, function(index, tag){
   var fontUnit=Math.round((tag[freq]-min)/divisionUnit);
   tag.fontSize=(fontUnit<10)?'1.'+fontUnit+'em':'2.0'+'em';
  });

Now, I am only left with a simple task of creating a new unordered list and adding list items with anchors to it. This list item should reside in the selected container, i.e. the current dom element of the widget. Here is how we do it.

$domElement.append("
    "); var $tagList = $('ul',$domElement); $.each(tags, function(index, tag){ $tagList.append('
  • '+ '' + tag[name]+''+ '
  • '); });

    As seen above, there is nothing special going on. All i do is iterate over each of the elements of the tags array, and crete list items and anchor tags with the calculated font-size for each of the tag. Now the last thing that I would do is to apply the user specified styles to the anchors. And thats very trivial.


    $('a',$domElement).hover(function(){   $(this).toggleClass(options.linkHoverClass);
      });
    
    $tagList.addClass('tag-cloud-ul');
      $('a',$domElement).hover(function(){
       console.log($(this));
       $(this).toggleClass(options.linkHoverClass);
       
      });
    

    Here is the entire widget as one big blob!

    (function($){
    var tagcloudPrototype={
     options:{
      tagStructure:{name:'name',freq:'freq',url:'url'},
      linkClass:'tag-static',
      linkHoverClass:'tag-hover',
      tags:[]
     },
     _create:function(){
      console.log('create');
      var widget=this;
      var $domElement=widget.element;
      var options=widget.options;
      
      var tags=options.tags;
      var name=options.tagStructure.name;
      var freq=options.tagStructure.freq;
      var url=options.tagStructure.url;
      
      //Scaling down the frequency to a range of 1 to 10 and determining the font size
      var max=0,min;
      $.each(tags,function(index, tag){
       max = Math.max(max,tag[freq]);
      });
      min=max;
      $.each(tags,function(index, tag){
       min = Math.min(min,tag[freq]); 
      });
      
      var divisionUnit=(max-min)/10;
      
      $.each(tags, function(index, tag){
       var fontUnit=Math.round((tag[freq]-min)/divisionUnit);
       tag.fontSize=(fontUnit<10)?'1.'+fontUnit+'em':'2.0'+'em';
      });
      
      //Creating the unordered list
      $domElement.append("
      "); var $tagList = $('ul',$domElement); //Adding list items and anchors for each tag in the array $.each(tags, function(index, tag){ $tagList.append('
    • '+ '' + tag[name]+''+ '
    • '); }); //Styling $tagList.addClass('tag-cloud-ul'); $('a',$domElement).hover(function(){ console.log($(this)); $(this).toggleClass(options.linkHoverClass); }); } }; $.widget('ui.tagcloud',tagcloudPrototype); })(jQuery);

      Here is the CSS that I am using.

      #tagContainer{
          width:200px;
          height:100px;
          overflow:hidden;
          background-color:#6c6c6c;
         }
         
         .tag-cloud-ul{
          list-style:none;
          margin:0px;
          margin-left:10px;
          margin-top:10px;
          padding:0px;
          width:100%;
          height:100%;
         }
         
         .tag-cloud-li{
          float:left;
          padding:5px;
          height:30px;
          margin:0px;
         }
         
         .tag-static{
          text-decoration:none;
          color:white;
         }
         
         .tag-hover{
          color:blue;
         }
      

      Okey. Thats our widget, now lets see how to use it. Ill show you two ways. the first one shown here uses the default tag structure.

      var cloudtags = [
         { name: "Java", freq: "50" , url:"#"},
         { name: "CSS", freq: "53" , url:"#"},
         { name: "XHTML", freq: "27" , url:"#"},
         { name: "jQuery", freq: "71" , url:"#"},
         { name: "MySQL", freq: "35" , url:"#"}
         ];
         
         $('#tagContainer').tagcloud({tags:cloudtags});
      

      The one shown below does uses a custom structure for the tags.

      var cloudtags = [
         { tagName: "Java", frequency: "50" , url:"#"},
         { tagName: "CSS", frequency: "53" , url:"#"},
         { tagName: "XHTML", frequency: "27" , url:"#"},
         { tagName: "jQuery", frequency: "71" , url:"#"},
         { tagName: "MySQL", frequency: "35" , url:"#"}
         ];
         
         $('#tagContainer').tagcloud(
         {tags:cloudtags},
         {tagStructure:{name:'tagName',freq:'frequency',url:'url'}}
         );
      

      We're done! As simple as that! Once again, cheers to the jQuery folks!
      And of course, suggestions for improvement are most welcome :)

      Happy Programming :)
      Signing Off
      Ryan

      Sunday, January 23, 2011

      jQuery : Creating a simple table sorting widget

      In this article, I am going to create a very simple widget for sorting a html table using jQuery. In this article, we will see how to create a bit more complex widget as compared to the one that I had discussed earlier in my post jQuery : Creating a custom widget.

      I am going to call my new widget a 'tablesort'.

      First the HTML.

      My HTML table comprises of three columns, and contains a list of 4 of my favorite movies. In the first column, i provide the movie name, the second column is my own rating of the movie and the third column is the year in which the movie was released.

      Here is our table

      Favorite Movies My Rating Year Of Release
      October Sky 9.6 1999
      Forrest Gump 9.5 1994
      Matrix 9.9 1999
      Pursuit Of Happiness 10 2006


      Okey, lets us first see what features we will include in our tablesort widget.

      1. A user can should be able to make any table sortable which follows more or less the above html structure.
      2. A user should be able to specify which columns can be used as a sort criteria for sorting the rows.
      3. Sorting of both strings and numeric values should be handled. (This is a simple widget, and i am not handling sorting of complex data types like dates because date formats can vary a lot and i still need to figure out how to handle that sort of stuff. Any suggestions on how to do that efficiently would be great.)
      4. The user should be able to reverse the sorting on a particular column, when clicked upon consecutively.


      Now lets see how our formal requirements translate in technical terms.

      1. Since our table contains a 'thead' and a 'tbody', we first need a way to associate a column header with all the columns under it. i.e. Association of a 'th' element with a set of 'td' elements.
      2. Secondly, we need to provide a means for the user to specify the columns to be sorted and add the sorting functionality to only those columns. We also need to provide a visual cue to the user to identify the sortable columns.
      3. When a column header is clicked on, the data in the associated 'td' elements should be compared and used as a basis to sort the 'td' elements. Then based upon the ordering of the 'td' elements, we will update the DOM for the table and rearrange the table rows.


      I ususally create a prototype object for the widget first and then initialize the widget instead of doing both of them at the same time. Lets first begin by creating the options object

      var tablesortPrototype=(
      options:{
         header:'thead',
         body:'tbody',
         sortableColumns:[0],
         sortableClass:'sortable'
        }
      };
      

      I have explicitly created the header and body variables so as to allow the user a bit of flexibilility of using CSS selectors as well for identifying the head and body elements. The next two variables are to specify the default settings for the sortable columns. We will used a 0 based index, as is common in most javascript functions. So, if the user does not specify anything, the table will be sortable based upon the first column. The next variable is for the css class that can be used for styling the sortable column.

      Now lets do the widget initialization. The code for it is pretty simple and i will be doing it in the _create() function of the widget.

      _create:function(){
         console.log('create');
         var widget=this;
         var $domTable=widget.element;
         var options=widget.options;
         
         var $headings=$('th',options.header);
         
         //For each column index as specified in the sortable columns, add a click event handler
         //and the necessary css
         $.each(options.sortableColumns,function(index){
         
          var columnIndex=this;
          $headings.eq(columnIndex).click(function(){
           //call event handler for click event
          })
          .addClass(options.sortableClass);
          
         });
        }
      

      As seen in the above code, i have initialized a few local variables to reduce the amount of typing that i may have to do. You dont actually need to do it, but i find it pretty handy because not only does it eliminate unnecessary typing, but it also eliminates extra function calls and helps your scripts run a tad faster.

      So, what I have done in the above code is, fetch all the headers, and for each numeric value specified as in the sortableColumns variable, I add a click event handler and a css class.

      Okey, right now, our code is pretty useless without the click event handler. Now, lets create another private function _toggleSort that handles sorting of the columns. This function will handle sort toggling, i.e. ascending order and descending order for the clicked column. Here is my empty sort toggling function

      _toggleSort:function(columnIndex,srcDomHeader){}
      

      and here is how I will call it in my click event handler

      var columnIndex=this;
          $headings.eq(columnIndex).click(function(){
           widget._toggleSort(columnIndex, this);
          })
          .addClass(options.sortableClass);
      

      Okey, now that we have created our function, lets try to break down the code for adding the functionality one by one.

      First, i will declare local variables for the javascript objects the way I did so in the _create function

      var widget=this;
         var $domTable=widget.element;
         var options=widget.options;
      

      All the following code has comments that would explain what is being doe.

      //Get the column which has to be sorted, i.e. get all the td elements of that particular column
         var column=$(options.body,$domTable).find('tr>td:nth-child('+(columnIndex+1)+')');
      

      The column variable is a jQuery object. I need to extract the td objects from it and keep it in an array to allow for sorting and reverse ordering.

      //Convert the jQuery object into an array
         var columnArray=[];
         $.each(column,function(index){
          columnArray[index]=$(this);
         });
      

      In this widget, since we want the sorting to be reversed on consecutive clicks, i am going to use a small technique to save resorting every time the header is clicked. What I will do is to store a sortstatus when an unsorted column header is clicked. I will do this using the data() function of jQuery. So, if a header is clicked, and it does not already have the sortstatus value or if it is set to false, we will sort the data. If the value is set to true, then it indicates that this is a consecutive click, and all we need to do is to reverse current order of the rows.

      But what this also means is that when a column header is clicked upon, i must clear the sortstatus on the other column headers so that they can be resorted when clicked upon.

      This is how I do it

      //Get the heading
         var $currentHeading=$(srcDomHeader);
         
         if($currentHeading.data('sortstatus')){
          //If the column is already sorted, just reverse the rows
          columnArray.reverse();
         }
         else{
          //If not already sorted
          
          //Clear the sort status on all the other columns
          $currentHeading.siblings().data('sortstatus',false);
      
      //More code for sorting goes here
      }
      

      Once in the else, my next task will be to identify the data types for the columns. As mentioned earlier, i will handle only string and numeric values here. I save the identified datatype as a property on the columnArray variable itself.

      //Determine the datatype for the column(whether string or numeric)
          $.each(columnArray,function(index){
           if(isNaN($(this).text())){
            columnArray.dataType='string';
            return false;
           }
          });
          
          if(columnArray.dataType!='string'){
            columnArray.dataType='number';
          }
      

      My next task is to sort the data, based upon the datatype for the data in the column. So, in the following code, i will cast the data to numbers wherever applicable, and then sort the 'td' elements.

      //Sort the array using Arrays.prototype.sort by passing a custom function
          columnArray.sort(function(a,b){
           var value1='';
           var value2='';
           if(columnArray.dataType=='string'){
            value1=$(a).text();
            value2=$(b).text();
           }
           else{
            value1=parseFloat($(a).text());
            value2=parseFloat($(b).text());
           }
           return (value1<value2)?-1:(value1==value2?0:1);
          });
      

      Once this is done, my column array now contains the selected 'td' elements in a sorted order.

      Now i must add the sorting status to the header

      //Set the sort status on the current column heading, 
          //which can be used later to toggle the sorting
          $currentHeading.data('sortstatus',true);
      


      All i now need to do is to manipulate the rows of the respective 'tr' elements for the sorted 'td' elements.

      //Append the rows to the table body for each td, thereby sorting them
         $.each(columnArray,function(index){
          var column=$(options.body,$domTable).append($(this).parent());
         });
      

      Once that is done, i can safely creae my widget with the following code

      $.widget('ui.tablesort',tablesortPrototype);
      

      Here is the code for the entire widget as one big blob!

      (function($){
       var tablesortPrototype={
        options:{
         header:'thead',
         body:'tbody',
         sortableColumns:[0],
         sortableClass:'sortable'
        },
        _create:function(){
         console.log('create');
         var widget=this;
         var $domTable=widget.element;
         var options=widget.options;
         
         var $headings=$('th',options.header);
         
         //For each column index as specified in the sortable columns, add a click event handler
         //and the necessary css
         $.each(options.sortableColumns,function(index){
         
          var columnIndex=this;
          $headings.eq(columnIndex).click(function(){
           widget._toggleSort(columnIndex, this);
          })
          .addClass(options.sortableClass);
          
         });
        },
        _init:function(){
         console.log('init');
        },
        _toggleSort:function(columnIndex,srcDomHeader){
         
         var widget=this;
         var $domTable=widget.element;
         var options=widget.options;
         
         //Get the column which has to be sorted, i.e. get all the td elements of that particular column
         var column=$(options.body,$domTable).find('tr>td:nth-child('+(columnIndex+1)+')');
         
         //Convert the jQuery object into an array
         var columnArray=[];
         $.each(column,function(index){
          columnArray[index]=$(this);
         });
         
         //Get the heading
         var $currentHeading=$(srcDomHeader);
         
         if($currentHeading.data('sortstatus')){
          //If the column is already sorted, just reverse the rows
          columnArray.reverse();
         }
         else{
          //If not already sorted
          
          //Clear the sort status on all the other columns
          $currentHeading.siblings().data('sortstatus',false);
          
          //Determine the datatype for the column(whether string or numeric)
          $.each(columnArray,function(index){
           if(isNaN($(this).text())){
            columnArray.dataType='string';
            return false;
           }
          });
          
          if(columnArray.dataType!='string'){
            columnArray.dataType='number';
          }
          
          //Sort the array using Arrays.prototype.sort by passing a custom function
          columnArray.sort(function(a,b){
           var value1='';
           var value2='';
           if(columnArray.dataType=='string'){
            value1=$(a).text();
            value2=$(b).text();
           }
           else{
            value1=parseFloat($(a).text());
            value2=parseFloat($(b).text());
           }
           return (value1<value2)?-1:(value1==value2?0:1);
          });
          
          //Set the sort status on the current column heading, 
          //which can be used later to toggle the sorting
          $currentHeading.data('sortstatus',true);
          
         }
         
         //Append the rows to the table body for each td, thereby sorting them
         $.each(columnArray,function(index){
          var column=$(options.body,$domTable).append($(this).parent());
         });
        }
       };
       
       $.widget('ui.tablesort',tablesortPrototype);
       
      })(jQuery);
      
      

      Here is how I set up my tablesort widget on my table

      $(function(){
         $('#movies').tablesort({sortableColumns:[0,1]});
        });
      

      Yay! Now we have a very very simple table sorter in less than 100 lines of code. jQuery makes it so easy!

      Try out the code on your own table or on the table that I showed earlier, click on the column headings and see the effect. Of course, if there is a bug, let me know. If not, I would welcome suggestions on how this can be enhanced, or improved, or simplified.

      After all, we all love a KISS(Keep It Simple, Stupid)!

      Happy Programming :)
      Signing Off
      Ryan

      Thursday, January 13, 2011

      Using Struts 2 with JSON and jQuery

      It took a decent amount of time to figure out how to set up struts 2 with JSON. and how to extract the data using jQuery. So, i thought that i'd better make a note of the stuff i learned and just restate the rules, few as they are, so that me or someone else can cross verify them when writing code.

      There are a few things that need to be done in order to use JSON with struts 2. Basically, struts provides you with a few result types. For JSON, you will require a new Result Type, because, obviously, since the response is a JSON response, you dont have a page to redirect to.

      So, first you need to download the JSON plugin, if you already dont have it in your struts download. As usual, keep it in the lib folder of your application.

      The struts 2 JSON plugin allows you to create an action that can be serialized into a JSON object. Ok, what that means in basic terms is that in the response that is sent back to the client, the response is the Javascript object that represents the Action class, and the attributes of the javascipt object are actually named after the public getter methods of the action. If the value of any getter method returns a null, the value of the javascript attribute will be null and vice versa.

      The plugin not only handles basic types but also complex types like lists and arrays. We will see a code snippet shortly.

      First things first. Lets see what needs to be done for setting up our action for JSON.

      Keep the json plugin jar in your lib directory.
      In struts.xml, create a new package that extends json-default. If you want to use an existing package, you can simply use a comma separated value for the package names as the value of the extends parameter of the package tag. That is what I will be doing here. (TIP : json-default package extends struts-default.)
      Specify the result type of your action class to be 'json'

      Thats pretty much all you need to do to get things going from the struts configuration perspective.

      The json-default package contains an interceptor and the result type configuration for JSON requests and responses.

      Now lets get to the code.


      1. From the browser perspective : jQuery
        jQuery allows you to issue an ajax request that expects a JSON object as a response by the getJSON method. Like all other ajax requests, the syntax for making the call is the same. You need to pass the url, a javascript object representing the form parameters, and a function that will be invoked upon the return of the invocation. In the returned function, the data that is returned from the server can be treated as a JSON object.

      2. From the server's perspective : Struts 2 
        All you need to do is to create instance variables and respective getter and setter methods for variables that need to be accessed via javascript. Once in the execute method, you can simply set the values of these instance variables. Then the action need to be configured to return a json object in the struts configuration file.


      The point to be noted here is that all the variables that have a setter can be set to the values as received by the form parameters. And all the variables that have a getter method can be retrieved in the client javascript code.

      In the following code sections, we will see how we can not only handle simple data types, but also, lists and maps as JSON objects.

      First the HTML. This is just an ordinary form that contains nothing but a text field for the user to enter a name. The struts action that we will write will just be used to say Hi to the user.



      The form id is introForm. Lets handle the submit event of this form in the code to return false, since we do not want to be going anywhere when the user submits. All the action must stay on this page itself.

      $(function(){
      
       $("#introForm").submit(function(){
       
        return false;
      
       });
       
      });
      

      So, now that we know that the action will stay here, what we need to do is serialize the form inputs and issue a request to the server with the form inputs. But before we do that, we must first create the action class and then configure the action and its url in the struts configuration file. So, lets jump towards the server code for once.

      Creating the action class is as simple as it has ever been. Since this is a demo, I have created a few instance variables of type List and Map and will populate some dummy values in them so that they can be retrieved using javascript later. Also note that for all my instance variables, I have created getter methods so that their values can be retrieved.

      public class AjaxActions extends ActionSupport{
      
          private String name;
          private String greeting;
          private List countryList;
          private Map countryMap;
      
          public String sayHi(){
              
              greeting="HI " +name;
      
              countryList=new ArrayList();
              countryList.add("US");
              countryList.add("UK");
              countryList.add("Russia");
      
              countryMap= new HashMap();
              countryMap.put("US",1L);
              countryMap.put("UK",2L);
              countryMap.put("Russia",3L);
      
              return ActionSupport.SUCCESS;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public String getGreeting() {
              return greeting;
          }
      
          public void setGreeting(String greeting) {
              this.greeting = greeting;
          }
      
          public List getCountryList() {
              return countryList;
          }
      
          public void setCountryList(List countryList) {
              this.countryList = countryList;
          }
      
          public Map getCountryMap() {
              return countryMap;
          }
      
      }
      

      So, basically what i have done here in the sayHi() function is to initialize an instance variable call greeting, that says hi to the user. Then i populated a dummy list with the names of a few countries. Then i populated a dummy map with the country codes of those countries. My objective is to fetch the greetig, the list and the map on the action from the javascript code.

      In the struts configuration file, the following lines would be sufficient to configure the JSON action.

      
          
              
                  
                      
                  
      
          
      
      

      Now my server side code is ready.

      Getting back to the javascript code, I am simply going to print the values on the firefox console, you can choose to do whatever you feel like!

      $(function(){
      
       $("#introForm").submit(function(){
        
        var formInput=$(this).serialize();
        
        $.getJSON('ajax/sayHi.action', formInput,function(data) {
         
         $('.result').html('' + data.greeting + '
      ');
      
         $.each(data.countryList,function(index, value){
          console.log("value " + value);
         });
      
         $.each(data.countryMap,function(key, value){
          console.log("key "+ key + ", value " + value);
         });
        });
      
        return false;
      
       });
       
      });
      


      That does it! Last but not the least, many thanks to the programmers to write such a easy to use plugin. Kudos to all of you!

      Happy Programming :)
      Signing Off
      Ryan

      Monday, January 3, 2011

      jQuery : Binding events to dynamic DOM elements

      Today in this blog post am going to discuss about a simple way of binding events to a DOM structure, especially one that changes dynamically.

      Binding events to jQuery is simple. All that you need to do is use the bind function to bind a DOM element to a given event or to use the various alias functions like click, dblclick etc etc.

      One of the major advantages that jQuery offers is the easy manipulation of DOM objects. That means, you can easily create, add or delete DOM elements on the fly and insert them into the page. However, doing this has its quirks as well when it comes to event binding. Lets take an example.

      Consider the following HTML snippet in your page.

      1_c1
      1_c2
      2_c1
      2_c2


      Let us assume that I want to add a sibling div to the div with class "parent2" whenever a child is clicked upon. Doing that is very simple. Here's how I would do it initially.

      $(".child").click(function(){
           var newSibling = '
      new_child
      '; $(this).parent().append(newSibling); });

      Well, that solves our purpose. But there is one small problem. As you see, the new div that i inserted into the DOM has a class attribute with a value "child". So, i should presumably expect that if the user clicks over the newly inserted div element, the click event handler should be triggered. Unfortunately for us, that does no happen.

      It seems like the event handlers are bound to the DOM elements statically. i.e. Once the DOM is built, the selectors do not bind the same event handlers to newly introduced elements.

      Now that poses a serious problem, because conceptually, it seems like the events should have been bound. So, how do we go about it?

      Event bubbling to the rescue!

      We know well that events in javascript are bubbled upwards in the DOM structure. This feature enables us to solve the problem of event binding for dynamically created elements.

      What we are going to do is to bind the click event handler to the parent div of the "child" elements. So, whenever a child element is clicked upon, the parent div gets notified due to event bubbling. In the click handler, you can identify the source DOM element that was clicked by using the value of event.target, where event is the argument that is passed to the click handler. Once we have got a handle on the source DOM element, the job's done! So, if you add a new DOM element to the parent, since the click handler is bound to the parent, you can always be sure that the new child element will also be clickable because the actual handler function is on the parent element.

      Here is the code.

      $(".parent1").click(function(event){
           var $source = $(event.target);
           var newSibling = '
      new_child
      '; $($source).parent().append(newSibling); });

      Pretty simple eh? Ya, I know its a dumb example, but, I guess simple is always better for demonstration purposes.

      Oh, and I could have used $(this).append(newSibling); instead of $($source).parent().append(newSibling);, because it suits our requirement, but I was just trying to be a bit verbose!

      Thats all for now folks!

      Happy Programming :)
      Signing Off
      Ryan