user1234
user1234

Reputation: 51

jQuery - Unchecked other checkbox when CHECK ALL is checked

My purpose

When I click Check All in the first column, all check boxes in that column should be checked and the Set button should show up. While the other check boxes in other column should be unchecked. Besides, when I click Check All in the second column, the Set button in the first column will be hidden and show up in the second column and then uncheck other check boxes.

HTML CODE :

<div id="allCheckboxes">
<table width="500px">
 <tr>
    <td>Check ALL <input type="checkbox" id="checkAll_1"><div id="setBttn_1" style="display:none;"><input type="button" value="Set"></div></td>
    <td>Check ALL <input type="checkbox" id="checkAll_2"><div id="setBttn_2" style="display:none;"><input type="button" value="Set"></div></td>
    <td>Check ALL <input type="checkbox" id="checkAll_3"><div id="setBttn_3" style="display:none;"><input type="button" value="Set"></div></td>
 </tr>
 <tr>
  <td><input type="checkbox" id="chkBox1" name="Box1" checked value="1" /></td>
  <td><input type="checkbox" id="chkBox2" name="Box2" value="12"/></td>
  <td><input type="checkbox" id="chkBox3" name="Box3" value="13"/></td>
  <tr>
  <td><input type="checkbox" id="chkBox10" name="Box1" checked value="001" /></td>
  <td><input type="checkbox" id="chkBox20" name="Box2" value="182"/></td>
  <td><input type="checkbox" id="chkBox30" name="Box3" value="123"/></td>
  </tr>
  <tr>
  <td><input type="checkbox" id="chkBox11" name="Box1" value="333" /></td>
  <td><input type="checkbox" id="chkBox181" name="Box2" value="184442"/></td>
  <td><input type="checkbox" id="chkBox101" name="Box3" checked value="1243"/></td>
  </tr>
 </table>
</div>

jQuery :

$('input[type="checkbox"]').on('change', function() {
  $(this).closest('tr').find('input').not(this).prop('checked', false);
});
$('#checkAll_1').change(function () {
  $('[name="Box1"]').prop('checked', $(this).prop("checked"));
  if($('#checkAll_1').is(':checked')) {
    $('#setBttn_1').show();
  } else {
    $('#setBttn_1').hide();
  }
});
$('#checkAll_2').change(function () {
  $('[name="Box2"]').prop('checked', $(this).prop("checked"));
  if($('#checkAll_2').is(':checked')) {
    $('#setBttn_2').show();
  } else {
    $('#setBttn_2').hide();
  }
});
$('#checkAll_3').change(function () {
  $('[name="Box3"]').prop('checked', $(this).prop("checked"));
  if($('#checkAll_3').is(':checked')) {
    $('#setBttn_3').show();
  } else {
    $('#setBttn_3').hide();
  }
});

The current result is when I click Check All in the first column, it won't uncheck other check boxes. When I click Check All in the second column, the Set button in the first column won't hide. Is it possible to go back to the previously checked option(s) just before the current selection if I unclick "Check All"?

LIVE DEMO : http://jsfiddle.net/WzuMa/142/

Upvotes: 3

Views: 1612

Answers (4)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

The problem is that prop does not fire change (with good reason, as that could cause recursive events by default).

You can simply trigger the change() event after setting prop, but you need to ensure it does not fire recursively (so added a sentinel variable):

