Success! Looks like we've fixed this one. According to our records the fix was applied for EXTJS-5253 in a recent build.
  1. #1
    Sencha User
    Join Date
    Sep 2009
    Posts
    7
    Vote Rating
    0
    michael@freepascal.org is on a distinguished road

      0  

    Default Ext.data.writer.Json no longer respects dateFormat

    Ext.data.writer.Json no longer respects dateFormat


    Ext version tested:
    • Ext 4.0.7


    Browser versions tested against:
    • FF3 (firebug 1.4)


    Description:

    Describe the problem in greater detail here, summarizing the behavior.
    In a model, you can specify .dateFormat for date fields to indicate the format that the server uses. The Ext.data.reader.Json properly uses this format to decode the server response.

    However, the Ext.data.writer.Json class sends updates to the server in the standard format, like in 03-04-2011T00:00:00.

    This is due to the use of the Ext.encode() function which ignores the .dateFormat setting and always formats the date with the standard ExtJS date format.

    As a consequence, a server that worked fine with ExtJS 3, now no longer
    works with ExtJS 4 since it gets updates from the browser in a format it
    does not understand.

    Tested with ExtJS 4.0.7, independent of the browser type.


    Steps to reproduce the problem:
    • Specify .dateFormat on any date field in the grid example
    • Make sure encode= true for the json writer


    The result that was expected:
    • Server gets update for date field in .dateFormat


    The result that occurs instead:
    • Server gets update in standard Ext.Date format

    HELPFUL INFORMATION


    Debugging already done:
    • Debugged to see how update packet is constructed. Error is in Ext.JSON.encode, that uses a encodeDate (see ext-all-debug.js, line 5129)


    Possible fix:


    Additional CSS used:
    • only default ext-all.css


    Operating System:
    • Linuxd
    • Windows 7

  2. #2
    Sencha User Izhaki's Avatar
    Join Date
    Apr 2009
    Location
    London
    Posts
    118
    Vote Rating
    13
    Izhaki will become famous soon enough

      0  

    Default


    Same with 4.1.0b2
    Also see this thread.


    Fix in green:

    Code:
    Ext.override(Ext.data.writer.Writer, {
    
    
        /**
         * Formats the data for each record before sending it to the server. This
         * method should be overridden to format the data in a way that differs from the default.
         * @param {Object} record The record that we are writing to the server.
         * @return {Object} An object literal of name/value keys to be written to the server.
         * By default this method returns the data property on the record.
         */
        getRecordData: function(record) {
            var isPhantom = record.phantom === true,
            writeAll = this.writeAllFields || isPhantom,
            nameProperty = this.nameProperty,
            fields = record.fields,
            data = {},
            changes,
            name,
            field,
            key;
    
    
            if (writeAll) {
                fields.each(function(field){
                    if (field.persist) {
                        name = field[nameProperty] || field.name;
                        data[name] = record.get(field.name);
                        if (field.dateFormat && Ext.isDate(data[name]))
                        {
                            data[name] = Ext.Date.format(data[name], field.dateFormat);
                        }
                    }
                });
            } else {
                // Only write the changes
                changes = record.getChanges();
                for (key in changes) {
                    if (changes.hasOwnProperty(key)) {
                        field = fields.get(key);
                        name = field[nameProperty] || field.name;
                        if (field.dateFormat && Ext.isDate(changes[key]))
                        {
                            data[name] = Ext.Date.format(changes[key], field.dateFormat);
                        }
                        else
                        {
                            data[name] = changes[key];
                        }
                    }
                }
                if (!isPhantom) {
                    // always include the id for non phantoms
                    data[record.idProperty] = record.getId();
                }
            }
            return data;
        }
    });

  3. #3
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,665
    Vote Rating
    586
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Not so much a bug as a feature, however I'll push this one to the tracker.

    Also note that this may be likely to break a lot of code, so such a feature would need to be opt-in.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  4. #4
    Sencha - Community Support Team hendricd's Avatar
    Join Date
    Aug 2007
    Location
    Long Island, NY USA
    Posts
    5,962
    Vote Rating
    10
    hendricd will become famous soon enough hendricd will become famous soon enough

      0  

    Default


    @Izhaki --

    This is a popular issue. If your 'Application' serializes (consumes) dates the same way throughout, you can simply modify the JSON serialization method for all dates as needed:

    Code:
     Ext.JSON.encodeDate = function(o) {
            return Ext.Date.format(o, '"Y-m-d"');   //make sure the results are fully quoted !
        };
    If you operate in a mixed environment where input formats may vary (in contrast to Reader formats), something like this might be valuable:

    Code:
    /**
         * Formats the data for each record before sending it to the server. This
         * method should be overridden to format the data in a way that differs from the default.
         * @param {Object} record The record that we are writing to the server.
         * @return {Object} An object literal of name/value keys to be written to the server.
         * By default this method returns the data property on the record.
         */
        getRecordData: function(record) {
            var isPhantom = record.phantom === true,
            writeAll = this.writeAllFields || isPhantom,
            nameProperty = this.nameProperty,
            fields = record.fields,
            data = {},
            changes,
            name,
            serialize,
            field,
            key;
    
            if (writeAll) {
                fields.each(function(field){
                    if (field.persist) {
                        name = field[nameProperty] || field.name;
                        data[name] = record.get(field.name);
                        if( typeof field.serialize == 'function' ) {
                             data[name] = field.serialize(data[name], record);
                        }
                    }
                }, this);
            } else {
                // Only write the changes
                changes = record.getChanges();
                for (key in changes) {
                    if (changes.hasOwnProperty(key)) {
                        field = fields.get(key);
                        name = field[nameProperty] || field.name;
                        if( !field.persist ) continue;   // also a bug (missing)
                        if( typeof field.serialize == 'function' ) {
                               data[name] = field.serialize(record.get(name), record);
                        } else {
                               data[name] = changes[key];                    
                        }
                    }
                }
                if (!isPhantom) {
                    // always include the id for non phantoms
                    data[record.idProperty] = record.getId();
                }
            }
            return data;
        }
    permitting serialize methods on any field:

    Code:
    Ext.define('User', {    
         extend: 'Ext.data.Model',    
         fields: [        
            'name', 
            'email',         
            {name: 'age', type: 'int'},
    
            { name : 'birthday', 
              type : 'date', 
              dateFormat : 'c',
              serialize : Ext.util.Format.dateRenderer('Y-m-d')         
            }, 
            {name: 'gender', type: 'string', defaultValue: 'Unknown'},
          ] 
    });
    and not just Dates either.
    "be dom-ready..."
    Doug Hendricks

    Maintaining ux: ManagedIFrame, MIF2 (FAQ, Wiki), ux.Media/Flash, AudioEvents, ux.Chart[Fusion,OFC,amChart], ext-basex.js/$JIT, Documentation Site.


    Got Sencha licensing questions? Find out more here.


  5. #5
    Sencha User
    Join Date
    Sep 2009
    Posts
    7
    Vote Rating
    0
    michael@freepascal.org is on a distinguished road

      0  

    Default


    Surprised to hear that you would see this as "a feature and not a bug" and are afraid that it "could break working code".

    Because breaking working code is what it already does:

    We developed all our apps in ExtJS 3 where .dateFormat was respected by the writer.

    This change in the API breaks a lot of our server code in all our apps.
    Fixing all the server code to work without .dateFormat is very costly.

    So a fix (opt-in or not, I leave to you) would really be appreciated.

    Seeing the other threads about this subject, I'm not the only one to think so...

  6. #6
    Sencha User Izhaki's Avatar
    Join Date
    Apr 2009
    Location
    London
    Posts
    118
    Vote Rating
    13
    Izhaki will become famous soon enough

      0  

    Default


    I've just upgraded to 4.1 and my app seems to work fine. No patch is needed.

    Anyone else has the same experience?

  7. #7
    Sencha User
    Join Date
    Feb 2012
    Posts
    21
    Vote Rating
    0
    K4T is on a distinguished road

      0  

    Default


    I have 4.1.0 and dateFormat field property still not working for me.

  8. #8
    Sencha Premium Member
    Join Date
    May 2012
    Posts
    63
    Vote Rating
    1
    stevanicus is on a distinguished road

      0  

    Default


    Yea still doesnt work in 4.1.0 for me either...

    JSON
    Code:
    cal_date: '2012-05-09'

    Model > fields

    Code:
    {name: 'calendar_date', type: 'date', dateFormat:'d/m/y'}
    Output is blank (in my grid panel)


    However if I leave the type as 'date' and only remove dateFormat I get the output:

    Code:
    Wed May 09 2012 02:00:00 GMT +0200
    Update

    Found a solution to this problem by using renderer (in my case in the Grid Panel)

    Model > fields
    Code:
    {name: 'calendar_date', type: 'date'}
    And in my grid panel under the config columns
    Code:
    {header:'Date', dataIndex:'calendar_date', renderer:function(date){
                     return Ext.Date.format(date, 'd.m.Y');
                 }}

  9. #9
    Sencha User
    Join Date
    May 2012
    Posts
    4
    Vote Rating
    0
    shogikishi is on a distinguished road

      0  

    Default


    Many hours in to this, and having a workaround in architect only for areas with a 'tpl' field config, concluded this is a bug and found this thread. I am also pointing to ExtJS 4.1 and Sencha Architect does not respect 'dateFormat' config parameters. Bump +1.

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,496
    Vote Rating
    44
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    I think it should honour the dateFormat when writing back.

    The fix should be

    Code:
    if (field.persist) {
        name       = field[nameProperty] || field.name;
        if (field.type === Ext.data.Types.DATE) {
            data[name] = field.dateFormat ? Ext.Date.format(data[name], field.dateFormat) : data[name];
        } else {
            data[name] = record.get(field.name);
        }
    }