Archive for the ‘Javascript’ Category

DateField Issues with ExtJs 2.1

August 1st, 2008

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.  * @file Special hotfix patch released by mystix on Ext development team
  3.  * to fix known issues with the DateField class. Next release may see the
  4.  * need to remove this.
  5.  */
  6.  
  7. // private
  8. Date.createParser = function(format) {
  9.   var funcName = "parse" + Date.parseFunctions.count++;
  10.   var regexNum = Date.parseRegexes.length;
  11.   var currentGroup = 1;
  12.   Date.parseFunctions[format] = funcName;
  13.  
  14.   var code = "Date." + funcName + " = function(input){\n"
  15.       + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, o, z, u, v;\n"
  16.       + "input = String(input);var d = new Date();\n"
  17.       + "y = d.getFullYear();\n"
  18.       + "m = d.getMonth();\n"
  19.       + "d = d.getDate();\n"
  20.       + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
  21.       + "if (results && results.length > 0) {";
  22.   var regex = "";
  23.  
  24.   var special = false;
  25.   var ch = ;
  26.   for (var i = 0; i < format.length; ++i) {
  27.       ch = format.charAt(i);
  28.       if (!special &amp;&amp; ch == "\\") {
  29.           special = true;
  30.       }
  31.       else if (special) {
  32.           special = false;
  33.           regex += String.escape(ch);
  34.       }
  35.       else {
  36.           var obj = Date.formatCodeToRegex(ch, currentGroup);
  37.           currentGroup += obj.g;
  38.           regex += obj.s;
  39.           if (obj.g &amp;&amp; obj.c) {
  40.               code += obj.c;
  41.           }
  42.       }
  43.   }
  44.  
  45.   code += "if (u){\n"
  46.       + "v = new Date(u * 1000);\n" // give top priority to UNIX time
  47.       + "}else if (y >= 0 &amp;&amp; m >= 0 &amp;&amp; d > 0 &amp;&amp; h >= 0 &amp;&amp; i >= 0 &amp;&amp; s >= 0 &amp;&amp; ms >= 0){\n"
  48.       + "v = new Date(y, m, d, h, i, s, ms);\n"
  49.       + "}else if (y >= 0 &amp;&amp; m >= 0 &amp;&amp; d > 0 &amp;&amp; h >= 0 &amp;&amp; i >= 0 &amp;&amp; s >= 0){\n"
  50.       + "v = new Date(y, m, d, h, i, s);\n"
  51.       + "}else if (y >= 0 &amp;&amp; m >= 0 &amp;&amp; d > 0 &amp;&amp; h >= 0 &amp;&amp; i >= 0){\n"
  52.       + "v = new Date(y, m, d, h, i);\n"
  53.       + "}else if (y >= 0 &amp;&amp; m >= 0 &amp;&amp; d > 0 &amp;&amp; h >= 0){\n"
  54.       + "v = new Date(y, m, d, h);\n"
  55.       + "}else if (y >= 0 &amp;&amp; m >= 0 &amp;&amp; d > 0){\n"
  56.       + "v = new Date(y, m, d);\n"
  57.       + "}else if (y >= 0 &amp;&amp; m >= 0){\n"
  58.       + "v = new Date(y, m);\n"
  59.       + "}else if (y >= 0){\n"
  60.       + "v = new Date(y);\n"
  61.       + "}\n}\nreturn (v &amp;&amp; (z || o))?" // favour UTC offset over GMT offset
  62.       +     " (Ext.type(z) == ‘number’ ? v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - z) :" // reset to UTC, then add offset
  63.       +         " v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == ‘+’? -1 : 1) * (hr * 60 + mn))) : v;\n" // reset to GMT, then add offset
  64.       + "}";
  65.  
  66.   Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$", "i");
  67.   eval(code);
  68. };
  69.  
  70. // private
  71. Ext.apply(Date.parseCodes, {
  72.     j: {
  73.         g:1,
  74.         c:"d = parseInt(results[{0}], 10);\n",
  75.         s:"(\\d{1,2})" // day of month without leading zeroes (1 - 31)
  76.     },
  77.     M: function() {
  78.         for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names
  79.         return Ext.applyIf({
  80.             s:"(" + a.join("|") + ")"
  81.         }, Date.formatCodeToRegex("F"));
  82.     },
  83.     n: {
  84.         g:1,
  85.         c:"m = parseInt(results[{0}], 10) - 1;\n",
  86.         s:"(\\d{1,2})" // month number without leading zeros (1 - 12)
  87.     },
  88.     o: function() {
  89.         return Date.formatCodeToRegex("Y");
  90.     },
  91.     g: function() {
  92.         return Date.formatCodeToRegex("G");
  93.     },
  94.     h: function() {
  95.         return Date.formatCodeToRegex("H");
  96.     },
  97.     P: {
  98.       g:1,
  99.       c:[
  100.           "o = results[{0}];",
  101.           "var sn = o.substring(0,1);", // get + / - sign
  102.           "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)
  103.           "var mn = o.substring(4,6) % 60;", // get minutes
  104.           "o = ((-12 <= (hr*60 + mn)/60) &amp;&amp; ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, ‘0′) + String.leftPad(mn, 2, ‘0′)) : null;\n" // -12hrs <= GMT offset <= 14hrs
  105.       ].join("\n"),
  106.       s: "([+\-]\\d{2}:\\d{2})" // GMT offset in hrs and mins (with colon separator)
  107.     }
  108. });
  109.  
  110. // private
  111. Date.formatCodeToRegex = function(character, currentGroup) {
  112.     // Note: currentGroup - position in regex result array (see notes for Date.parseCodes above)
  113.     var p = Date.parseCodes[character];
  114.  
  115.     if (p) {
  116.       p = Ext.type(p) == ‘function’? p() : p;
  117.       Date.parseCodes[character] = p; // reassign function result to prevent repeated execution
  118.     }
  119.  
  120.     return p? Ext.applyIf({
  121.       c: p.c? String.format(p.c, currentGroup || "{0}") : p.c
  122.     }, p) : {
  123.         g:0,
  124.         c:null,
  125.         s:Ext.escapeRe(character) // treat unrecognised characters as literals
  126.     }
  127. };
  128.  
  129. Date.prototype.getGMTOffset = function(colon) {
  130.     return (this.getTimezoneOffset() > 0 ? "-" : "+")
  131.         + String.leftPad(Math.abs(Math.floor(this.getTimezoneOffset() / 60)), 2, "0")
  132.         + (colon ? ":" : "")
  133.         + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
  134. };

