reptile7's JavaScript blog
Saturday, April 10, 2010
 
Brighten the Controls, Take Two
Blog Entry #176

In this post, we'll wrap up our discussion of HTML Goodies' "Pure Magic Form Script" tutorial with a look at the tutorial's "second script". Billed as an "update" to the first "Pure Magic Form Script" script, which we dissected in detail in Blog Entry #174, the second "Pure Magic Form Script" script is an altogether more straightforward and down-to-earth script than is its predecessor. Specifically, the second script dispenses with arcane DOM features and achieves its background-color effects via object.style commands of the type we have long used on this blog. Relatedly, the second script's use of the DOM getElementById( ) method is unnecessary in all but one case, as we'll see below.

The tutorial's The Second Script hyperlink is broken because the target anchor that precedes the tutorial's "The Second Script" section has the wrong fragment identifier: it's specified as <a name="first"></a> when it should be <a name="second"></a>. The second script is posted on a separate page here but, as explained in the introduction of Blog Entry #174, is for readability reasons better viewed via the source of its demo page.

change( ) two

Like the first "Pure Magic Form Script" script, the second "Pure Magic Form Script" script contains an onkeyup-triggered change( ) function that applies background colors to text boxes and activates/disables a reset button in a form. The second script's change( ) function also effects a one-way change to the content of a div element. As in the first script, the text inputs of the second script's form are given a class="bgwhite" attribute, but no use is made of this class nor of the first script's bgyellow class, which is entirely absent from the second script; rather, the second script's change( ) function directly queries and sets the CSS backgroundColor property of the text inputs.

The second script's change( ) function begins with an if statement that handles the 'field's current value is equal to its initial value' situation:
<script type="text/javascript">
changed = 0;
function change(field)
{
	if (field.defaultValue == field.value)
	{
		if (document.getElementById(field.id).currentStyle.backgroundColor != "white")
		{
			document.getElementById(field.id).style.backgroundColor = "white";
			changed--;
		}
	}
If the defaultValue and value of the field in question are the same, then a nested if statement tests if the field background color is not white. If the nested if statement's condition returns true, for example, if field's background color is yellow, then field is given a white background color and the changed state variable is decremented.

Comments

field is itself an object reference, and thus there's no need whatsoever to use the DOM getElementById( ) method or the DOM id property to access the field object; the document.getElementById(field.id) expression(s) can be reduced to simply field in the above code.

• The proprietary currentStyle property/object was implemented by Microsoft in MSIE 5 - go here for its page in the MSDN Library. currentStyle [r]epresents the cascaded format and style of the [parent] object as specified by global style sheets, inline styles, and HTML attributes, quoting Microsoft. Of the OS X GUI browsers on my computer, currentStyle is supported by MSIE and Opera, but not by Camino, Chrome, Firefox, and Safari, which throw an error at this point in the code.

Unlike currentStyle, the standard and more familiar style property/object is not inclusive with respect to the style information it can access; style will not recognize style rules in a style element, for example. However, currentStyle and style are scope-wise equivalent vis-à-vis the second script's change( ) function - they both reflect the style attribute of field's corresponding input element, and that's it - and replacing the change( ) function's currentStyle tokens with style tokens is pretty much all that's necessary to convert the second "Pure Magic Form Script" script to a cross-browser script (there are also a couple of script typos we'll need to deal with - vide infra).

• If you could use a refresher on setting CSS styles dynamically, JavaScript Kit's style object page will get you all sorted out.

• If desired, the if statements can be merged per the previous post:
if (field.defaultValue == field.value && field.style.backgroundColor != "white")
{
	field.style.backgroundColor = "white";
	changed--;
}
Next in the second script's change( ) function we have an else block that handles the 'field's value has been changed' situation:
else
{
	if (document.getElementById(field.id).currentStyle.backgroundColor != "yellow")
	{
		document.getElementById(field.id).style.backgroundColor = "yellow";
		changed++;
	}
}
The above code gives field a yellow background color and increments changed if field's value and defaultValue are not the same AND if field's background color is not already yellow. Like its preceding if clause, the else block can be written as a merged conditional:
else if (field.value != field.defaultValue && field.style.backgroundColor != "yellow")
{
	field.style.backgroundColor = "yellow";
	changed++;
}
The second script's change( ) function then uses the same

field.form.reset.disabled = ! changed;

