Buksy
Buksy

Reputation: 12228

jquery, click event doesnt work sometimes

I have form with multiple input type="radio" with text next to them. I want to hide those inputs and show only text, which will react on click and change value of inputs and background color.

HTML:

<div class="right">
  <div>
    <span onclick='$("input.rg1").attr("checked", false).change();'>Choose</span>
    <div>A<input type="radio" name="radio[1]" class="rg1" value="1"></div>
    <div>B<input type="radio" name="radio[1]" class="rg1" value="2"></div>
    <div>C<input type="radio" name="radio[1]" class="rg1" value="3"></div>
  </div>
</div>

Javascript:

// Bind click event on divs and send it to radio input
$("div.right div div").click(function(e){
if(!$(e.target).is("input") )
{
    alert("Clicked Div/Text!")
    $(e.target).children("input").click();
}
});

// Hide all radio inputs, make only texts visible
$("div.right input[type='radio']").hide();

// Bind change event on radio inputs, change
// background-color of text that is next to clicked radio input
$("div.right input[type='radio']").change( function(e){
    alert("change Event "+$(e.target).is(":checked"));
    if( $(e.target).is(":checked") )
    {
        $(e.target).parent().css("background-color", "#A00");
    }
    else
    {
        $(e.target).parent().css("background-color", "#00A");
    }
});

The problem is, when I click on text next to radio (e.g A), 2 alerts pop up and background-color is changed, but if I click on that text again, I got only first alert, but not the second. Why? Right after the first alert, there is $(e.target).children("input").click(); that should run that change event, but it doesn't, although there isn't any condition.

Can any one give me an advice on whats wrong? Thank you

Upvotes: 0

Views: 2615

Answers (3)

Tomm
Tomm

Reputation: 2142

The problem is that you are using radio buttons as input elements. Once checked, clicking them again won't uncheck them and therefore not "change" their status. Not unless you click a different radio button belonging to the same group. This means that the change function will not work if you click the same element twice.

Try using checkboxes and it will work -> http://jsfiddle.net/jPMF9/

Upvotes: 1

Anthony
Anthony

Reputation: 37065

The issue is that you're using the change event, which doesn't fire when a radio is clicked the second time, since it's not changing. But based on your code, you might want to consider using labels, which would allow in every modern browser other than IE8 for you to get the same effect with pure css. The only catch is that your label has to follow your input.

Your HTML redone with labels:

<input type="radio" id="radioa" name="radio[1]" class="rg1" value="1" />
<label for="radioa">A</label>
<input type="radio" id="radiob" name="radio[1]" class="rg1" value="2" />
<label for="radiob">B</label>
<input type="radio" id="radioc" name="radio[1]" class="rg1" value="3" />
<label for="radioc">C</label>

The CSS:

[type=checkbox], [type=radio] {
    display: none;
}    

[type=checkbox] + label, [type=radio] + label {
     background-color: #00A;
}

:checked + label {
     background-color: #A00;
}

And that does it. I went ahead and made it for both radios and checkboxes, since both are checkable, but like I said, it only works if its <input /><label></label> since CSS doesn't (and may never) allow for parent selectors and doesn't yet allow for preceding sibling selectors. If that order isn't an option, you're back to doing it via js.

Upvotes: 1

Koray S.
Koray S.

Reputation: 106

can you please check this solution:

// Bind click event on divs and send it to radio input
$("div.right div div").unbind("click").bind("click", function(e){
if(!$(e.target).is("input") )
{
    alert("Clicked Div/Text!")
    $(e.target).children("input").attr("checked", "checked");
    $(e.target).children("input").trigger("change");
}
});

// Hide all radio inputs, make only texts visible
$("div.right input[type='radio']").hide();

// Bind change event on radio inputs, change
// background-color of text that is next to clicked radio input
$("div.right input[type='radio']").unbind("change").bind("change", function(e){
    alert("change Event "+$(e.target).is(":checked"));
    if( $(e.target).is(":checked") )
    {
        $(e.target).parent().css("background-color", "#A00");
    }
    else
    {
        $(e.target).parent().css("background-color", "#00A");
    }
});

Upvotes: 0

Related Questions