Tags: , ,
Posted in Development, Javascript | Comments (0)

Advanced Data Validation Using ExtJs

May 8th, 2008

While working on my personal project tonight I finally got around to going over some of the new examples in the ExtJs documentation. In this case they are demonstrating having a form with a password field, and a confirmation password field, and how you can validate that the second password entered is the same as the first. That’s fine and dandy, but I did need it to do a little more. I need this validation to verify that the entered password is at least five characters, and contains at least one number or special character from a specific set.

Read the rest of this entry »

Tags: , ,
Posted in Development, Javascript | Comments (0)

Useful Javascript Tools

February 21st, 2008

I’ve been doing a lot of development using ExtJS, which involves a lot of AJAX work. And for anyone who has ever used AJAX you know you must deal with JSON. JSON is fine and dandy, and is certainly the best way to get compact data from a remote call response, but it sure can be hard to read at times. Anyone using this stuff will also tell you that when doing a lot of Javascript work that finding errors can be challenging. This is why I recommend the following suite of tools.

JSON formatter is a nifty tool that allows you to either paste JSON code into a textbox, or provide a URL, and it will spit out nice, neatly formatted JSON. That’s right. All spacing, line breaks, etc… all formatted for easy readability.

JSLint is a great tool for figuring out those hard syntax related bugs when attempting to write clean Javascript code. The same premise applies here. Paste in your code, and it will spit out a list of exceptions and problems, complete with line numbers and descriptions on how to resolve the issues.

Firebug is simply the best Javascript debugging tool available today. This tool allows you to view header content, responses, error messages and line numbers, included scripts and CSS, DOM selection using your mouse cursor, and even Javascript step-by-step execution!

Debug Bar is like Firebug, except that it is for IE, and it features only a small subset of what Firebug does. If you are in an environment where IE is required, however, it proves useful to see what has executed, what headers where sent, and responses.

Tags: , ,
Posted in Development, Javascript | Comments (0)

Ok, jQuery Is Pimp

October 18th, 2007

Alright, I’m with Ben Nadel on this one… jQuery is PIMP!! I started playing with it, and although I have barely scratched the surface I can tell that this thing is really powerful. As an example let us say that I have a form with a bunch of text boxes that I want to clear. Let’s say that the id of the form is frmSearch. Here’s how that could be done in jQuery.

  1. $(’#frmSearch :text’).val(”);

How cool is that? Yes, one line. Here’s what that does. The dollar sign ($) is the shortcut for the jQuery class. Inside the parenthesis we say to match an element who’s ID is frmSearch. Then the :text tells jQuery that we want to match ALL text boxes in that form. Then we are calling the val function which gets or sets the value of an element. In this case we are setting the value to blank.

Yeah, you need to check it out.

Tags: , ,
Posted in Development, Javascript | Comments (0)