var processing = false;
$('input[type="checkbox"]').on('change', function() {
  if (!processing) {
    processing = true;
    $(this).closest('tr').find('input[type="checkbox"]').not(this).prop('checked', false).trigger('change');
    processing = false;
  }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/WzuMa/143/

Update - Restore previous values on uncheck

var processing = false;
var $checkboxes = $('input[type="checkbox"]');
$checkboxes.on('change', function() {
  if (!processing) {
    processing = true;
    if (this.checked){
        // Store all answers on a data attribute
        $checkboxes.each(function(){
            $(this).data('lastcheck', $(this).prop('checked'));
        });
        $(this).closest('tr').find('input[type="checkbox"]').not(this).prop('checked', false).trigger('change');
    }
    else {
            // Restore all the previous checked box states
        $checkboxes.not(this).each(function(){
                $(this).prop('checked', $(this).data('lastcheck')).removeData('lastcheck');
        });
    }
    processing = false;
  }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/WzuMa/144/

You can tweak this technique to operate on rows instead, for the lower checkboxes but I have to leave something for you to do :)

Upvotes: 1

Yogesh Sharma
Yogesh Sharma

Reputation: 2017

Try below JS for now things are hard-coded but if this solution is as expected as you then I can update it to more dynamics

  

 $('input[type="checkbox"]').on('change', function() {
		$(this).closest('tr').find('input').not(this).prop('checked', false);
  
	});
	
	$('#checkAll_1').change(function () {
 		$('[name="Box1"]').prop('checked', $(this).prop("checked"));
    $('[name="Box2"],[name="Box3"]').prop('checked', false);
 if($('#checkAll_1').is(':checked')){
			$('#setBttn_1').show();
     $('#setBttn_2,#setBttn_3').hide();
  	}else{
			$('#setBttn_1').hide();
		}
    
	});
	
	$('#checkAll_2').change(function () {
		$('[name="Box2"]').prop('checked', $(this).prop("checked"));
      $('[name="Box1"],[name="Box3"]').prop('checked', false);
  	if($('#checkAll_2').is(':checked')){
			$('#setBttn_2').show();
      $('#setBttn_1,#setBttn_3').hide();
  	}else{
			$('#setBttn_2').hide();
		}
	});
	
	$('#checkAll_3').change(function () {
		$('[name="Box3"]').prop('checked', $(this).prop("checked"));
      $('[name="Box1"],[name="Box2"]').prop('checked', false);
  	if($('#checkAll_3').is(':checked')){
			$('#setBttn_3').show();
      $('#setBttn_1,#setBttn_2').hide();
  	}else{
			$('#setBttn_3').hide();
		}
	});

Upvotes: 1

Jai
Jai

Reputation: 74738

You can use this:

$('#allCheckboxes').find('tr').first().find(':checkbox').on('change', function(e) {
  var $this = $(this),
    idx = $this.closest('td').index();
  $('div[id^="setBttn"]').hide();
  $this.next('div').toggle(this.checked);
  $('[id^="checkAll"]:checked').not(this).prop('checked', !this.checked);
  $('#allCheckboxes').find('tr').not(':first').each(function() {
    $(this).find(':checkbox:checked').prop('checked', !$this.prop('checked'));
    $(this).find('td').eq(idx).find(':checkbox').prop('checked', $this.prop('checked'));
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="allCheckboxes">
  <table width="500px">
    <tr>
      <td>Check ALL
        <input type="checkbox" id="checkAll_1">
        <div id="setBttn_1" style="display:none;">
          <input type="button" value="Set">
        </div>
      </td>
      <td>Check ALL
        <input type="checkbox" id="checkAll_2">
        <div id="setBttn_2" style="display:none;">
          <input type="button" value="Set">
        </div>
      </td>
      <td>Check ALL
        <input type="checkbox" id="checkAll_3">
        <div id="setBttn_3" style="display:none;">
          <input type="button" value="Set">
        </div>
      </td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" id="chkBox1" name="Box1" checked value="1" />
      </td>
      <td>
        <input type="checkbox" id="chkBox2" name="Box2" value="12" />
      </td>
      <td>
        <input type="checkbox" id="chkBox3" name="Box3" value="13" />
      </td>
      <tr>
        <td>
          <input type="checkbox" id="chkBox10" name="Box1" checked value="001" />
        </td>
        <td>
          <input type="checkbox" id="chkBox20" name="Box2" value="182" />
        </td>
        <td>
          <input type="checkbox" id="chkBox30" name="Box3" value="123" />
        </td>
      </tr>
      <tr>
        <td>
          <input type="checkbox" id="chkBox11" name="Box1" value="333" />
        </td>
        <td>
          <input type="checkbox" id="chkBox181" name="Box2" value="184442" />
        </td>
        <td>
          <input type="checkbox" id="chkBox101" name="Box3" checked value="1243" />
        </td>
      </tr>
  </table>
</div>

Upvotes: 1

Satpal
Satpal

Reputation: 133403

You you are programmatically setting the checked property it doesn't triggers the change event handler.

To trigger the event handler, .trigger(event) function should be used.

$('input[type="checkbox"]').on('change', function() {
  $(this).closest('tr').find('input').not(this).prop('checked', false);
});

$('#checkAll_1').change(function() {
  $('[name="Box1"]').prop('checked', $(this).prop("checked")).trigger('change');
  if ($('#checkAll_1').is(':checked')) {
    $('#setBttn_1').show();
  } else {
    $('#setBttn_1').hide();
  }
});

$('#checkAll_2').change(function() {
  $('[name="Box2"]').prop('checked', $(this).prop("checked")).trigger('change');
  if ($('#checkAll_2').is(':checked')) {
    $('#setBttn_2').show();
  } else {
    $('#setBttn_2').hide();
  }
});

$('#checkAll_3').change(function() {
  $('[name="Box3"]').prop('checked', $(this).prop("checked")).trigger('change');
  if ($('#checkAll_3').is(':checked')) {
    $('#setBttn_3').show();
  } else {
    $('#setBttn_3').hide();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="allCheckboxes">
  <table width="500px">
    <tr>
      <td>Check ALL
        <input type="checkbox" id="checkAll_1">
        <div id="setBttn_1" style="display:none;">
          <input type="button" value="Set">
        </div>
      </td>
      <td>Check ALL
        <input type="checkbox" id="checkAll_2">
        <div id="setBttn_2" style="display:none;">
          <input type="button" value="Set">
        </div>
      </td>
      <td>Check ALL
        <input type="checkbox" id="checkAll_3">
        <div id="setBttn_3" style="display:none;">
          <input type="button" value="Set">
        </div>
      </td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" id="chkBox1" name="Box1" checked value="1" />
      </td>
      <td>
        <input type="checkbox" id="chkBox2" name="Box2" value="12" />
      </td>
      <td>
        <input type="checkbox" id="chkBox3" name="Box3" value="13" />
      </td>
      <tr>
        <td>
          <input type="checkbox" id="chkBox10" name="Box1" checked value="001" />
        </td>
        <td>
          <input type="checkbox" id="chkBox20" name="Box2" value="182" />
        </td>
        <td>
          <input type="checkbox" id="chkBox30" name="Box3" value="123" />
        </td>
      </tr>
      <tr>
        <td>
          <input type="checkbox" id="chkBox11" name="Box1" value="333" />
        </td>
        <td>
          <input type="checkbox" id="chkBox181" name="Box2" value="184442" />
        </td>
        <td>
          <input type="checkbox" id="chkBox101" name="Box3" checked value="1243" />
        </td>
      </tr>
  </table>
</div>

Upvotes: 1

Related Questions