2010-03-26 12 views
30

Me gustaría crear una versión personalizada del widget ordenable. He estado buscando documentación, pero no he podido encontrar algo realmente preciso. La mejor información que encontré fue: http://jqueryui.pbworks.com/Widget-factory.¿Cómo extender un widget jquery ui? (1.7)

me trataron:

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

Pero $ .widget.prototype._init no es la función que quiero llamar supongo ya que es el prototipo de $ .widget.

Entonces, intenté algo que leí aquí y allá:

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

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

Pero:

  • No puedo creer que tenga que almacenar todos los métodos que desea anular esta manera, es tan feo.
  • Lanza un error ("this.refresh no es una función"), lo que significa que el método de actualización no existe. ¿Eso significa que tendría que volver a crear todos los métodos que quiero anular? ¿Cuál es el punto de extender en ese caso?

¿Falta algo aquí?

Gracias por su ayuda!

+1

En 1.8 Esto es muy fácil. – PetersenDidIt

+2

¿Cómo es fácil en 1.8? – powtac

+3

En 1.8, la función $ .widget() acepta un widget base como el segundo parámetro. http://docs.jquery.com/UI_Developer_Guide#The_widget_factory – itsadok

Respuesta

22

Después de varios intentos, finalmente encontré la manera de hacer esto fácilmente:

$.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 clave consiste en copiar los datos de su widget personalizado al original. No se olvide de usar $ .ui.sortable.prototype. [Overriden method] .apply (this, arguments); en cada método anulado.

Holly crap!

+9

Esto está muy mal. Vea la respuesta del toro a continuación. –

2

No sé qué es lo que buscas cuando dices "extender un widget". En mi caso, quería cambiar la forma en que el widget se renderizaba a sí mismo y jugar con las clases CSS no satisfacía. No se trataba de extender el comportamiento de un widget, sino de modificar el comportamiento de un widget.

Así que superé el método de renderizado. El widget en cuestión era the jQueryUI autocomplete, y el de anulación se veía así:

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

simplemente llamé que en $(document).ready().


relacionada:
- 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

Gracias por su respuesta. Desafortunadamente, no quiero modificar el widget existente, ya que quiero que el widget original permanezca intacto. Otra forma de lograr lo que hace sería: $ .extend ($. Ui.sortable.prototype, {...}); Quiero crear un nuevo widget basado en uno existente, con herencia, en la lógica de la programación OO. – Jide

+0

Creo que deberíamos almacenar la función anterior en el mismo espacio de nombres: '$ .ui.autocomplete.prototype._originalRenderItem = $ .ui.autocomplete.prototype._renderItem;'. – jjmontes

3

En cuanto a la solución seleccionada arriba:

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

Si está ampliando una objetos opciones en otro, la bandera [de profundidad] de verdad le dará los resultados deseados.

2

he usado esta vez:

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

Estos son respuestas poco extrañas. Hay un segundo parámetro opcional - basewidget para heredar. Es fácil. No es necesario trabajar con prototipos, etc.

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

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

El segundo parámetro es $ .ui.sortable. Creo que es todo lo que necesitas

3

estoy usando esto con el fin de predefinir marcha, paro y actualización de funciones:

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