2011-10-12 15 views
8

Me gusta que jQueryUI datepicker sea lo suficientemente personalizable como para permitir que se active un botón que muestre el datepicker, pero, desafortunadamente, no le permite personalizar su propio marcado.¿Cómo puedo extender jQueryUI datepicker para que acepte un argumento adicional?

Si tengo marcado de este modo:

<span> 
    <input type="text" class="datepicker" /> 
</span> 
<span> 
    <button class="datepicker-trigger">Open</button> 
</span> 

Con el fin de conseguir que el selector de fecha para mostrar al hacer clic en el botón, que tendría que poner en práctica el siguiente código:

$('.datepicker').datepicker({ 
    showOn:'none' 
}); 
$('.datepicker-trigger').click(function() { 
    $('.datepicker').datepicker('show'); 
}); 

Aquí es un jsFiddle del código anterior: http://jsfiddle.net/P9Qmu/

Esto está muy bien, pero lo que yo realmente quiero hacer es pasar t La función datepicker es un argumento adicional que especifica un objeto o selector que indica qué elemento debe desencadenar la muestra.

Por ejemplo, me gustaría ser capaz de hacer esto:

$('.datepicker').datepicker({ 
    showOn:'none', 
    trigger:'.datepicker-trigger' 
}); 

Sé cómo extender jQuery para agregar métodos y crear plugins, pero no estoy seguro de cómo (o si se trata de posible) para modificar los argumentos permitidos en una función existente.

¿Alguien sabe cómo podría ampliar $.datepicker para lograr lo que estoy buscando hacer o al menos apuntarme en la dirección correcta? Cualquier ayuda sería muy apreciada.

Respuesta

15

¿Qué tal:

var __picker = $.fn.datepicker; 

$.fn.datepicker = function(options) { 
    __picker.apply(this, [options]); 
    var $self = this; 

    if (options && options.trigger) { 
     $(options.trigger).bind("click", function() { 
      $self.datepicker("show"); 
     }); 
    } 
} 

Uso:

$("#date").datepicker({ 
    trigger: "#button" 
}); 

$("#date2").datepicker({ 
    trigger: "#button2" 
}); 

Ejemplo:http://jsfiddle.net/gduhm/


o, menos intrusiva con su propio plugin de jQuery:

$.widget("ui.datepicker2", { 
    _init: function() { 
     var $el = this.element; 
     $el.datepicker(this.options); 

     if (this.options && this.options.trigger) { 
      $(this.options.trigger).bind("click", function() { 
       $el.datepicker("show"); 
      }); 
     } 
    } 
}); 

(uso similar, excepto el uso datepicker2 o lo que sea lo que sea)

Ejemplo:http://jsfiddle.net/puVap/

+0

Gracias Andrew, ¡excelente respuesta! Me alegro de que hayas demostrado ambos métodos. –

+0

@PhilipWalton: ¡No hay problema! –

+0

@AndrewWhitaker: ¿se puede extender el datepicker por medio de '$ .widget', incluso si datepicker en 1.8 no usa la fábrica de widgets? Esta [respuesta SO] (http://stackoverflow.com/questions/2526592/how-to-subclass-a-specific-jqueryui-widget-method) parece decir que no. – superjos

0

No puede extender debido a que el selector de fechas no utiliza la fábrica widget y por lo tanto se puede' t lo usa para extenderlo pero puede anular los métodos y puede inyectar su código. Para obtener una lista completa de los métodos que usa Jquery UI Datepicker, marque datepicker.js o jquery-ui.js

Puede sencillo añadir que el código en el archivo de JS personalizada y después de anulando puede llamar selector de fechas como de costumbre

$.datepicker._selectDay_old = $.datepicker._selectDay; 
$.datepicker._selectDay = function(id, month, year, td) { 
    this._selectDay_old(id, month, year, td); 
    // Your code here 
    console.log("Injected Custom Method"); 
} 

// Call Datepicker after Injecting code 
$("#datepicker").datepicker() 
+0

Muchas gracias ... Me estaba rascando la cabeza tratando de entender por qué mi extensión de widget no funcionaba. – VictorEspina

0

Por si acaso, para definir un método exigible debe seguir este patrón para el método nombre:

_<methodName>Datepicker(target, param1, param2,...,paramN) 

y si es necesario llamar a cualquier método interno que requiere una referencia a la instancia de calendario, debe hacer:

var inst = this._getInst(target); 
this._internalMethod(inst); 
Cuestiones relacionadas