4

i have div that have image, label and input check-box. what i like when i click on div, it change check-box status from true to false and vise verse

jQuery

$(".markerDiv").click(function () {

    if ($(this).find('input:checkbox[name=markerType]').is(":checked")) {

          $(this).find('input:checkbox[name=markerType]').attr("checked", false);
    }
    else {
          $(this).find('input:checkbox[name=markerType]').attr("checked", true);
    }


 alert($(this).find('input:checkbox[name=markerType]').is(":checked"));
});

html

<div class="markerDiv"  id="maker_school"><label class="marker_label">School</label> <input class="marker_ckeckbox" name="markerType" value="school" type="checkbox"  /> </div> <br />
K.Z
  • 5,201
  • 25
  • 104
  • 240

7 Answers7

6

You can select checkbox with children('input[type="checkbox"]') selector and change its state with the following code

$('.markerDiv').on('click', function(){
   var checkbox = $(this).children('input[type="checkbox"]');
   checkbox.prop('checked', !checkbox.prop('checked'));
});
Ilu
  • 894
  • 6
  • 12
  • why suggesting `children` rather than `find`? – TecHunter Jul 04 '13 at 09:00
  • 1
    @TecHunter Because the `checkbox` element is immediate children of `.markerDiv`. If it was deeper in the tree I would use `find`. I am not sure about the performance side of this, but I'll do some research on it. – Ilu Jul 04 '13 at 09:05
  • that's a good point if you have value arguments :) +1 for that – TecHunter Jul 04 '13 at 09:09
  • 1
    After browsing for a while I found [this site](http://jsperf.com/jquery-children-vs-find/18) to test performance between `find` and `children`, and it seems `find` is indeed faster with such high element count. However, in this case the element count is low and I would guess we can refer to [this site](http://blog.ekini.net/2009/03/16/jquery-children-vs-find-which-is-faster/) saying that `children` is faster. Anyway, it's intresting topic to research, but I would guess in this case it doesn't matter enough to go deeper. :P – Ilu Jul 04 '13 at 09:42
  • nice catch! interesting subject indeed – TecHunter Jul 04 '13 at 11:16
5

You can do it without writing any javaScript/jQuery method.

Just wrap div inside a label:-

div {
  background: red;
  padding: 10px 40px;
}
<label for="myCheck">
  <div>
    <input id="myCheck" type="checkbox" />Remember Me!
  </div>
</label>
Tunaki
  • 132,869
  • 46
  • 340
  • 423
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
  • Please do not link to external resources when you can just embed it directly in your answer. – Tunaki May 08 '16 at 19:29
  • 1
    Element div is not allowed as a child of element label. http://stackoverflow.com/questions/18609554/is-div-inside-label-block-correct – Jan W Feb 23 '17 at 21:19
3

The simplest solution would be to put the checkbox inside of the label. That way, no JS/jQuery is required.

If you can't/don't want to do that, you can do the following:-

$(".markerDiv").click(function (e) {    
    if (!$(e.target).is('input:checkbox')) {
        var $checkbox = $(this).find('input:checkbox');
        $checkbox.prop('checked', !$checkbox.prop('checked'));
    }
});

This is pretty much the same as what you already had. Except it uses prop(). The reason yours didn't work properly is because when you use .attr() to get the checked property, it refers to the defaultChecked state, and not the current state.

From the documentation:

Nevertheless, the most important concept to remember about the checked attribute is that it does not correspond to the checked property. The attribute actually corresponds to the defaultChecked property and should be used only to set the initial value of the checkbox.

The only other thing in there is the if statement which checks if you clicked on the checkbox itself. The default behaviour interferes with the click handler, so the simplest solution is to only check the checkbox programatically when the checkbox isn't clicked, otherwise leave it to its default behaviour.

Hope that makes sense,

Here's a fiddle

billyonecan
  • 20,090
  • 8
  • 42
  • 64
2

You need to use .prop('checked',true) instead of .attr(). check it out here : http://jsfiddle.net/techunter/VQ5E2/

Or with .attr use attr.('checked','checked') or .removeAttr('checked'). here : http://jsfiddle.net/techunter/SaRmW/

Optimized code here :

$(".markerDiv").click(function () {
    var $checks = $(this).find('input:checkbox[name=markerType]');

    $checks.prop("checked", !$checks.is(":checked"));

    alert($checks.is(":checked"));
});

http://jsfiddle.net/techunter/YymBH/

TecHunter
  • 6,091
  • 2
  • 30
  • 47
1

use prop as you been guide through out this blog. As your check-box is in div and because div is registered with click event, it may stop you using check-box. Use e.stopPropagation to make check-box itself click-able too.

$('.markerDiv').click(function () {

  if ($(this).find('input:checkbox[name=markerType]').is(":checked")) {

    $(this).find('input:checkbox[name=markerType]').attr("checked", false);
  }
  else {
      $(this).find('input:checkbox[name=markerType]').prop("checked", true);
  }

   alert($(this).find('input:checkbox[name=markerType]').is(":checked"));
});


 $('input[type=checkbox]').click(function (e) {
     e.stopPropagation();
 });
K.Z
  • 5,201
  • 25
  • 104
  • 240
0

There is a property 'for' in HTML element 'label'.

<div class="markerDiv"  id="maker_school">
    <label class="marker_label" for="markerType">School</label> 
    <input class="marker_ckeckbox" id="markerType" name="markerType" value="school" type="checkbox"  /> 
</div>

Here is an example: http://jsfiddle.net/bH3jJ/

You have to set 'id' attribute in your 'input[type="checkbox"]' element and then pass this id into property 'for' in 'label' element.

Edit:

If do you like to make in with jQuery, here is solution:

$(".markerDiv").click(function () { 
    var checkBox = $('input[name=markerType]', this);

    $(checkBox).prop('checked', !checkBox.is(':checked'));
});

with your HTML markup:

<div class="markerDiv" id="maker_school">
    <label class="marker_label">School</label>
    <input class="marker_ckeckbox" name="markerType" value="school" type="checkbox"  />
</div>

Example: http://jsfiddle.net/QgEL8/1/

Maxim Zhukov
  • 10,060
  • 5
  • 44
  • 88
  • no the label and every thing is working fine, even in alert i am getting current value of check-box onclick, is just not changing to true or false on markerDiv click – K.Z Jul 04 '13 at 08:47
  • The label is working? As in when you click on the label it toggles the checkbox? I don't think it would be working. Isn't clicking on the label what you are trying to get working? There's nothing else in the div. – Michael Geary Jul 04 '13 at 08:49
  • BTW you can nest the `` tag inside the ` – Michael Geary Jul 04 '13 at 08:50
  • Are there any arguments why do you think, that the answer is not useful? – Maxim Zhukov Jul 04 '13 at 09:01
  • -1 when you only had the ` – TecHunter Jul 04 '13 at 09:07
  • 1
    You are right, i have to use input:checkbox[name=markerType] as in question – Maxim Zhukov Jul 04 '13 at 09:11
  • for positing of each element in div purpose i am not nesting inside the label, plus id="maker_school" representing/ displaying image of size 40px by 40px. I am not interesting only label click fires event but the whole div "markerDiv". – K.Z Jul 04 '13 at 09:39
  • 1
    I did not tell you to put inside label. There are two solutions in my answer, which you could use. Even if you don't want to use pure HTML label & input, you could see how to write your JS code. Anyway, i think it's better than in your example in question, but you could think and do what you want, i just tried to give you answer. I hope you already found solution and my answer wasn't so bad. – Maxim Zhukov Jul 04 '13 at 09:46
  • @FSou1 after edits your answer is okay but I dunno if you could just keep editing picking part of answers from other people. – TecHunter Jul 04 '13 at 11:20
  • i say thanks for everyone helping me out and i have learned valuable aspects from these discussion so i have voted +1 to all answers on this blog. – K.Z Jul 04 '13 at 16:29
0

I have followed TecHunter and khurram suggestion.

1) don't mix attribute and properties by using only properties attribute but using only this will block input check-box click-able behavior so

2) so use separate function; register input[type=checkbox] with click event, then use e.stopPropagation() which will ensure running of check-box clickable itself too

$('.markerDiv').click(function () {

    var $checks = $(this).find('input:checkbox[name=markerType]');

     $checks.prop("checked", !$checks.is(":checked"));

       //process my data here

 });

$('input[type=checkbox]').click(function (e) {

    e.stopPropagation();

      //process my data here
});
FabioBranch
  • 175
  • 4
  • 19
K.Z
  • 5,201
  • 25
  • 104
  • 240