/    Sign up×
Community /Pin to ProfileBookmark

capture associated LABEL when you have INPUT (unobtrusively)

if my form is similar to the layout below and i’ve captured a <input>/<select>/<textarea> element and want to capture it’s corresponding <label> element, what’s the best approach without using inline JS?

[code]

<form name=”myform”>
<label for=”email”>Email</label>
<input type=”text” name=”email”/>
<label for=”news”>Newsletter</label>
<ul>
<li><input type=”radio” name=”news” value=”yes”/>Yes</li>
<li><input type=”radio” name=”news” value=”no”/>No</li>
</ul>
</form>[/code]

note that it has to work for situations where the <label> and <input> are siblings and also when the <inputs> are children of another element (in this case a <ul>

to post a comment
JavaScript

11 Comments(s)

Copy linkTweet thisAlerts:
@konithomimoJan 31.2007 — There are many ways to do it, but it depends on where the label is. For example, here is one way to do it:

function getLabel(obj){
var els = document.getElementsByTagName('*');
var cur=-1;
for(var i=0;i&lt;els.length;i++){
if(els[i].nodeName=='LABEL')
cur = i;

if(els[i]==obj){
if(cur==-1)
alert('There is not label for the specified object');
else
alert(els[cur].text);

return true;
}
}
return false;
}
Copy linkTweet thisAlerts:
@FangJan 31.2007 — The attribute [I]for[/I] has a value associated with [I]id[/I] not [I]name[/I].

http://www.w3.org/TR/html4/interact/forms.html#h-17.9.1
Copy linkTweet thisAlerts:
@konithomimoJan 31.2007 — Of course that only gets the last label before a specified node. Here is another way that checks to see if the specified node had a previous sibling that is a label, if not then it runs the function on the parentNode, which would then yield the same result as the code in my previous post:

function getLabel(obj){
if(obj.nodeName=='BODY')
{
alert('There is no label for the specified object');
return false;
}

var cur = -1;
var pare = obj.parentNode;
var children = pare.childNodes;
for(var i=0;i&lt;children.length;i++){
if(children[i].nodeName=='LABEL')
cur=i;
if(children[i]==obj){
if(cur==-1)
getLabel(pare);
else
{
alert('The label for the specified object is ' + children[cur].text);
return true;
}
}
}
}
Copy linkTweet thisAlerts:
@mrhooJan 31.2007 — When you have a group of controls you should use a fieldset and legend, a label can only be associated with one control.

By enclosing controls within their labels, you do not need the 'for' attribute, and it is easy to find the label-

if(element.parentNode.nodeName=='LABEL')

This syntax allows you to put the label text either before or after the control, as you see fit.

<form name="myform" action="">

<div>

<label>Email <input type="text" name="email"></label>

<fieldset style="border:none">

<legend>Newsletter</legend>

<ul>

<li> <label> <input type="radio" name="news" value="yes">Yes</label></li>

<li> <label> <input type="radio" name="news" value="no">No</label></li>

</ul>

</fieldset>

</div>

</form>
Copy linkTweet thisAlerts:
@bcamp1973authorJan 31.2007 — hmmm...interesting. mrhoo, is that considered the "standard compliant" way of doing it? I've seen some various discussions on the issue of labels/controls before, but I like your solution better than others i've seen...
Copy linkTweet thisAlerts:
@mrhooJan 31.2007 — I did validate the form on an html 401 strict page, by removing the closing slashes on the inputs. It might validate xhtml if you re-close the input tags, I don't know.

I like to validate if I can, but mainly the code is easier to write and read

when you treat labels like containers.

And using fieldsets to group related controls simplifies navigating (and validating ) a long form.
Copy linkTweet thisAlerts:
@felgallFeb 01.2007 — If you add a for attribute to the label tag and a corresponding id attribute to the input tag contained within the label then your code will work on more browsers since there are a few that expect the input to be enclosed in the label (even though this is nonstandard) as well as some that follow the standards and wont associate the label with the input even if it does enclose it unless they are also attached together using for-id as per the standards.
Copy linkTweet thisAlerts:
@mrhooFeb 01.2007 — from The W3 HTML forms reference:

To associate a label with another control [B]implicitly[/B], the control element must be within the contents of the LABEL element.

In this example, we implicitly associate two labels with two text input controls:

<FORM action="..." method="post">

<P>

<LABEL>

First Name

<INPUT type="text" name="firstname">

</LABEL>

<LABEL>

<INPUT type="text" name="lastname">

Last Name

</LABEL>

</P>

</FORM>

Note that this technique cannot be used when a table is being used for layout, with the label in one cell and its associated control in another cell.
[/QUOTE]

http://www.w3.org/TR/html4/interact/forms.html
Copy linkTweet thisAlerts:
@FangFeb 01.2007 — ... By enclosing controls within their labels, you do not need the 'for' attribute, ...[/QUOTE]As [B]felgall[/B] wrote, you must use the [I]for - id [/I]association if the label is to function correctly in all browsers.

[B]bcamp1973[/B] How do you intend firing the event to find the associated label(s)?
Copy linkTweet thisAlerts:
@felgallFeb 01.2007 — from The W3 HTML forms reference:


http://www.w3.org/TR/html4/interact/forms.html[/QUOTE]


Not all browsers follow the standard with regard to implicit references the same as not all browsers follow the standard with regard to explicit for-id references and so to get it to work in all the browsers that support labels you should use both.
Copy linkTweet thisAlerts:
@mrhooFeb 01.2007 — I was really hoping Microsoft would have fixed this by now. IE is, of course, the browser that needs the 'for', requiring an id as well as a name in a labeled control.

This may interest some people- it has the same form with and without the for=id attribute. Different clients behave differently on the two forms, but the second comes closest to behaving the same in different browsers.

It validates strict, so I can live with the fors...


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>The Yankee Webshop Guide-Elements of HTML</title>

<style type="text/css">

body{font-size:120%;color:black;background:white;font-family:"Times New Roman", serif}

p{padding-left:10px;margin:10px}

body hr{visibility:hidden}

button,a,select, #inBtns input, #input_6{cursor:pointer}

div{margin:1ex 1em;padding:1ex;border:solid black 4px;background:#eee}

input,button,textarea,#intxtEval,select{font-size:1em}

input,select,textarea,button,fieldset, legend, label{padding:0 2px;

margin-right:2px;font-weight:bolder}

fieldset{border-width:2px;background:#ddd;padding:1ex}

legend,label{background:#fadeaf}

</style>

</head>

<body>

<p id="p_opts"><a href="../webshop.html">Home</a></p>

<h1 id="firstH1">HTML Elements</h1>

<h2>Form &lt;form&gt;</h2>

<div>

<form action="" onsubmit="return false">

<div>

<h3>(&lt;fieldset&gt? A fieldset is a bit like a div for grouping form controls.

The legend element should be the first child of its fieldset.

</h3>

<fieldset id="inBtns"><legend>Input button and image types (legend)</legend>

<input type="submit" value=" Submit">

<input type="reset" value="reset" name="input_2">

<input type="button" value="button" name="input_3">

</fieldset>

<fieldset><legend>checkbox group (legend)</legend>

<label>checkbox 1?label)<input type="checkbox" name="input_4" value="checkbox"></label>

<label>checkbox 2?label)<input type="checkbox" name="input_4" value="checkbox"></label>

<label>checkbox 3?label)<input type="checkbox" name="input_4" value="checkbox"></label>

</fieldset>

<fieldset><legend>text input group (legend)</legend>

<label>text input: (label) <input type="text" value="text box" name="input_t"></label>

<label>password: (label)<input type="password" value="" name="input_5"></label>

<label>file input: (label)<input type="file" value="file" name="input_6"></label>

</fieldset>

<fieldset>

<legend>Radio (legend)</legend>

<label> radio 1<input type="radio" value="radio" checked="checked" name="input_7"></label>


<label>radio 2<input type="radio" value="radio" name="input_7"></label>

<label>radio 3<input type="radio" value="radio" name="input_7"></label>


<label>radio 4<input type="radio" value="radio" name="input_7"></label>

</fieldset>

<p>

<select name="select_1">

<optgroup label="First optgroup">

<option selected="selected" value="option">Select element

(&lt;select&gt?</option>

<option value="2">Option 2</option>

<option value="3">Option 3</option>

<option value="2">Option 4</option>

</optgroup>

<optgroup label="Second optgroup">

<option value="3">Option 5</option>

<option value="2">Option 6</option>

<option value="3">Option 7</option>

</optgroup>

</select> <button id="button_1">Button Element</button></p>

<p><textarea rows="4" name="textarea1" cols="40">Text Area

(&lt;textarea&gt?</textarea></p>

</div>

</form>

</div>

<hr>

<h2>Form &lt;form&gt; IE</h2>

<div>

<form action="" onsubmit="return false">

<div>

<h3>(&lt;fieldset&gt? A fieldset is a bit like a div for grouping form controls.

The legend element should be the first child of its fieldset.

</h3>

<fieldset id="fieldBtns"><legend>Input button and image types (legend)</legend>

<input type="submit" value=" Submit">

<input type="reset" value="reset" name="input_2">

<input type="button" value="button" name="input_3">

</fieldset>

<fieldset><legend>checkbox group (legend)</legend>

<label for="input_4a">checkbox 1?label)<input type="checkbox" name="input_4" id="input_4a" value="checkbox"></label>

<label for="input_4b">checkbox 2?label)<input type="checkbox" name="input_4" id="input_4b" value="checkbox"></label>

<label for="input_4c">checkbox 3?label)<input type="checkbox" name="input_4" id="input_4c" value="checkbox"></label>

</fieldset>

<fieldset><legend>text input group (legend)</legend>

<label for="input_t">text input: (label) <input type="text" value="text box" name="input_t" id="input_t"></label>

<label for="input_5">password: (label)<input type="password" value="" name="input_5" id="input_5"></label>

<label for="input_6">file input: (label)<input type="file" value="file" name="input_6" id="input_6"></label>

</fieldset>

<fieldset>

<legend>Radio (legend)</legend>

<label for="input_7a"> radio 1<input type="radio" value="radio" checked="checked" name="input_7" id="input_7a"></label>


<label for="input_7b">radio 2<input type="radio" value="radio" name="input_7" id="input_7b"></label>

<label for="input_7c">radio 3<input type="radio" value="radio" name="input_7" id="input_7c"></label>


<label for="input_7d">radio 4<input type="radio" value="radio" name="input_7" id="input_7d"></label>

</fieldset>

<p>

<select name="select_1">

<optgroup label="First optgroup">

<option selected="selected" value="option">Select element

(&lt;select&gt?</option>

<option value="2">Option 2</option>

<option value="3">Option 3</option>

<option value="2">Option 4</option>

</optgroup>

<optgroup label="Second optgroup">

<option value="3">Option 5</option>

<option value="2">Option 6</option>

<option value="3">Option 7</option>

</optgroup>

</select>

<button id="button_el">Button Element</button></p>

<p><textarea rows="4" name="textarea1" cols="40">Text Area

(&lt;textarea&gt?</textarea></p>

</div>

</form>

</div>

</body>

</html>
×

Success!

Help @bcamp1973 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...