user2133435
user2133435

Reputation:

Show / Hide div if checkbox selected

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>

Fiddle

Upvotes: 1

Views: 209

Answers (5)

Stephen P
Stephen P

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

samair ali
samair ali

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

Bryan Dellinger
Bryan Dellinger

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

matthias_h
matthias_h

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

G&#246;ksel &#214;ZER
G&#246;ksel &#214;ZER

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

Related Questions