I have this object:
function formBuddy()
{
var fields = new Array();
var labels = new Array();
var rules = new Array();
var count=0;
this.addField = function(field, label, rule)
{
fields[count] = field;
labels[field] = label;
rules[field] = rule;
count = ++count;
}
}
Its used in this way:
var cForm=new formBuddy();
cForm.addField("c_first_name","First Name","required");
cForm.addField("c_last_name","Last Name","required");
The problem is, in the addField()
function the fields
array is being set correct (perhaps because a numerical index is being used to refer to it) but the other 2 arrays (labels
and rules
) aren't being touched at all. Doing a console.log
shows them as empty in firebug.
What do I need to change to make them work? I'd still like to refer to the rules and labels by the string index of the field.
Use objects instead:
function formBuddy()
{
var fields = {};
var labels = {};
var rules = {};
var count = 0;
this.addField = function(field, label, rule)
{
fields[count] = field;
labels[field] = label;
rules[field] = rule;
count++;
}
}
But as Christoph already mentioned, I would store this information in a single data structure too. For example:
function formBuddy() {
var fields = {};
this.addField = function(name, label, rule) {
fields[name] = {
name: name,
label: label,
rule: rule
};
};
this.getField = function(name) {
return fields[name];
};
}
var cForm=new formBuddy();
cForm.addField("c_first_name","First Name","required");
cForm.addField("c_last_name","Last Name","required");
alert(cForm.getField("c_last_name").label);
fields
should be an array, whereas labels
and rules
should be objects as you want to use strings as keys. Also, addField()
is the same for each instance of FormBuddy()
(names of constructor functions should be capitalized) and should reside in the prototype, ie
function FormBuddy() {
this.fields = []; // this is the same as `new Array()`
this.labels = {}; // this is the same as `new Object()`
this.rules = {};
}
FormBuddy.prototype.addField = function(field, label, rule) {
this.fields.push(field);
this.labels[field] = label;
this.rules[field] = rule;
};
You can access the labels/rules via
var buddy = new FormBuddy();
buddy.addField('foo', 'bar', 'baz');
alert(buddy.labels['foo']);
alert(buddy.rules.foo);
Just to further enrage Luca ;), here's another version which also dosn't encapsulate anything:
function FormBuddy() {
this.fields = [];
}
FormBuddy.prototype.addField = function(id, label, rule) {
var field = {
id : id,
label : label,
rule : rule
};
this.fields.push(field);
this['field ' + id] = field;
};
FormBuddy.prototype.getField = function(id) {
return this['field ' + id];
};
var buddy = new FormBuddy();
buddy.addField('foo', 'label for foo', 'rule for foo');
It's similar to Gumbo's second version, but his fields
object is merged into the FormBuddy
instance. An array called fields
is added instead to allow for fast iteration.
To access a field's label, rule, or id, use
buddy.getField('foo').label
To iterate over the fields, use
// list rules:
for(var i = 0, len = buddy.fields.length; i < len; ++i)
document.writeln(buddy.fields[i].rule);
Arrays are treated as Objects in Javascript, therefore your piece of code works, it's just that firebug's console.log
isn't showing you the "Objects" inside the array, rather just the array values ...
Use the for(var i in obj)
to see what objects values the Array contains:
function formBuddy() {
var fields = new Array();
var labels = new Array();
var rules = new Array();
var count=0;
this.addField = function(field, label, rule)
{
fields[count] = field;
labels[field] = label;
rules[field] = rule;
count = ++count;
for(var i in labels) {
console.log(labels[i]);
}
for(var i in rules) {
console.log(rules[i]);
}
console.log(labels.c_last_name);
// or
console.log(labels["c_last_name"]);
}
}
var cForm = new formBuddy();
cForm.addField("c_last_name","Last Name","required");