Cjxcz Odjcayrwl
Cjxcz Odjcayrwl

Reputation: 22847

Dijit DateTextBox - setting the date in ISO/numeric format?

I'm using DateTextBox as one of many controls in my screen. I register them in one place and then batch set values to them in loop, calling set('value', val) on each of them. All controls behave correctly, only the DateTextBox won't accept the data from server.

Initially java's Date was serialized as long (ex. 1280959200000), but when I've changed to ISO format (ex. "2010-08-04T22:00:00.000+0000") it isn't accepted either. But both are accepted date formats for new Date() constructor.

On the output I get the date value in ISO format: "2013-08-04T22:00:00.000Z" so it should be also accepted on input.

What can I do with DateTextBox to make it accept values in all formats supported by JavaScript's Date object, or one of the formats that can be returned from my server?

Upvotes: 0

Views: 1306

Answers (2)

Darien
Darien

Reputation: 3592

I think the fundamental problem is that the Javascript built-in Date object only accepts certain formats, and Dojo is relying on that built-in-behavior. At work, we have a similar issue, where lots of legacy PHP code is accustomed to passing dates around in a Mysql-derived format (ex. YYYY-MM-DD HH:MM:SS)

Our current workaround is to subclass dijit/form/DateTextBox, which also lets us impose some UI improvements. When something tries to set a value which isn't already a Date object and looks like a MySQL datetime, this code re-forms it to match ISO-8601 and passes it on through.

Dojo 1.9 code for a custom version of DateTextBox:

define([
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/_base/array",
    "dijit/form/DateTextBox"
], function(declare, lang, array, DateTextBox){

    var clazz = declare([DateTextBox], {


        _mysqlStyleExp : /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})$/,

        postMixInProperties: function(){ // change value string to Date object
            this.inherited(arguments);
            this.constraints.datePattern = "yyyy-MM-dd"; // Affects display to user
        },

        _convertMysqlDateToIso: function(value){
            value = lang.trim(value);
            var matches = this._mysqlStyleExp.exec(value);
            if(matches !== null){
                // Put the "T" in the middle and add fractional seconds with UTC
                // timezone

                // If your MySQL dates are NOT in UTC, obviously this will screw things up!                    
                return matches[1] + "T" + matches[2] + ".000Z";
            }else{
                return null;
            }
        },

        _setValueAttr : function(/*Date|String*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
            /*
             We want to be slightly more permissive in terms of the strings that can be set in order to support
             older code... But someday it'd be nice to standardize on Date.toJSON, so warn.
             */
            if(typeof(value) === "string"){
                var isoDate = this._convertMysqlDateToIso(value);
                if(isoDate !== null){
                    console.warn("Converting non-ISO date of "+value);
                    value = isoDate;
                }
            }
            this.inherited(arguments);
        }        
    });

    return clazz;
});

Note that this only affects data flowing into the Dojo widget.

Upvotes: 2

Chris
Chris

Reputation: 7278

The docs say:

The value of this widget as a JavaScript Date object, with only year/month/day specified.

So instead of this (which I assume you're currently doing):

new dijit.form.DateTextBox({value: "2010-08-04T22:00:00.000+0000"}, domNode);

Do this:

var myDate = new Date("2010-08-04T22:00:00.000+0000");
new dijit.form.DateTextBox({value: myDate}, domNode);

Upvotes: 0

Related Questions