DateField Issues with ExtJs 2.1
I ran into an interesting problem tonight while working on one of my projects that just so happens to use a little bit of the ExtJs SDK. I had dropped an Ext.form.DateField onto a regular old HTML form for a bit of polish. When I started testing I began to notice strange behaviors when leaving the field (onBlur), or even when bringing up the date selector. The date would change at random!!
After a bit of searching on the Ext forums I did find a couple of posts that indicated that this is a known issue, and that it has been fixed in the current Subversion build. In the meantime they did offer up a script you could include AFTER your Ext includes that would correct the issue in the current build (2.1). Below is a copy of that code for anyone who may be looking for it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | /** * @file Special hotfix patch released by mystix on Ext development team * to fix known issues with the DateField class. Next release may see the * need to remove this. */ // private Date.createParser = function(format) { var funcName = "parse" + Date.parseFunctions.count++; var regexNum = Date.parseRegexes.length; var currentGroup = 1; Date.parseFunctions[format] = funcName; var code = "Date." + funcName + " = function(input){\n" + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n" + "input = String(input);var d = new Date();\n" + "y = d.getFullYear();\n" + "m = d.getMonth();\n" + "d = d.getDate();\n" + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n" + "if (results && results.length > 0) {"; var regex = ""; var special = false; var ch = ''; for (var i = 0; i < format.length; ++i) { ch = format.charAt(i); if (!special && ch == "\\") { special = true; } else if (special) { special = false; regex += String.escape(ch); } else { var obj = Date.formatCodeToRegex(ch, currentGroup); currentGroup += obj.g; regex += obj.s; if (obj.g && obj.c) { code += obj.c; } } } code += "if (u){\n" + "v = new Date(u * 1000);\n" // give top priority to UNIX time + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0){\n" + "v = new Date(y, m, d, h, i, s, ms);\n" + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0){\n" + "v = new Date(y, m, d, h, i, s);\n" + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0 && i >= 0){\n" + "v = new Date(y, m, d, h, i);\n" + "}else if (y >= 0 && m >= 0 && d > 0 && h >= 0){\n" + "v = new Date(y, m, d, h);\n" + "}else if (y >= 0 && m >= 0 && d > 0){\n" + "v = new Date(y, m, d);\n" + "}else if (y >= 0 && m >= 0){\n" + "v = new Date(y, m);\n" + "}else if (y >= 0){\n" + "v = new Date(y);\n" + "}\n}\nreturn (v && (z || o))?" // favour UTC offset over GMT offset + " (Ext.type(z) == 'number' ? v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - z) :" // reset to UTC, then add offset + " v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn))) : v;\n" // reset to GMT, then add offset + "}"; Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i"); eval(code); }; // private Ext.apply(Date.parseCodes, { j: { g:1, c:"d = parseInt(results[{0}], 10);\n", s:"(\\d{1,2})" // day of month without leading zeroes (1 - 31) }, M: function() { for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names return Ext.applyIf({ s:"(" + a.join("|") + ")" }, Date.formatCodeToRegex("F")); }, n: { g:1, c:"m = parseInt(results[{0}], 10) - 1;\n", s:"(\\d{1,2})" // month number without leading zeros (1 - 12) }, o: function() { return Date.formatCodeToRegex("Y"); }, g: function() { return Date.formatCodeToRegex("G"); }, h: function() { return Date.formatCodeToRegex("H"); }, P: { g:1, c:[ "o = results[{0}];", "var sn = o.substring(0,1);", // get + / - sign "var hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60);", // get hours (performs minutes-to-hour conversion also, just in case) "var mn = o.substring(4,6) % 60;", // get minutes "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" // -12hrs <= GMT offset <= 14hrs ].join("\n"), s: "([+\-]\\d{2}:\\d{2})" // GMT offset in hrs and mins (with colon separator) } }); // private Date.formatCodeToRegex = function(character, currentGroup) { // Note: currentGroup - position in regex result array (see notes for Date.parseCodes above) var p = Date.parseCodes[character]; if (p) { p = Ext.type(p) == 'function'? p() : p; Date.parseCodes[character] = p; // reassign function result to prevent repeated execution } return p? Ext.applyIf({ c: p.c? String.format(p.c, currentGroup || "{0}") : p.c }, p) : { g:0, c:null, s:Ext.escapeRe(character) // treat unrecognised characters as literals } }; Date.prototype.getGMTOffset = function(colon) { return (this.getTimezoneOffset() > 0 ? "-" : "+") + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0") + (colon ? ":" : "") + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0"); }; |





Leave a Reply