开发者

How to extend a jquery ui widget ? (1.7)

开发者 https://www.devze.com 2022-12-24 02:16 出处:网络
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://jqueryu

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 !


These are kinda strange answers. There is an optional second parameter - basewidget to inherit from. It's easy. No need to work with prototype and so on.

$.widget( "ui.customsortable", $.ui.sortable, {

  _init: function() {
    this.element.data('sortable', this.element.data('customsortable'));
    // or whatever you want
  }
} );

The second parameter is $.ui.sortable. I think it's all you need.


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 !


Regarding the selected solution above:

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

If you are extending one objects options into another, the [deep] flag of true will give you the desired results.


I'm using this in order to predefine start, stop and update functions:

$.widget('ui.custom_sortable_or_any_other_name', $.ui.sortable, {
    _init: function() {
        this.element.children().css('position', 'relative'); //for example
    },
    options : {
        start: function (event, ui) {   
            ui.item.addClass('noclick'); //ui.item get's the item, that's my point
        },
        stop: function (event, ui) {            
        },
        update: function (event, ui) {
            $.ajax(); //some ajax you might want to do
        }
    }
});


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?


I used this one time:

$.ui.buttonset.prototype.value = function() {
     return this.element.find('#' + this.element.find('label[aria-pressed="true"]').attr('for')).val();
} 
0

精彩评论

暂无评论...
验证码 换一张
取 消