Ajax and Ajax Frameworks

I have been a developer for nearly 20 years and a web developer for about 10 years. Over the years, I have considered creating a blog to share the things I have learned (and am learning) about web design and development, but I never seemed to have the time. When I began learning about web development using Ajax and Ajax Frameworks, I decided to take the time to create this blog.

My intention for this blog is to focus primarily on Ajax Frameworks, but since web development requires knowledge of many technologies, I will occasionally write about things such as CSS, Javascript, PHP, MySQL, Flash, etc.

Lately, I have been using JQuery as my primary Ajax tool. Although I have used other Ajax Frameworks in the past (Dojo Toolkit, Yahoo! User Interface Library, Scriptaculous/Prototype), JQuery has thus far been the easiest to learn. In my first few posts I will discuss some of the JQuery Plugins that I have created. Some of these include: a plugin for Google Maps (jquery.imGoogleMaps), Form validation and submission  (jquery.imValidateForm), Page Populater (jquery.imPagePopulate), and a plugin to create lists (jquery.imList).

While I am still learning about some of the other Ajax Frameworks, I hope that what I have learned will be helpful to others. Just remember, “When you can pull the pebbles from my hand…”

Share

JQuery $.each

Friday, March 27th, 2009

The JQuery $.each object accessor is probably the best method since the invention of the wheel (or at least, since Stargate SG1 was first conceived). It completely replaces the ‘for’ loop to iterate over an object. The power of this method is that it can iterate over any collection (Dom collections, associative arrays, JSON objects, etc). In general, using JQuery can make Javascript development so much easier.

When I use Javascript to iterate over DOM elements, I usually do something like this:

?View Code JAVASCRIPT
this.getFormValues = function(form, fncName) {
     var str = "";
     var fn = eval("this."+fncName);
     var nL = form.elements.length;
     for (var i = 0; i < nL; i++) {
          if (fn) {
               if (this.canSubmit) {
                    this.canSubmit = fn (form.elements[i]);
               } else {
                    break;
               }
          }
          if ((form.elements[i].type == 'radio') || (form.elements[i].type == 'checkbox')) {
               if (form.elements[i].checked) {
                    str += form.elements[i].name + "=" + escape(form.elements[i].value) + "&";
               }
          } else {
               str += form.elements[i].name + "=" + escape(form.elements[i].value) + "&";
          }
     }
     return str;
}

With JQuery $.each, I can do the follwing:

?View Code JAVASCRIPT
function getFormValues(form, fncName) {
     var str = "";
     var fn = eval(fncName);
     $(':input', $form).each(function(i) {
          if ((this.type == 'radio') || (this.type == 'checkbox')) {
               if (this.checked) {
                    str += this.name + "=" + escape(this.value) + "&";
               }
          } else {
               str += this.name + "=" + escape(this.value) + "&";
          }
     });
     str = str.substr(0, str.length-1);
     return str;
};

Using JQuery, I don’t have to get the form elements and the number of form elements. The ‘this’ keyword refers to the individual form element that is contained within the html form collection. But I can use the $.each method to iterate over more than just Dom elements. Take for example the following Json object:

?View Code JAVASCRIPT
var valMapRequestor = { "fields":
[{"id": "tFirstName", "label" : "First Name", "rules":
[{"name": "hasValue"}]
},
{"id": "tLastName", "label": "Last Name", "rules":
[{"name": "hasValue"}]
},
{"id": "tAddress1", "label": "Street Address", "rules":
[{"name": "eitherOr", "fields": [
{"id" : "tAddress2"}]}]
},
{"id": "tCity", "label": "City", "rules":
[{"name": "hasValue"}]
},
{"id": "tZipCode", "label": "Zip Code", "rules":
[{"name": "hasValue"}, {"name": "isNum"}]
},
{"id": "cbxReferredBy", "label": "ReferredBy", "rules":
[{"name": "hasValue"}]
},
{"id": "rdoGender", "label": "Gender", "rules":
[{"name": "isChecked", "fields": [
{"id" : "rdoGender"}]}]
},
{"id": "rdoResident", "label": "Resident", "rules":
[{"name": "isChecked", "fields": [
{"id" : "rdoResident"}]}]
},
{"id": "rdoInsurance", "label": "Insurance", "rules":
[{"name": "isChecked", "fields": [
{"id" : "rdoInsurance"}]}]
}]
}

To iterate over the Json object, I can do the following:

?View Code JAVASCRIPT
function validateFields(el) {
     var msg = '';
     var bSubmit = false;
     $.each(valMapRequestor.fields, function(i, itm) {
     if (itm.id == el.name) {
          $.each(itm.rules, function(j, rule) {
               var fn = eval(rule.name);
               if (rule.fields) {
                    bSubmit = fn (el.value, rule.fields);
               } else if (rule.exclude)	{
                    bSubmit = fn (el.value, rule.exclude)
               } else if ((rule.value) && (rule.condition)) {
                    bSubmit = fn (el.value, rule.value, rule.condition)
               } else {
                    bSubmit = fn (el.value);
               }
               if (!bSubmit) {
                   msg += itm.label + aMessages[rule.name] + "";
                   canSubmit = false;
               }
          });
     }
});

I use the $.each method to iterate over all of the valMapRequestor fields. If the itm.id value of valMapRequestor.fields value matches the el.name value, the $.each method then iterates over the valMapRequestor.fields.rules members.

Creating this same functionality using Javascript takes a bit of extra programming.

?View Code JAVASCRIPT
this.validateFields = function (el) {
     var canSubmit = false;
     if (self.valMap == '') {
          canSubmit = true;
     } else {
          var nL = valMapRequestor.fields.length;
          for (var i=0; i < nL; i++) {
               if (valMapRequestor.fields[i].id == el.name) {
                    var ln = valMapRequestor.fields[i].rules.length;
                    for (var j=0; j < ln; j++) {
                         var fn = eval("self."+self.valMap.fields[i].rules[j].name);
                         if (valMapRequestor.fields[i].rules[j].fields) {
                              canSubmit = fn (el.value, valMapRequestor.fields[i].rules[j].fields);
                         } else {
                              canSubmit = fn (el.value);
                        }
                        if (!canSubmit) {
                              self.message = self.aMessages[valMapRequestor.fields[i].rules[j].name];
                              break;
                        }
                    }
                   if (!canSubmit) {
                        self.message = {"type": "message", "label": ""+valMapRequestor.fields[i].label + self.message+""};
                        break;
                   }
               } else {
                    canSubmit = true;
               }
           }
      }
     return canSubmit;
}

When it comes to iterating over an object, JQuery is far more superior than using Javascript alone.

Share

7 Responses to “JQuery $.each”

  • YAHOO.util.Dom.batch | GrasshopperPebbles.com Says:

    [...] but I haven’t explored it thoroughly). While this method is not as powerful as JQuery’s $.each (see example), it is still a very good replacement for a Javascript ‘for’ loop when iterating over a DOM [...]

  • Jayden Scott Says:

    Stargate is probably the best science fiction series after Firefly. Nice visual effects too.,.’

  • admin Says:

    The best since the original Star Trek (I’m a trekky – minus the garb and the conventions).

  • Olivia Smith Says:

    Stargate SG1 is much better than Stargate the movie. the series has lots of action and adventure.’:*

  • Computer Fan : Says:

    i think that the visual effects of Stargate SG1 is not very impressive, perhaps they should improve it.`~

  • bob Says:

    var fn = eval(“this.”+fncName);
    can be written as
    var fn = this[fncName];

  • bob Says:

    eval(“this.”+fncName)
    should be written as
    this[fncName]

CommentLuv badge