assignment to activate/disable the reset button that we saw in the first script's change( ) function. Finally, the second script's change( ) function replaces the id="message" div element's Make your changes to the form string with a Click the reset button to go back to the original form text string via the following command:

document.getElementById("message").innerHTML = "<big>Click the reset button to go back to the original form text</big>";

Comments

• It may not be necessary to use the getElementById( ) method to access the second script's text inputs, but we definitely need it or a related DOM method (e.g., the getElementsByTagName( ) method) to access the script's div element.

• We most recently discussed the on-course-to-be-standardized DOM innerHTML property in Blog Entry #162.

• As noted in the "The form and the div" section of Blog Entry #174, the W3C is 'retiring' the big element. I find that the big element is equivalent to a font-size:larger; CSS declaration with all of the OS X GUI browsers on my computer excepting Opera, which renders font-size:larger; text slightly larger than it does big element text.

• On the pm2code.html script page and in the source of the pm2.html demo page, the big element child of the second script's div element is not properly closed:

<div id=message><big>Make your changes to the form<big></div>

Instead of correcting the above mistake, the big element should be removed and replaced with a #message { font-size: larger; } style rule per the preceding comment.

• The above innerHTML command is a one-way assignment: upon restoring the second script's form to its original state via either the change( ) function or the changeall( ) function (which we'll get to momentarily), the div element text does not revert to Make your changes to the form. It is simple enough to give the change( ) function a revert-to-Make your changes to the form capability by replacing its last two statements with:
if (changed) // If changed is 1 or 2, and thus convertible to true:
{
	field.form.reset.disabled = false;
	document.getElementById("message").innerHTML = "Click the reset button to go back to the original form text.";
}
else // If changed is 0, and thus convertible to false:
{
	field.form.reset.disabled = true;
	document.getElementById("message").innerHTML = "Make your changes to the form.";
}
changeall( ) two

Like the first "Pure Magic Form Script" script, the second "Pure Magic Form Script" script contains an onreset-triggered changeall( ) function that redisables the script's reset button and sets the background colors of both script text boxes to white. Here it is:
function changeall(form)
{
	form.reset.disabled = true;
	changed = 0;
	for (var el = 0; el < form.elements.length; el++)
	{
		if (form.elements[el].id != "") /* Some way needed of knowing which to reset -- in this case, only those with an ID. */ 
		{
			document.getElementById(form.elements[el].id).style.backgroundColor = "white";
		}
	}
}
Comments

• You may recall that the first script's changeall( ) function uses the name property of a control, which originated in classical JavaScript but is now part of the DOM's HTMLInputElement interface, to indirectly flag the script's text boxes for setting their background colors; the second script's changeall( ) function uses the DOM id property to do so. However, the size, type, or value property of the HTMLInputElement interface could also be used for this purpose in either changeall( ) function - e.g., if (form.elements[el].size == 14) form.elements[el].style.backgroundColor = "white";.

• Per the preceding comment and the preceding section, the document.getElementById(form.elements[el].id) expression can and should be shrunk to form.elements[el].

• The second script's changeall( ) function does not reset the script's original div element text, but adding a

document.getElementById("message").innerHTML = "Make your changes to the form.";

statement before or after the for loop will take care of that.

HTML detritus

The second script's body element concludes with the following lines of junk code:

<style>
NOBR {color=blue}
</style>
</FONT>
</CODE>
<!-- There are one and two font element end-tags on the pm2code.html page and in the pm2.html source, respectively. Also, in the pm2.html source the font element end-tags and the code element end-tag are separated by the Back hyperlink. -->


The above code should be thrown out (indeed, the color=blue CSS syntax error throws a "Warning" with Firefox and Opera) and doesn't really merit any comment, but while we're here, I should mention that the W3C is also obsoleting the proprietary, Microsoft-implemented nobr element, whose effect can be reproduced by a white-space:nowrap; CSS declaration.

Demo

I thought it would be a good idea to whip up a demo for those of you using browsers that don't support the currentStyle object and/or would like to try out my div text-reversion code. In the div below, click on one or both text boxes and change the text therein in some way; subsequently, return the text to its original value(s) either via the reset button or by deleting/adding the character(s) that you added/deleted initially.

Change and then unchange the text in one or both boxes. Watch the reset button and the text below the form.

Make your changes to the form.

In the next entry, we'll finish our tour of the "JavaScript Form Scripts" series by discussing the event cancelation code in the series' second tutorial, "Checkboxes: Only Two".

reptile7

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)