There's a large family of (X)HTML elements that I've left out: (X)HTML forms. Forms are a means of input. When you enter a name and a password to log into a website, when you post to a forum, when you fill out information about yourself online, when you take an online quiz, you are using a form.
And they are completely useless without scripting.
All core, language, and event attributes are permissible with these elements, unless otherwise stated. Some have events of their own; since those can be used like attributes, they're mentioned in the attribute lists, but are highlighted by their color.
There are nine elements that are especially for forms, but the form family of elements isn't like other families such as lists and tables, which exist on their own. Many form elements must be nested inside block elements; these block elements are what structure the form.
JavaScript is designed to play extra-special nice with forms. Form elements are given extra properties to facilitate their use. Those properties are tied directly to attributes with the same name. Two of the most important attributes/properties are name
and value
.
The name
attribute holds a very important place in forms. Virtually every language created to work with forms (both client-side and server-side) uses these names to extract data. JavaScript is no different. The following form-related elements get the name
attribute:
Yes, I know I introduced the button
class way back in Inline Elements, but they're usually used in forms.
JavaScript has a neat way of handling the name attribute: the value of the name
attribute is treated like the name of a property which contains a reference to that form
element node. For example, if I gave a form
element the name
Form1
, then Form1
would be a property of the document
node. Any form elements with name
attributes of their own within that form
element can be referred to using its name
as a property of Form1
. If multiple elements have the same name
value, then JavaScript considers that a node list.
The value is what's passed on to the script. It can be defined in the value
attribute (with the exception of the textarea
element, where the value is set through the element's content), but can be overridden by interaction with the input.
The value of an input is accessed through the property of the value
property.
Do note: If you set a default value but override it through interaction with the input, you will still be able to get the original value through the getAttribute
function (for most inputs) or through
for the firstChild
.data
textarea
element, since those methods read right from the webpage code; the webpage code is only altered through methods I will explain in DOM Manipulation. I've used this to my advantage.
Element Name: form
There are form elements, and then there's the form
element. When I talked about form elements, I meant the numerous elements that accept input, give the form structure, label the form, and so on and so forth. The form
element is the element that contains the form itself.
GET(the default) and
POST, which describes how the information from the form is sent.
GETaffects the URI, and a
?in the URI is a good indication that this is going on. The server-side script generating the resultant page then gets the necessary information from the URI.
POST, on the other hand, just posts information to the server without affecting the URI.
application/x-www-form-urlencoded.
input
element is of the file uploadtype.
For a form to function, it has to have a means of receiving input. The input
, textarea
, and select
elements all provide various means of entering that input.
All input elements must be descendants of block elements within the form
element.
disabled
.onfocus
, onblur
, onselect
, and onchange
are all events and may be set through client-side scripting.
Element Name: input
The input
element is where you enter the information. It must be contained within a block element, such as p
or li
.
The input
element is an empty element. It has no end tag.
The following are used in all input
elements. Attributes used in specific types are explained in their own sections.
text
The attribute type
is the most important attribute in an input
element. It describes what kind of input it is. The type
has the following possible values:
* Server-side use only
Every attribute I mention in this section on input
elements can be used with any type. However, not all of them will do what is expected. For example, you may use the checked
attribute with an input
element with type
text
. It just won't do any good.
The attribute type
corresponds with the property type
, and may be changed through JavaScript.
Both of these are text boxes, but the text inside them is handled differently. In a textbox, it's clear for all to see; in a password box, the text is obscured:
readonly
.The text of a textbox or a password box is known as its value. It's this property that you use to get its information.
Below is a simple form and the script used to get its information:
var
form = document
.Form;var
txt = document
.getElementById
("Text-text"
).firstChild
;var
pass = document
.getElementById
("Pass-text"
).firstChild
;onclick
= function
(){Write
(form.Input[0].value
, txt);Write
(form.Input[1].value
, pass);function
Write
(box, span){"Null"
;Notice that I highlighted the contents of the name
attributes to show how the form name becomes a property name of the document
and the input names become property names of the form; that's what I meant by, In JavaScript, the value of name becomes an property of its respective form element node.
Below is the result:
Checkboxes and radio buttons allow for multiple choice. There is one major difference: More than one checkbox can be chosen, but only one radio button may be chosen.
If two or more radio buttons share the same name
, only one of those buttons can be checked at any time. Below, I have two groups of radio buttons arranged in columns; one is named G1
, the other G2
.
Three share the name
G1
, the other three the name
G2
. Therefore, there are two groups and only one from each group can be chosen (two choices in total).
Which is the case.
checked
.value
attribute is a checkbox's or radio button's only means of passing on information beyond whether or not it is checked to the script.When you assign the same name to inputs, the name, used as a property, returns an actual node list, which you can then use like an array.
Both types of inputs have a property called checked. If a checkbox or radio button is checked (i.e. selected), the property returns the boolean value true
. Otherwise, it returns the value false
.
Look at the example below:
I have one list with checkboxes, and another with radio buttons.
You can't show both 1 and 2 or 2 and 4 sentences, but you can have the letters underlined, overlined, and struck through. Therefore, radio buttons for the number of sentences, and checkboxes for the text decoration.
Below is the full script:
var
form = document
.Form1
;var
txt = document
.getElementById
("Display_Text"
);var
lorem = document
.getElementById
("Lorem"
).firstChild
.data
.split
("."
);Click
.onclick
= function
(){var
sentence = -1;var
text = ""
;var
decor = ""
;do
{". "
;while
(!(form.Sentences
[sentence].checked
));firstChild
.data
= text;for
(var
l = 0; l < form.Decorate
.length
; l++){if
(form.Decorate
[l].checked
){Decorate
[l].value
+ " "
;style
.textDecoration
= decor;The radio buttons in the Sentences
group is handled by a do-while loop.
do
{". "
;while
(!(form.Sentences
[sentence].checked
));The Lorem Ipsum text is split using the period as a delimiter, resulting in an array of four sentences (lorem). Every time the loop is run (as a do-while loop, it's run at least once), sentence (initially set to negative 1) is incremented by one, the text stored in the slot that corresponds to the variable sentence is added to text, and the while condition keeps everything going so long as the radio button that sentence had corresponded to is not checked.
There's a couple of things I want to point out. First, if no radio buttons in that group were checked, this would technically be an infinite loop (or, rather, would crash when it ran out of nodes), but recall in the HTML, one of the radio buttons has the attribute checked
, so even if you don't check a radio button, one will be automatically checked. Second, I omitted the value
attribute from the radio buttons— I don't need it. The do-while loop tells the script to keep adding text until it encounters a checked radio button, allowing me to omit value
.
Since only one radio button can be checked, the loop doesn't need to run anymore once a checked one is found. Thus, a while loop (or in this case, a variation thereof) is used.
Meanwhile, since any number from none to all checkboxes can be checked, we have to go through all of them. This calls for a for loop, which will check all of them.
for
(var
l = 0; l < form.Decorate
.length
; l++){if
(form.Decorate
[l].checked
){Decorate
[l].value
+ " "
;This loop thus runs through the node list represented by Decorate
, so the if statement checks to see if each one is checked (which, remember, returns a value of true
). Each time one is, the variable decor (which starts out empty) is updated, and the final result is later sent to the style property textDecoration
. As you know, in CSS the value underline overline strikethrough
is perfectly acceptable, and so it is with JavaScript.
The last two inputs that are commonly used for client-side scripts are the reset button and the regular button. The reset button simply resets the form to its original state, while the regular button is there for something to click on (for example, if you're running a client-side script).
The value
attribute of these alter their text. Normally, a button-type input has no text, and a reset button has simply the word Reset
.
There are four types of inputs that I didn't mention, mostly because they're used with server-side scripting:
action
attribute of the form
element are the x- and y-coördinates of where you clicked on the image. Yes, it works like an server-side image map, as explained in Image Maps. It has the following attributes:img
elements.Element Name: textarea
The textarea
element is used to contain large amounts of text, and therefore shows multiple lines (as opposed to the input
element, which shows only one).
While this attribute does not have a value
attribute (though it does have a value
property), this is offset by the fact that this is not an empty element, and may therefore contain text. It cannot have other elements nested in it, though, and treats them like the title
element does.
There are other attributes that may be used with the input
element, but work best with specific types.
readonly. It means the text in it can't be directly altered by the user.
While this element does not have a name
element, you can identify it by the id
element, which will have much the same effect.
The text area presents a special challenge because its contents may include new lines, which I explained back in Text.
In the example below, the script takes the text entered into a text area, and writes the first three lines that contain text to three separate p
elements. You will see that the id
attribute can be used like a property for these elements.
p
Elementsvar
form = document
.getElementById
("Form"
);var
txt = form.Text
;var
write = document
.getElementById
("Write"
).getElementsByTagName
("p"
);Click
.onclick
= function
(){var
txt_split = (txt.value
.match
("\r\n"
))?txt.value
.split
("\r\n"
):txt.value
.split
("\n"
);var
l = 0;var
pc = 0;while
(pc < write.length
&& l < txt_split.length
){if
(txt_split[l].length
> 0){firstChild
.data
= txt_split[l];Note the highlighted line. Some browsers see a new line in a text area as a carriage return character (\r
) followed by a new line character (\n
), while others see a new line as simply a new line character. Here, I have set up the script to choose which to split the line on.
The result is below:
There are several blank lines, but all have a length of 0, which means that the if statement skips them.
Dropdown menus are yet another means of input. These elements come in a specific set. The elements are:
Element Name: select
The select
element contains all the options associated with it. This element must be a child of a block element.
Element Name: option
The option element is what contains the values that are passed on to the script. Moreover, it is not an empty element, but may contain text, since the contents of the value
attribute and the text of the element may indeed differ.
option
element with this boolean attribute is pre-selected. If there is more than one option
element within the same select
element with this attribute, the last option
element with this attribute is preselected. It corresponds with the JavaScript property selected
.option
element (and thus the entire select
element) passes on to the script.Element Name: optgroup
The optgroup
element contains a group of options. This creates a heirarchy in the list of options; useful for organizing a list of options.
Below is a page that uses all of these elements:
Here is the code of the elements in question:
I could have easily arranged them like this as well, eschewing the optgroup
altogether:
optgroup
elementsBelow is the script that works with this particular control:
var
form = document
.getElementById
("Form"
);var
txt = document
.getElementById
("Answer"
).firstChild
;Click
.onclick
= function
(){var
ans = Number
(form.Selection
.value
);if
(ans > 5){data
= "greater than 5"
;else
if
(ans < 5){data
= "less than 5"
;else
{data
= "equal to 5"
;Below, I select a random option, and click the button for a comparison.
If I want to get rid of the button, and have simply selecting an option do the comparison, a simple change of the code suffices:
var
form = document
.getElementById
("Form"
);var
txt = document
.getElementById
("Answer"
).firstChild
;Selection
.onchange = function
(){var
ans = Number
(form.Selection
.value
);if
(ans > 5){data
= "greater than 5"
;else
if
(ans < 5){data
= "less than 5"
;else
{data
= "equal to 5"
;I set the event to detect a change in Selection
's value, and that runs the script instead, which means I can get rid of the button:
There are two things you can do to make a form easier to work with. First, you can use labels for all your input elements. Second, you can break the form up into smaller, more manageable parts and label those parts. The first is done with the label
element, the second with the fieldset
and legend
elements
Element Name: label
The label
element is usually used with the input
element, though it can also be used with textarea
and select
as well.
It is permissible for other inline elements (including input
, textarea
, select
, and other label
elements) to be nested inside a label
element.
label
that has a for
attribute will place focus on the element that the for
attribute refers to. In the case of checkboxes and radio buttons, this will actually select them.Element Name: fieldset
The fieldset
element is like a div
element for forms; it breaks the form up into separate chunks. However, it's not supposed to contain anything but whitespace (enters, tabs, and spaces) and elements nested therein. If given an ID that matches the name given to form elements, it will be considered part of the resulting node list.
Unlike most form elements, it has no special attributes.
Element Name: legend
The legend
element gives a title to the fieldset
element and must be its first child. Like the fieldset
element, legend
has no special attributes.
Below is a form that is arranged and labelled with the elements mentioned above. Yes, it's an adjustment of the example with checkboxes and radio buttons.
With the stylesheet of the page removed, the form looks like this:
Do note: I did not change the script at all. These elements don't affect the script in any way. Yes, I know part of the page was truncated; those are the same paragraphs as you saw in the original radio button and checkbox demonstration.
Earlier in this chapter, I mentioned that there were a few attributes that corresponded with JavaScript properties in forms. Those attributes were:
JavaScript reads from these properties, but it can also set them—and through setting them, alter the inputs themselves. To demonstrate this, I created a webpage where you can choose what kind of input an input
element will be.
form
action
=""
id
="Form"
>p
><label
>Input Types:</label
> <select
name
="Type"
>optgroup
label
="Text Inputs"
>option
value
="text"
selected
="selected"
title
="Insert text"
>Text</option
>option
value
="password"
title
="Enter Password"
>Password</option
>option
value
="file"
title
="file.html"
>File</option
>optgroup
>optgroup
label
="Checked Inputs"
>option
value
="radio"
>Radio Button</option
>option
value
="checkbox"
>Check Box</option
>optgroup
>optgroup
label
="Button Inputs"
>option
value
="submit"
title
="Submit Query"
>Submit Button</option
>option
value
="reset"
title
="Reset"
>Reset Button</option
>option
value
="button"
>Button</option
>option
value
="image"
>Image</option
>optgroup
>select
></p
>p
><label
>Input To Be Changed</label
>: <input
name
="Input"
value
="Insert text"
src
="./arrow.png"
></p
>form
>var
form = document
.getElementById
("Form"
);var
inp = form.Input
;var
sel = form.Type
;var
ops = sel.getElementsByTagName
("option"
);onchange
= function
(){type
= sel.value
;checked
= true
;var
i = 0;while
(!ops[i].selected
){i++;}value
= ops[i].getAttribute
("title"
);The important part of the script is highlighted: The input type is set to the value of the select
element.
I have used this in actual websites! An input
element, set to the button
type, had an onmousedown
event that ran a whole bunch of error checking to make sure all inputs were properly filled out. If there was a problem, alert boxes would show up and point out the errors and the type remained button
(which of course, meant the form wasn't submitted to the server). If all was done correctly, however, the input
element's type was set to Submit
, which meant the form was submitted to the server for processing.
I have also done something similar with the disabled
property. A server-side script ignores inputs that are disabled. It also ignores checkboxes that aren't checked. Using a script that boiled down to input.
(basically, if disabled
= !controlling_checkbox.checked
checked
was true, disabled
was false and vice versa) I was able to choose which sets of inputs were read from.
To demonstrate, I have created something similar here: a form in which a checkbox decides whether or not the inputs in each fieldset
element are disabled or not.
form
action
=""
id
="Form"
>fieldset
><legend
>Group 1</legend
>label
>Use These Inputs?</label
><input
type
="checkbox"
name
="Use_Inputs"
checked
="checked"
>p
><select
>option
>Choice 1</option
>option
>Choice 2</option
>option
>Choice 3</option
>option
>Choice 4</option
>select
></p
>p
><textarea
cols
="11"
rows
="1"
>Block Of Text</textarea
></p
>p
><input
type
="radio"
><input
type
="radio"
><input
type
="radio"
></p
>fieldset
>fieldset
><legend
>Group 2</legend
>label
>Use These Inputs?</label
><input
type
="checkbox"
name
="Use_Inputs"
checked
="checked"
>p
><select
>option
>Choice 1</option
>option
>Choice 2</option
>option
>Choice 3</option
>option
>Choice 4</option
>select
></p
>p
><textarea
cols
="11"
rows
="1"
>Block Of Text</textarea
></p
>p
><input
type
="radio"
><input
type
="radio"
><input
type
="radio"
></p
>fieldset
>form
>var
form = document
.getElementById
("Form"
);var
use_inp = form.Use_Inputs
;for
(var
i = 0; i < use_inp.length
; i++){onclick
= function
(i){return
function
(){var
field = use_inp[i].parentNode
;var
selects = field.getElementsByTagName
("select"
);var
textareas = field.getElementsByTagName
("textarea"
);var
inps = field.getElementsByTagName
("input"
);for
(var
ii = 0; ii < selects.length
; ii++){disabled
= !(use_inp[i].checked
);for
(var
ii = 0; ii < textareas.length
; ii++){disabled
= !(use_inp[i].checked
);for
(var
ii = 1; ii < inps.length
; ii++){disabled
= !(use_inp[i].checked
);Below, you can see that the checkbox in the first fieldset
element is checked and the inputs are active. Meanwhile the checkbox in the second fieldset
element is unchecked, and the inputs are disabled.
I would like you to notice something about the highlighted for loop: It starts at 1, not 0. The reason for this is that input
element #0 is the checkbox that controls the disabling of the other inputs. If I disable that, I'd have to reload the page to enable those inputs again.
In the same way that you can control the type and disabling, you can set the value of an input using the value
property. In textboxes and password and text inputs, it changes the text; in submit, reset and button-type inputs, it changes the text of the buttons, and in select
elements, the option
element with that value is selected.
Well, that's it for (X)HTML elements. Now that I've explained forms, I've taught every element in HTML 4.01 Strict and XHTML 1.0 Strict. That does not, however, mean I'm done with the (X)HTML DOM, since there's plenty to play with yet...