views:

59

answers:

5

If the code is

<form>
  <input type="radio" name="font"> Arial</input><br>
  <input type="radio" name="font"> Times New Roman</input><br>
  <input type="radio" name="font"> Monaco</input><br>
</form>

<script>

  $('form input').each(function(i, e) {
      alert($(this).text())
  })

</script>

It shows 3 empty strings. How can it show the 3 names of fonts?

try it at: http://jsfiddle.net/bKhsp/3/

+2  A: 

You can't have text inside an <input> tag - it's invalid HTML even though the browser will try to render it, if you want that you should use a <label> wrapper (which keeps the text clickable as well) like this:

<form>
  <label><input type="radio" name="font" value="Arial"> Arial</label><br>
  <label><input type="radio" name="font" value="Times New Roman"> Times New Roman</label><br>
  <label><input type="radio" name="font" value="Monaco"> Monaco</label><br>
</form>

With a loop to match:

$('form input').each(function(i, e) {
  alert($(this).parent().text()); //for the label text
  alert($(this).val()); //for the input value
});

You can view the updated/working fiddle here. For postback reasons, you probably want a value on the inputs as well, so a value for font gets sent.

Nick Craver
Note that IE 7 and lower have bugs with implicit labels - http://www.communitymx.com/content/article.cfm?cid=E251C.
Andy E
I'd prefer not to repeat font name in `value` attribute... but then what if i want the label to say "default font" and the value should be ""... maybe it can say, if the attribute `value` is defined, then use it, otherwise use `$(this).parent().text()`
動靜能量
@動靜能量 - you can do `alert($(this).val() || $(this).parent().text())` for that effect :)
Nick Craver
A: 

The HTML markup is incorrect. Each option needs a value:

<form>
  <input type="radio" name="font" value="Arial"> Arial <br>
  <input type="radio" name="font" value="Times New Roman"> Times New Roman<br>
  <input type="radio" name="font" value="Monaco"> Monaco<br>
</form>

Your jQuery can then look something like this (from memory):

$('form input').each(function(i, e) {
    alert($(this).val());
})
Craig A Rodway
+1  A: 

You should use a <label> element and specify the id of the input element in its for attribute, that way when you click on the text it will check the radio input for you. As Nick Craver mentioned, you can't have text nodes inside an input element.

You can use nextSibling to get the text node following an element, then access its nodeValue property for the text:

$('form input').each(function(i, e) {
    alert(this.nextSibling.nodeValue);
});

This should also be more efficient than solutions that wrap this with jQuery. You can also use this.value to get the value without wrapping and calling .val().

Updated fiddle at http://jsfiddle.net/AndyE/bKhsp/6/.

Andy E
nice. if using jQuery, can you get to the text node like the `nextSibling()` non-jQuery method does?
動靜能量
@動靜能量: I don't think any jQuery traversal methods return text nodes (only elements). The point I was trying to make was that you don't have to sacrifice performance and efficiency when using jQuery. Code that looks like `$(this).val()` is a complete waste of time compared to `this.value`, because of all the unnecessary wrapping, comparing and function calling involved.
Andy E
+2  A: 

Inputs never have end tags, meaning to be correct, you'd have to have the following:

<form>
  <input type="radio" name="font" /> Arial<br />
  <input type="radio" name="font" /> Times New Roman<br />
  <input type="radio" name="font" /> Monaco<br />
</form>

From there, you can take measures to tie the text with its respective radio button:

<form>
  <input type="radio" name="font" id="fontArial"/><label for="fontArial">Arial</label><br />
  <input type="radio" name="font" id="fontTimes"/><label for="fontTimes">Times New Roman</label><br />
  <input type="radio" name="font" id="fontMonaco"/><label for="fontMonaco">Monaco</label><br />
</form>

<script type="text/javascript">
  $('form label').each(function(i, e) {
      alert($(this).text());
  })
</script>

For grabbing the respective radio button from the label, simply take the for attribute for a selector id (for example this takes the value of a label's respective radio button):

$('#' + $(this).attr('for')).val();
Neil
+1 because this selects only elements that have a `for`.
Pekka
There's no need for IDs here, a `<label>` is for the element it wraps, you can see it working in the demo in my answer.
Nick Craver
You're right, you don't have to, but it looks cleaner this way, imo. To each his own though.
Neil
+1  A: 

The input element doesn't have a closing tag. Use a label around the radio button and text, then the text is clickable as it should be:

<form>
  <label><input type="radio" name="font"/><span>Arial</span></label><br>
  <label><input type="radio" name="font"/><span>Times New Roman</span></label><br>
  <label><input type="radio" name="font"/><span>Monaco</span></label><br>
</form>

Putting the text in a span is a good idea, then you can target it separately so that you can style it with CSS.

Use the next function to reach the text from the input:

$('form input').each(function(i, e) {
  alert($(this).next().text())
});
Guffa