3/17/13

How to extend jquery ui widget

Sometimes it is happen that you need to use some jquery ui widget, which is perfect solution for your project except one little feature - that must be somehow act differently. In that case some customization of the widget needed. As you may already know - in javascript, it may be plenty of ways to do the same thing, the question is - what is the nicest way. In this post i will try to show some ways of widget customization and discus the advantages/disadvantages of each way.

For example we will take the jquery ui dialog widget. Lets say in your project you must have the same  dialogs as jquery ui offers, but without the titlebar :

Of course, in real life the things to change would be much more interesting and complicate, the dialog titlebar is only using us for making the example easier.
So, you can handle this in some quick way like using the "open" event of the plugin:

$( "#dialog" ).dialog({
    modal:true,
    open:function(){
       $(this).parent().find(".ui-dialog-titlebar").hide();
    }
}) 

This will work, but what if we using the same kind of dialog in multiple places? In this case you will need to specify the same open handler code each time you make use the of dialog widget.
More convenient way to make all dialog insitances to hide titlebar at once- is to make a little modifictaion inside the code of the widget.
You can download the full source code of all jquery ui widgets from the githube repository and play with the code as you wish. Once you clicked the ZIP button

all the code is yours. You can find the dialog widget code inside ui folder -here is it jquery.ui.widget.js.
So desired functionality can easily be achieved if we comment out the following line inside _create method:



var uiDialogTitlebar = (self.uiDialogTitlebar = $('<div>
</div>'))

 .addClass(
  'ui-dialog-titlebar ' +
  'ui-widget-header ' +
  'ui-corner-all ' +
  'ui-helper-clearfix'
 )
 /*.prependTo(uiDialog)*/,

This code creating the titlebar element and adds it to dialog body.
Comment it out will make all the dialogs to appear without titlebars in all the places, as needed.
Unfortunately, short time after the brilliant solution you found it may occur that the application design will change so that in some lonely case the dialog titlebar will be still needed.

extending dialog widget
For this case, i think  you may take advantage of the $.widget method generously offered by jquery-ui framework.The method give you an ability to create your own custom dialog widget that inherits form the standart jquery-ui module:



$.widget('ui.extendeddialog', $.ui.dialog, {
 _init: function() {
  if ( this.options.autoOpen ) {
   this.open();
  }
  //hiding the titlebar  
         this.uiDialogTitlebar.hide();
 }
});     

Explanation: In this code i make the new widget named extendeddialog, which is exact copy of jquery-ui dialog except -that it has no titlebar. I choose to override the _init method that runs after all the elements of the widget been created already in previously called _create method.
Now if you need to display dialogs without titlebars you may use the new extended widget ,which should called in  following way:


$( "#dialog" ).extendeddialog();

The original dialog widget is functioning now without changes.
$( "#dialog1" ).dialog();

You may be noticed the code inside init method that does not contribute a thing to hiding titlebar functionality:

if ( this.options.autoOpen ) {
 this.open();
}
This code must stay inside the _init method because we overriding it when we specify it inside $.widget function parameter. So here is the way the widget extending code may be more nice: instead of coping all the code of overriden function - we may call the original function of the original widget (prototype) from inside the overriding code:

$.widget('ui.extendeddialog', $.ui.dialog, {
  _init: function() {
    //calling the _init function of prototype  (like "super" in java)
    $.ui.dialog.prototype._init.call(this);
    //hiding the titlebar
    this.uiDialogTitlebar.hide();
  }
});
Now it much more nice.
We can augment our new extendeddialog widget even little bit more: We can add the ability to hide the titlebar conditionally(depend on hideTitle custom option):

 $.widget('ui.extendeddialog', $.ui.dialog, {
 _init: function() { 
  $.ui.dialog.prototype._init.call(this);
  if( this.options.hideTitle )this.uiDialogTitlebar.hide();
 },
        //extending the options
 options : {
              hideTitle:true 
 }
});
From now if we give hideTitle option the false value( by default it is true) - the titlebar will become visible.

$( "#dialog" ).extendeddialog({hideTitle:false});
Hope this post was interesting,
I wish it will help somebody to  understand things better...

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...