views:

2136

answers:

3

Hey ya'll

I would like the label associated with a radio button 'hot'. I started to implement this using the .siblings() method. I think there must be a better way. The click event on the radio button looks like this:

$(".RadioButton").click(function(event) {

        var questionId = $(this).find('input').attr('name');
        var responseId = $(this).find('input').attr('value');
        var answerText = displayPopupQuizAnswer($(this));

This works great. I would like the same code to execute when the user clicks on the text label accompanying the radio button. The html looks something like this:

<div class="answers">
<span class="radiobutton>
<input type="radio" name="answer1"/>
</span>
<span class="answertextwrapper">
<a href="return false">this is the text</a>
</span>
</div>

This is simplified but it's close. What I want is to capture the click event on the element with class="answertextwrapper" i.e. $(".answerwrapper").click

So I need to somehow reference the input when the text is clicked. Make sense?

Any ideas?

+4  A: 

You can come up with some sort of traversing technique to suit your needs, but I recommend you use the <label> element instead: not only is it the semantically correct way of doing this, you can then add in the for attribute to point it back to the input field it is a label of:

<div class="answers">
    <span class="radiobutton>
       <input type="radio" name="answer1" id="answer1"/>
    </span>
    <label class="answertextwrapper" for="answer1">
        this is the text
    </label>
</div>

And then your Javascript can look like this:

$("span.RadioButton").click(function(event) {
    //...
});

Note that it is much better to prepend the tag name when you are doing class selectors in Javascript (see comments for more). I also removed the empty link as doing it that way is a bad practice as well. You should just add the cursor declaration in your CSS instead if you want the hand to come up.

Paolo Bergantino
Why is it "much" better? Just for readability or is there a performance increase as well?
Phairoh
There is a _huge_ performance gain. With a class selector jQuery has to look at EVERY SINGLE ELEMENT in the document to see if it has the class you are asking for. If you do span.classname, jQuery can use the native (and fast) getElementsByTagName and THEN filter out by class name.
Paolo Bergantino
+9  A: 

Simple, us actual label elements;

When you use these, not only do you gain nice usability, but their click event is bound to the radio button's click event. In otherwords, you don't have to do any additional jQuery, just update your HTML.

Here's it in action - if you have firebug you can clearly see that $(this) always refers to the <input>, regardless of whether or not you actually click on the corresponding <label>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html lang="en">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">

$(function()
{
  $('input.quiz-button').click( function( event )
  {
    console.log( $(this) );
  })
} );

</script>

</head>
<body>
  <form id="test" name="tester">
    <input class="quiz-button" type="radio" name="answer1" id="answer1"/>
    <label for="answer1">this is the text 1</label>
    <input class="quiz-button" type="radio" name="answer2" id="answer2"/>
    <label for="answer2">this is the text 2</label>
  </form>
</body>
</html>
Peter Bailey
oh wow, i did not know this. +1
Paolo Bergantino
You deserve a +1 just for the simple fact that Paolo didn't know about this. @Paulo - You are the Jon Skeet of jQuery :-)
ichiban
Thanks! To be fair, this is a DOM Events thing, not a jQuery thing. Also, it's probably more accurate to say that "clicking on a `<label>` automatically dispatches a click event from it's connected `<input>` - because `<label>` elements do actually dispatch a distinct click event. This means that clicking a label with a connected input actually dispatches TWO nearly-simultaneous click events, with the label's click dispatching first.
Peter Bailey
I love the firebug console.. just learned about it myself. This is a corrent answer however I do not have the luxury of changing my elements at this time.
Nick
http://www.quirksmode.org/dom/tests/labels.html says there are some browsers where this only partially works. Also I didn't see anywhere in the DOM event spec that specifies this behaviour re. labels.
ChrisW
A: 
<div class="answers">
<label class="answertextwrapper"><input type="radio" name="answer1"/> this is the text</label>
</div>

This works the best for me. This way you don't even need to "connect" the input to the label via for property in label element.

maksymko