Estoy usando un jQuery UI selector de fecha. El HTML de la entrada de campo detrás de ella está actualmente conectado a KnockoutJS como un dependentObservable, pero cuando su valor se establece en el viewmodel, el datepicker pierde su formato.

¿Cómo debo hacerlo y no perder el formato? Me gustaría que el viewModel no saben que es un jQuery selector de fecha.

7 Comentarios

  1. 79

    Podría escribir un enlace personalizado que establece la fecha en el campo utilizando el selector de fecha Api y también se establece el valor de su observables mediante la lectura de la fecha correctamente.

    El enlace personalizado aspecto:

    ko.bindingHandlers.datepicker = {
        init: function(element, valueAccessor, allBindingsAccessor) {
            var options = allBindingsAccessor().datepickerOptions || {},
                $el = $(element);
    
            //initialize datepicker with some optional options
            $el.datepicker(options);
    
            //handle the field changing
            ko.utils.registerEventHandler(element, "change", function() {
                var observable = valueAccessor();
                observable($el.datepicker("getDate"));
            });
    
            //handle disposal (if KO removes by the template binding)
            ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
                $el.datepicker("destroy");
            });
    
        },
        update: function(element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor()),
                $el = $(element),
                current = $el.datepicker("getDate");
    
            if (value - current !== 0) {
                $el.datepicker("setDate", value);   
            }
        }
    };

    Que podría utilizarlo como:

    <input data-bind="datepicker: myDate, datepickerOptions: { minDate: new Date() }" />

    La datepickeroptions sería opcional y podría incluir cualquier cosa que usted desea pasar a la datepicker() llamada.

    También, esto asume que usted está usando un observable para la fecha. La unión tiene que trabajar un poco más si quieres hacer un camino de unión con un no-observable, pero eso es improbable.

    Muestra aquí: http://jsfiddle.net/rniemeyer/NAgNV/

    • Lo que acerca de este enlace personalizado que necesita cambiar para mejorar la cooperación entre datepicker y «con: submodelObject» estilo de unión? En mi uso, lo que hizo que el selector de fechas del div de viento de hasta prestados visible hasta que pueda ser conectado a un visible <input>; el uso de la plantilla»: {afterRender: jqueryDecoratingMethod, de datos: submodelObject}» trabajó muy bien, sin embargo.
    • ¿tiene usted un ejemplo de donde usted está viendo a un problema o podría a su tenedor mi violín? Estaría encantado de echar un vistazo.
    • Ryan – gracias por la oferta; yo no soy capaz de reproducir en el violín. Sospecho (debido a otros fealdad en la página) que me he olvidado del tema jqueryui o tener algo similar feo en mi CSS…. si me pueden reducirse a una combinación específica de factores, voy a publicar un enlace o un violín.
    • Me doy cuenta de que esto es muy antiguo, pero cuando trato de usar este para la fecha de selector de hora, en IE7, el pop-up no desaparece totalmente. Cuando se selecciona un valor, se esconde la pop-up brevemente y, a continuación, se activa de nuevo sin ninguna manera de cerrarlo. Cualquier pensamiento sobre este error? Parece bien en Chrome.
    • He actualizado la respuesta y el violín con un tweak que evita este problema en IE7. Esto ocurrió en otra pregunta en algún momento.
    • Entonces, caigo en la situación en la que mi fecha NO es un observable y «tiene un poco más de trabajo para hacer una forma de unión». Lo que tengo es un observableArray de fechas. La interfaz de usuario es, efectivamente, la representación de los campos de ENTRADA y la datepickers a mi satisfacción.. pero.. cuando la fecha está seleccionada, mientras que se muestra en la ENTRADA, no puedo obtener el valor de ida y vuelta de nuevo en la modelo con el código actual se demostró anteriormente.
    • De modo que un cuadro de texto de entrada no debe ser null. Sin embargo, si usted se fija una fecha, a continuación, elimine la fecha, el valor se convierte en nulo. Resulta que los desarrolladores de código de otros servicios públicos con esta expectativa de que el cuadro de texto nunca es nula. Así que al final de la sección de actualización, he añadido esto: if (!valor) valor = «»;

  2. 6

    Tuve que hacer una pequeña edición para RP Niemeyer código para que funcione en mi código mediante el dateFormat opción, en sustitución de

    $(element).datepicker("getDate")

    Con

    $(element).val()

    Por lo que la versión con formato de la fecha en que se pasa todo correctamente bajo el capó.

  3. 6

    He estado usando RP Niemeyer código marcado como la respuesta anterior, pero desde que he estado usando yo he hecho unos pequeños cambios. Pensé que iba a publicar aquí. Tal vez va a ayudar a los demás. Es prácticamente el mismo, la única diferencia es que si el elemento tiene un valor cuando se carga la página, a continuación, va a mantener su valor. También, he hecho $elem una variable, por lo que habrá menos de procesamiento de $(element) que jQuery se tiene que hacer.

    ko.bindingHandlers['jqDatePicker'] = {
        'init': function(element, valueAccessor, allBindingsAccessor) {
            /* Initialize datepicker with some optional options */
            var options = allBindingsAccessor().jqDatePickerOptions || {},
                prop = valueAccessor(),
                $elem = $(element);
    
            prop($elem.val());
    
            $elem.datepicker(options);
    
            /* Handle the field changing */
            ko.utils.registerEventHandler(element, "change", function () {
                prop($elem.datepicker("getDate"));
            });
    
            /* Handle disposal (if KO removes by the template binding) */
            ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
                $elem.datepicker("destroy");
            });
        },
        'update': function(element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor()),
                $elem = $(element),
                current = $elem.datepicker("getDate");
    
            if (value - current !== 0) {
                $elem.datepicker("setDate", value);
            }
        }
    };
    • Yo no profundizar en ella, pero el valor inicial del selector de fecha no se ha ajustado el valor del límite observable.
  4. 2

    Aquí es lo que funcionó para mi conjunto particular de circunstancias. Yo estoy un bastante nuevo, la versión de MVC, que el defecto datetime serializador representa a la norma ISO 8601 (ver En la pesadilla que es JSON Fechas. Además, JSON.NET y ASP.NET Web API). Mis enlaces no escribir directamente en el selector de fecha, pero en lugar de una etiqueta de entrada del atributo «value».

    También, de la nota, estoy usando date.js

    ko.bindingHandlers.dateValue = {
        update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            var value = valueAccessor(),
                allBindings = allBindingsAccessor();
            var valueUnwrapped = ko.utils.unwrapObservable(value);
            var pattern = allBindings.datePattern || 'MM/dd/yyyy';
            var date = Date.parse(valueUnwrapped)
            $(element).val(date.toString(pattern));
        },
    
        init: function(element, valueAccessor, allBindingsAccessor) {
            //handle the field changing
            ko.utils.registerEventHandler(element, "change", function () {
                var observable = valueAccessor();
                var date = Date.parse($(element).val());
                observable(date.toString("yyyy-MM-ddThh:mm:ss"));
            });
        }
    }

    De unión se parece a esto:

    <input class="date" type="text" data-bind="dateValue: SomeViewModelDate" />

    Y el código JavaScript para activar el selector de fecha:

    $(document).ready(function () {
        $('.date').datepicker({ dateFormat: "mm/dd/yy" });
    });
    • Tengo una pregunta donde debo poner el código antes de aplicar los enlaces? Ahora estoy recibiendo el error: Uncaught TypeError: no se puede procesar el enlace de «foreach: function (){return políticas }» Mensaje: no se puede procesar el enlace de «dateValue: function (){return startDate }» Mensaje: No se puede leer la propiedad ‘toString’ null
  5. 1

    El datepicker de las muestras por encima de cambiar el formato de la fecha en la perspective de WCF formato para el JavaScript formato de fecha cuando el usuario selecciona una nueva fecha de la datepicker de control.

    En mi caso, me fue pasando la fecha de regreso a un servicio WCF, y que no aceptaría un deserializa date de JavaScript, es necesario la fecha en la WCF formato. He modificado el script de arriba para que almacena la fecha en la viewmodel en WCF formato para que pueda ser enviado de vuelta al servidor en ese formato.

    ko.bindingHandlers.datepicker = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            //Initialize datepicker with some optional options
            var options = allBindingsAccessor().datepickerOptions || {};
            $(element).datepicker(options);
            //Handle the field changing
            ko.utils.registerEventHandler(element, "change", function () {
                var observable = valueAccessor();
                //observable($(element).datepicker("getDate"));
                //store the date in 'WCF String format"
                var tempdate=$(element).datepicker("getDate");
                var tempdatestr="/Date("+tempdate.getTime()+")/";
                observable(tempdatestr);
            });
            //Handle disposal (if KO removes by the template binding)
            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                $(element).datepicker("destroy");
            });
        },
        update: function (element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            //Handle date data coming via JSON from Microsoft
            if (String(value).indexOf('/Date(') == 0) {
                value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
            }
            current = $(element).datepicker("getDate");
            if (value - current !== 0) {
                $(element).datepicker("setDate", value);
            }
        }
    };
  6. 0

    Una solución es el formato de la fecha a sí mismo dentro de la dependentObservable función. Así que usted debe devolver algo como return viewModel.someOtherObservable() en la función. Formato del valor de retorno.

    Si se incluye su código, puedo explicar más.

  7. 0

    El formato de la fecha (mm/dd/aaaa) en el interior de la dependentObservable es exactamente lo que yo estaba preguntando cómo hacer. Voy a publicar un poco de mi código si usted puede ayudar, Peter Mortensen y/o nEEBz.

        <div data-bind="with: technology">  
            <div class="titleblock">
                <label><b>End of Life Date</b></label> 
                <Input  type="text" class="ui-datepicker" id="datepicker" data-bind="value: END_OF_LIFE_DATE"/>
            </div>       
        </div>

    en ViewModel – technologydetail.js:

    var technology = ko.observable();

    en Activar:

    return dataContext.getTechnologyById(currentTechnologyId, technology);

    Esto muestra una fecha que tiene este aspecto en el cuadro de texto: el Miércoles 29 de enero 19:00:00 EST 2014 pero
    Quiero que se acaba de mostrar: 01/29/2014. Estoy usando este datepicker opción – dateFormat: «mm/dd/yy», pero no tiene ningún efecto en el valor inicial se muestra.

    Yo era capaz de formatear usando momento y funciona muy bien para visualizar el valor de base de datos, pero parece ser que romper la unión de vuelta a la observable debido a que dejará de actualización en una operación de GUARDAR.

    <Input type="text" class="ui-datepicker" id="datepicker" data-bind="value: moment(END_OF_LIFE_DATE()).format('MM/DD/YYYY')" />

Dejar respuesta

Please enter your comment!
Please enter your name here