O'Reilly logo

JavaScript Cookbook by Shelley Powers

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

5.15. Using an Associative Array to Store Form Element Names and Values

Problem

You want to store form element names and values, for later validation purposes.

Solution

Use an associative array to store the elements, using the element identifiers as array index:

var elemArray = new Object(); // notice Object, no Array
var elem = document.forms[0].elements[0];
elemArray[elem.id] = elem.value;

Iterate over the array using the for...in statement:

for (var key in elemArray) {
  str+=key + "," + elemArray[key] + " ";
}

Discussion

Most JavaScript arrays use a numeric index, such as the following:

arr[0] = value;

However, you can create an associative array in JavaScript, where the array index can be a string representing a keyword, mapping that string to a given value. In the solution, the array index is the identifier given the array element, and the actual array value is the form element value.

You can create an associative array, but you’re not using the Array object to do so. Using the Array object is risky and actively discouraged—especially if you’re using one of the built-in libraries that use the prototype attribute for extending objects, as people discovered when the popular Prototype.js library was first released several years ago.

The earlier Prototype.js library made an assumption that most array use in JavaScript is numeric index–based, like most of the earlier examples in this chapter. The library extended the Array object functionality via Array.prototype, based on this assumption. But extending Array objects in this way breaks the for...in loop functionality used to traverse an associative array created from an Array object.

It’s not that Prototype.js was “breaking” JavaScript. The for...in loop was intended for one purpose: iterating over an object’s properties, such as being able to loop through the String object’s properties, or your own custom object properties.

When we use an Array object to create an associative array, what we’re really doing is adding new properties to the array object, rather than adding new array elements. You could actually create an associative array with a RegExp or String, as well as an Array. The reason is that in JavaScript objects are associative arrays. When you’re adding a new array, element:

obj[propName] = "somevalue";

what you’re really doing is adding a new object property:

obj.propName = "somevalue";

To further demonstrate how different the associative array is from a numeric-based array, when you use an Array to create an associative array, you can’t access the array “elements” by index, and the length property returns zero.

Instead of using an Array object to create the associative array, use the JavaScript Object directly. You get the exact same functionality, but avoid the clashes with libraries that extend the base Array object using prototype.

Example 5-3 shows a web page. Here, when the form is submitted, all of the form elements of type text are accessed and stored in an associative array. The element IDs are used as the array keyword, and the values assigned to the array elements. Once collected, the associative array is passed to another function that could be used to validate the values, but in this case just creates a string of keyword/value pairs, which is then displayed.

Example 5-3. Demonstrating associative array with form elements

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Associative Array</title>
<script type="text/javascript">
//<![CDATA[

// get the form element names and values
function getVals() {
  var elems = document.getElementById("picker").elements;
  var elemArray = new Object();
  for (var i = 0; i < elems.length; i++) {
    if (elems[i].type == "text")
       elemArray[elems[i].id] = elems[i].value;
  }
  checkVals(elemArray);
  return false;
}

// check values
function checkVals(elemArray) {

  var str = "";
  for (var key in elemArray) {
    str+=key + "," + elemArray[key] + " ";
  }

 document.getElementById("result").innerHTML = str;
}

//--><!]]>
</script>
</head>
<body>
<form id="picker" onsubmit="return getVals()">
<label>Value 1:</label> <input type="text" id="first" /><br />
<label>Value 2:</label> <input type="text" id="second" /><br />
<label>Value 3:</label> <input type="text" id="third"  /><br />
<label>Value 4:</label> <input type="text" id="four"  /><br />
<input type="submit" value="Validate" />
</form>
<div id="result"></div>
</body>
</html>

In the example, notice that the array index is formed by the form element’s id. When the array is traversed, the for loop syntax used is:

for (keyword in array)

This syntax accesses the array index, which is then assigned to the keyword variable that can be used to access the array value:

for (keyword in array)
   var a = array[keyword];

Figure 5-1 shows the example after values are typed into the form fields and the form is submitted.

Demonstration of associative array and traversing form elements

Figure 5-1. Demonstration of associative array and traversing form elements

This type of keyword/value pairing is commonly referred to as a hash map or hash table, though the JavaScript functionality isn’t a true hash map functionality. The reason why it isn’t a true hash map is that it doesn’t account for the fact that the same keyword could be used with multiple values, and the JavaScript version only accepts strings as keywords.

See Also

See Chapter 16 for more on the object nature of JavaScript, and Recipe 16.3 for more information about extending the built-in objects, such as Array, using the prototype property. For more on the risks associated with associative arrays in JavaScript, read “JavaScript ‘Associative Arrays’ Considered Harmful”, by Andrew Dupont.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required