Reputation:
I have a checkbox with two options:
<label><input type="checkbox" value="Dogs">Dogs</label>
<label><input type="checkbox" value="Cats">Cats</label>
With the condition that if Cats is checked, append a div in that input's label:
jQuery("form").change(function() {
if (jQuery('input[value="Cats"]').is(':checked')) {
jQuery('input[value="Cats"]').parent('label').append('<div class="cats-notice">You love cats, nice one</div>');
} else {
jQuery(".cats-notice").remove();
}
});
If Cats is selected, the div appends. Great. But then if Dogs is then selected, it appends the div again. Deselect dogs and the div is appended again and so on. Why are Dogs getting involved?
n.b. In my scenario I can't [easily] add classes or ids to the inputs.
jQuery("form").change(function() {
if (jQuery('input[value="Cats"]').is(':checked')) {
jQuery('input[value="Cats"]').parent('label')
.append('<div class="cats-notice">You love cats, nice one</div>');
} else {
jQuery(".cats-notice").remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input name="dogs" type="checkbox" value="Dogs"> Dogs</label>
<label><input name="cats" type="checkbox" value="Cats"> Cats</label>
</form>
Upvotes: 1
Views: 209
Reputation: 14800
Checking the Dogs checkbox and unchecking it are both a change
on the form, so your change function gets run when either the Dogs or Cats checkbox is toggled.
Your if-test is looking to see if the Cats checkbox is checked, and if it is it appends the div.
So, Cats is checked the first time, the change is fired, the test sees that the Cats checkbox is checked and it appends the div. Fine so far.
Now, the Dogs checkbox is checked, which is a change, so the change event handler runs. It tests to see if the Cats checkbox is checked, and it still is checked because toggling the Dogs checkbox doesn't affect the Cats checkbox.
This is why the Dogs are "involved".
It's not clear what you want to happen — should Dogs do nothing at all? Should dogs toggle its own div?
What can you do to prevent Dogs from getting involved?
One way is you could use the event parameter (which you're not using now) to see which checkbox you're processing.
jQuery("form").change(function(e) {
if (e.target.name==="cats") {
if (jQuery('input[value="Cats"]').is(':checked')) {
jQuery('input[value="Cats"]').parent('label')
.append('<div class="cats-notice">You love cats, nice one</div>');
} else {
jQuery(".cats-notice").remove();
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input name="dogs" type="checkbox" value="Dogs"> Dogs</label>
<label><input name="cats" type="checkbox" value="Cats"> Cats</label>
</form>
Another way is to attach the handler to only the Cats checkbox, instead of the form (as Göksel ÖZER in another answer, though I am binding to the change
event not the click
event here)
jQuery("input[name=cats]").change(function(e) {
if (jQuery('input[value="Cats"]').is(':checked')) {
jQuery('input[value="Cats"]').parent('label')
.append('<div class="cats-notice">You love cats, nice one</div>');
} else {
jQuery(".cats-notice").remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input name="dogs" type="checkbox" value="Dogs"> Dogs</label>
<label><input name="cats" type="checkbox" value="Cats"> Cats</label>
</form>
(Note I also like some of the other changes Göksel ÖZER made in the code, but I tried to keep mine as close to your original code as I could.)
Further, although you say "Show / Hide" div, you're actually appending and removing a div element — a new one each time — which is different than showing/hiding an existing element.
You also say "I can't [easily] add classes or ids to the inputs" — but manipulating the classes on an element is no more work than you're already doing.
The question is: are you writing the Javascript to act on some HTML & CSS that you can't control? If that's the HTML you have and the "cats-notice" div doesn't exist you have no choice but to add it via the Javascript, but if you can modify the page source yourself you can easily show/hide existing divs.
$("form").change(function(e) {
const section = e.target.name;
$(`.${section}-notice`).toggleClass('active');
});
[class$="-notice"] {
display: none;
}
.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input name="dogs" type="checkbox" value="Dogs"> Dogs</label>
<label><input name="cats" type="checkbox" value="Cats"> Cats</label>
</form>
<div class="cats-notice">You love cats, nice one</div>
<div class="dogs-notice">You love dogs, nice one</div>
Upvotes: 0
Reputation: 802
i feel the easiest thing you can do is this
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input name="dogs" type="checkbox" value="Dogs"> Dogs</label>
<label><input name="cats" type="checkbox" value="Cats"> Cats</label>
</form>
<script>
jQuery('input[value="Cats"]').on("click", function(){
if (jQuery('input[value="Cats"]').is(':checked')) {
console.log('working')
jQuery('input[value="Cats"]').parent('label')
.append('<div class="cats-notice">You love cats, nice one</div>');
} else {
jQuery(".cats-notice").remove();
}
})
</script>
instead of on form change you can use
jQuery('input[value="Cats"]').on("click",function(){})
in future if you want for multiple check inputs you can use input type check and then loop it
Upvotes: 0
Reputation: 5294
just move your code around a little bit. as mentioned in the other answers you are firing on form change. so when you choose dog the form is changed and it still checks if cat is checked.
so when the form change just remove your cats notice first and then if cats is checked add it.
jQuery("form").change(function() {
jQuery(".cats-notice").remove();
if (jQuery('input[value="Cats"]').is(':checked'))
jQuery('input[value="Cats"]').parent('label').append('<div class="cats-notice">You love cats, nice one</div>');
});
Upvotes: 0
Reputation: 11416
You can check if the .cats-notice
div is already appended using length
:
jQuery("form").change(function() {
if (jQuery('input[value="Cats"]').is(':checked') && jQuery(".cats-notice").length == 0) {
jQuery('input[value="Cats"]').parent('label')
.append('<div class="cats-notice">You love cats, nice one</div>');
} else if (jQuery('input[value="Cats"]').is(':not(:checked)')) {
jQuery(".cats-notice").remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input type="checkbox" value="Dogs">Dogs</label>
<label><input type="checkbox" value="Cats">Cats</label>
</form>
Upvotes: 0
Reputation: 267
It might be something like that if I understood correct:
$(document).ready(function(){
$('input[value="Cats"]').click(function(){
if($(this).prop("checked") == true){
jQuery('input[value="Cats"]').parent('label').append('<div class="cats-notice">You love cats, nice one</div>');
}
else if($(this).prop("checked") == false){
jQuery(".cats-notice").remove();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><input name="dogs" type="checkbox" value="Dogs"> Dogs</label>
<label><input name="cats" type="checkbox" value="Cats"> Cats</label>
</form>
Upvotes: 2