views:

397

answers:

2

I would like to create a custom version of the sortable widget. I have been searching for documentation, but could not find something really accurate. The best information I found was : http://jqueryui.pbworks.com/Widget-factory.

I tried :

$.widget("ui.customsortable", $.extend($.ui.sortable, {
  _init: function() {
    $.widget.prototype._init.apply(this, arguments);
  }
}));

But $.widget.prototype._init is not the function I want to call I guess since it is the $.widget prototype.

Then, I tried something I read here and there :

var _init = $.ui.sortable.prototype._init; 

$.widget("ui.customsortable", $.extend($.ui.sortable, {
  _init: function() {
    _init.apply(this, arguments);
  },
}));

But :

  • I can't believe I have to store all methods I want to override like this, it is so ugly.
  • It throws an error ("this.refresh is not a function"), which means the refresh method does not exist. Does that mean I would have to recreate all methods I want to override ? What's the point of extending in that case ?

Am I missing something here ?

Thanks for your help !

A: 

I don't know just what you're after, when you say "extend a widget". In my case I wanted to change how the widget rendered itself, and fiddling with the CSS classes didn't satisfy. It was not a case of extending the behavior of a widget, but rather modifying the behavior of a widget.

So I over-rode the render method. The widget in question was the jQueryUI autocomplete, and the over-ride looked like this:

function monkeyPatchAutocomplete() {  

  // don't really need this, but in case I did, I could store it and chain  
  var oldFn = $.ui.autocomplete.prototype._renderItem;  

  $.ui.autocomplete.prototype._renderItem = function( ul, item) {  
     // whatever 
  };  
}  

I just called that in $(document).ready().


related:
- Can I replace or modify a function on a jQuery UI widget? How?
- jQueryUI: how can I custom-format the Autocomplete plug-in results?

Cheeso
Thank you for your answer. Unfortunately, I don't want to modify the existing widget, since I want the original widget to stay intact.Another way to achieve what you do would be : $.extend($.ui.sortable.prototype, { ... });I want to create a new widget based on an existing one, with inheritance, in the logic of OO programming.
Jide
+2  A: 

After several tries, I finally found out how to do this easily :

$.widget("ui.customsortable", $.extend({}, $.ui.sortable.prototype, {

  _init: function(){
    this.element.data('sortable', this.element.data('customsortable'));
    return $.ui.sortable.prototype._init.apply(this, arguments);
  }

  // Override other methods here.

}));

$.ui.customsortable.defaults = $.extend({}, $.ui.sortable.defaults);

The key is to copy data from your custom widget to the original one. Don't forget to use $.ui.sortable.prototype.[overriden method].apply(this, arguments); in each overriden method.

Holly crap !

Jide