JQuery $.each
Friday, March 27th, 2009The 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:
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:
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:
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:
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.
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.



March 27th, 2009 at 1:42 am
[...] 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 [...]
July 3rd, 2010 at 2:01 pm
Stargate is probably the best science fiction series after Firefly. Nice visual effects too.,.’
July 3rd, 2010 at 8:48 pm
The best since the original Star Trek (I’m a trekky – minus the garb and the conventions).
August 1st, 2010 at 12:07 pm
Stargate SG1 is much better than Stargate the movie. the series has lots of action and adventure.’:*
October 25th, 2010 at 1:28 am
i think that the visual effects of Stargate SG1 is not very impressive, perhaps they should improve it.`~
October 27th, 2010 at 12:40 am
var fn = eval(“this.”+fncName);
can be written as
var fn = this[fncName];
January 5th, 2011 at 7:43 pm
eval(“this.”+fncName)
should be written as
this[fncName]