Esta pregunta es similar a knockoutjs databind con jquery-ui datepicker, pero en lugar de la jQueryUI datepicker, me gustaría usar uno de los Bootstrap datepickers.

La API para el Bootstrap datepicker es diferente de jquery-ui, y estoy teniendo algunos problemas para envolver mi cabeza alrededor de lo que es trabajar con knockout.js. He creado un jsFiddle a probarlo.

Parece que el Bootstrap datepicker podría ser mucho más simple de usar, ya que no de forma independiente de la tienda de la fecha. Sin embargo, me gustaría saber si el jsFiddle es la manera apropiada de usar el Bootstrap widget datepicker con knockout.js es decir,

ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor, allBindingsAccessor) {
      //initialize datepicker with some optional options
      var options = allBindingsAccessor().datepickerOptions || {};
      $(element).datepicker(options);

      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).datepicker("destroy");
        });
    },
    update: function(element, valueAccessor) {
    }
};

4 Comentarios

  1. 41

    Aquí es un ejemplo de cómo se puede lograr esto con el datepicker de que usted está usando:

    ko.bindingHandlers.datepicker = {
        init: function(element, valueAccessor, allBindingsAccessor) {
          //initialize datepicker with some optional options
          var options = allBindingsAccessor().datepickerOptions || {};
          $(element).datepicker(options);
    
          //when a user changes the date, update the view model
          ko.utils.registerEventHandler(element, "changeDate", function(event) {
                 var value = valueAccessor();
                 if (ko.isObservable(value)) {
                     value(event.date);
                 }                
          });
        },
        update: function(element, valueAccessor)   {
            var widget = $(element).data("datepicker");
             //when the view model is updated, update the widget
            if (widget) {
                widget.date = ko.utils.unwrapObservable(valueAccessor());
                if (widget.date) {
                    widget.setValue();            
                }
            }
        }
    };

    No parezca hay alguna destruir la funcionalidad, así que me quita esa pieza. Se encarga de los widgets changeDate evento para actualizar el modelo de vista, cuando un usuario cambia la fecha. El update función controla cuando el modelo de vista es cambiado para actualizar el widget.

    Si desea enlazar el valor de un no-observable, entonces tomaría un poco más de código. Déjame saber si esto es algo que usted necesita para apoyar.

    http://jsfiddle.net/rniemeyer/KLpq7/

    • Aquí es un jsFiddle que tiene más susceptibles de cadena->la fecha de conversión cuando se actualiza el campo. Esto todavía tiene la salvedad de que sólo los cambios a través del widget están registrados; de realizar cambios en el campo de entrada no actualizar el modelo.
    • Aquí está una actualización para enlazar con el change evento para responder a cambios en el campo de entrada: jsfiddle.net/rniemeyer/uQcCx/3
    • JsFiddles de arriba no parece funcionar, tienen que hacer algunos cambios desde entonces ?, probado chrome y firefox, datepicker no aparecen más. Saludos
    • Lo de averiguar, El enlace externo de depuración knockoutjs no funciona más
    • He actualizado el violín.
    • Terminé la combinación de su respuesta de stackoverflow.com/questions/6612705/… con la respuesta aquí para resolver un problema. Realmente brillante respuestas, muchas gracias.
    • Me doy cuenta de que este ejemplo no funciona en el sentido de que la fecha inicial del selector de fecha no es la fecha en el cuadro de texto. Este es el error que estoy tratando de arreglar en mi propio código. Alguna idea?
    • Este código no funcionará si usted va a utilizar otra fecha: el formato de la configuración regional actual.
    • acerca de la destrucción, usted simplemente necesita en el final de init para agregar la correspondiente devolución de llamada: ko.utils.domNodeDisposal.addDisposeCallback(elemento, function() { // Este será llamado cuando el elemento es eliminado por Nocaut o // si alguna parte de su código llama ko.removeNode(elemento) $el.myWidget(«destruir»); });
    • Gracias. El comentario original en la respuesta fue, porque al menos en ese momento el datepicker no tenía destruir la funcionalidad, así que me quita la disposición código. Quizás lo que ha cambiado en jQuery UI.

  2. 6

    mi versión actual es una mezcla entre el ya demostrado soluciones:

    ko.bindingHandlers.datepicker = {
    init: function (element, valueAccessor, allBindingsAccessor) {
    
        var unwrap = ko.utils.unwrapObservable;
        var dataSource = valueAccessor();
        var binding = allBindingsAccessor();
    
        //initialize datepicker with some optional options
        var options = allBindingsAccessor().datepickerOptions || {};
        $(element).datepicker(options);
        $(element).datepicker('update', dataSource());
        //when a user changes the date, update the view model
        ko.utils.registerEventHandler(element, "changeDate", function (event) {
            var value = valueAccessor();
            if (ko.isObservable(value)) {
                value(event.date);
            }
        });
    },
    update: function (element, valueAccessor) {
        var widget = $(element).data("datepicker");
    
        var value = ko.utils.unwrapObservable(valueAccessor());
    
        //when the view model is updated, update the widget
        if (widget) {
            widget.date = value;
            if (widget.date) {
                widget.setValue();
                $(element).datepicker('update', value)
            }
        }
    }};
    • Actualización trabajado con este. Gracias.
  3. 5

    La aceptada respuesta no trabajo para mí con la versión actual del selector de fecha. La entrada no se inicializa con el valor de lo observable. He hecho una actualización de unión, a la que he añadido esto:

    $(element).datepicker('update', dataSource());

    Que parece hacer el truco.

    Aquí una actualización de violín que utiliza la última versión disponible del selector de fecha, Bootstrap, jQuery, y knock-out: http://jsfiddle.net/krainey/nxhqerxg/

    Actualización:

    He tenido algunas dificultades con el selector de fecha, no jugar bien con el observado cuando un usuario edita el valor en el campo de texto de forma manual. La herramienta de inmediato a analizar la fecha, y enchufe el resultado en el campo de entrada.

    Si el usuario ha intentado editar 10/07/2014, por ejemplo, y utiliza la tecla retroceso o supr para eliminar un número (10/0/2014), el valor resultante sería analizada de inmediato y se inserta en la entrada de texto. Si el valor fue, por un momento, 10/0/2014, el selector de cambio el calendario para 09/30/2014, y conecte el valor en el campo de texto. Si he intentado editar el mes, y el valor fue, por un momento, 1/7/2014, el selector de cambio de 7 de enero de 2014, y un enchufe que el valor en el campo de texto.

    Se puede ver que el comportamiento en este violín:

    http://jsfiddle.net/krainey/nxhqerxg/10/

    Tuve que actualizar mi unión con un especial de controlador para detectar el foco, y se unen de una vez el desenfoque del evento para que llegue a manejar manual de ediciones correctamente.

    $(element).on("changeDate", function (ev) {
        var observable = valueAccessor();
        if ($(element).is(':focus')) {
            //Don't update while the user is in the field...
            //Instead, handle focus loss
            $(element).one('blur', function(ev){
                var dateVal = $(element).datepicker("getDate");
                observable(dateVal);
            });
        }
        else {
            observable(ev.date);
        }
    });

    El violín que se hace referencia en la respuesta original ha sido actualizada para reflejar esto:

    http://jsfiddle.net/krainey/nxhqerxg/

  4. 2

    Aquí es lo que me Terminó de

    ko.bindingHandlers.datepicker = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        //initialize datepicker with some optional options
    
        var options = {
            autoclose: true,
            format: 'yyyy-mm-dd',
        }
    
        //var options = allBindingsAccessor().datepickerOptions || {};
        $(element).datepicker(options);
    
        //when a user changes the date, update the view model
        ko.utils.registerEventHandler(element, "changeDate", function (event) {
            var value = valueAccessor();
    
            if (ko.isObservable(value)) {
                var myDate = event.date;
                var month = myDate.getMonth() + 1;
                var monthText = month;
    
                if (month < 10)
                    monthText = "0" + month;
    
                var day1 = parseInt(myDate.getDate());
                var dayText = day1;
    
                if (day1 < 10)
                    dayText = '0' + day1;
    
                value(myDate.getFullYear() + '-' + monthText + '-' + dayText);
            }
        });
    },
    update: function (element, valueAccessor) {
    
        var widget = $(element).data("datepicker");
        //when the view model is updated, update the widget
        if (widget) {
            widget.date = ko.utils.unwrapObservable(valueAccessor());
            widget.setValue(widget.date);
        }
    }};

Dejar respuesta

Please enter your comment!
Please enter your name here