2010-03-26 7 views
30

Je voudrais créer une version personnalisée du widget triable. J'ai cherché de la documentation, mais je n'ai pas trouvé quelque chose de vraiment précis. La meilleure information que j'ai trouvée était: http://jqueryui.pbworks.com/Widget-factory.Comment étendre un widget jquery ui? (1.7)

J'ai essayé:

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

Mais .widget.prototype._init $ n'est pas la fonction que je veux appeler, je suppose, car il est le prototype .widget $.

Alors, j'ai essayé quelque chose que je lis ici et là:

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

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

Mais:

  • Je ne peux pas croire que je dois stocker toutes les méthodes que je veux passer outre comme celui-ci, il est tellement moche.
  • Il déclenche une erreur ("this.refresh n'est pas une fonction"), ce qui signifie que la méthode refresh n'existe pas. Cela signifie-t-il que je devrais recréer toutes les méthodes que je veux remplacer? Quel est le point de prolongation dans ce cas?

Est-ce qu'il me manque quelque chose ici?

Merci pour votre aide!

+1

Dans ce 1.8 est très facile. – PetersenDidIt

+2

Comment est-ce facile dans 1.8? – powtac

+3

Dans 1.8, la fonction $ .widget() accepte un widget de base comme second paramètre. http://docs.jquery.com/UI_Developer_Guide#The_widget_factory – itsadok

Répondre

22

Après plusieurs essais, j'ai finalement trouvé comment faire facilement:

$.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); 

La clé est de copier les données de votre widget personnalisé à l'original. N'oubliez pas d'utiliser $ .ui.sortable.prototype. [Méthode overriden] .apply (this, arguments); dans chaque méthode de dépassement.

Holly merde!

+9

C'est très faux. Voir la réponse de bullgare ci-dessous. –

2

Je ne sais pas exactement ce que vous cherchez, quand vous dites "étendre un widget". Dans mon cas, je voulais changer la façon dont le widget s'est rendu, et jouer avec les classes CSS n'a pas satisfait. Il ne s'agissait pas d'étendre le comportement d'un widget, mais plutôt de modifier le comportement d'un widget. Donc j'ai surchargé la méthode de rendu. Le widget en question était the jQueryUI autocomplete et le surpassement ressemblait à ceci:

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 
    }; 
} 

Je viens d'appeler que $(document).ready().


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

+0

Merci pour votre réponse. Malheureusement, je ne veux pas modifier le widget existant, puisque je veux que le widget original reste intact. Une autre façon de réaliser ce que vous faites serait: $ .extend ($ .ui.sortable.prototype, {...}); Je veux créer un nouveau widget basé sur un existant, avec héritage, dans la logique de la programmation OO. – Jide

+0

Je crois que nous devrions plutôt stocker l'ancienne fonction dans le même espace de noms: '$ .ui.autocomplete.prototype._originalRenderItem = $ .ui.autocomplete.prototype._renderItem;'. – jjmontes

3

En ce qui concerne la solution choisie ci-dessus:

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

Si vous étendez un des objets les options dans une autre, le drapeau [profond] de vrai vous donnera les résultats escomptés.

2

J'ai utilisé cette fois-ci:

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

Ce sont des réponses un peu étranges. Il existe un deuxième paramètre facultatif - basewidget à hériter de. C'est facile. Pas besoin de travailler avec un prototype et ainsi de suite.

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

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

Le deuxième paramètre est $ .ui.sortable. Je pense que c'est tout ce dont tu as besoin.

3

J'utilise ceci afin de prédéfinir démarrer, arrêter et mettre à jour les fonctions:

$.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 
     } 
    } 
}); 
Questions connexes