-1

I'm trying to get a 3-way checkbox to work. For this, I want to handle the click or change action myself... ie decide what the next state will be.

But I struggle at the very begin:

  • I initialize a checkbox

  • Set the indeterminate true

  • Check this runtime => indeterminate=true, checked=false

  • Got an event handler for a click with a prevenDefault()

  • The markup stays unchanged as expected => looks like an indeterminate checkbox

  • But when I check the values for indeterminate and checked they have toggled none the less

Googling for a solution I found that there are 2 ways to create an event handler

$('.chk').click(function(event){});

And

$('.chk').on('click',function(event){});

I tried both. Also tried to change instead of click. Even tried having both click and change, with one of them just having the prevenDefault().

I've got a jsfiddle set up:

https://jsfiddle.net/PeterKaagman/rpmL0gv4

$(".chk").prop("indeterminate", true);
$("#out").append("Checked "       + $('#chk_1').prop('checked') + "<br>");
$("#out").append("Indeterminate " + $('#chk_1').prop('indeterminate') );

$(".chk").click(function(event){
  event.preventDefault();
  
  $("#out").empty();
  console.log(this);
  $("#out").append("Checked "       + this.checked + "<br>");
  $("#out").append("Indeterminate " + this.indeterminate );
});

//$(".chk").on(change,function(event){
//  event.preventDefault();
//})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>3-way checkbox</p>
<input type="checkbox" class="chk" id="chk_1" >
<div id="out"></div>

Most of it is for debugging as you can see.

What I expected was that the properties checked and indeterminate would not change due to the preventDefault(). Letting me decide the next state of the checkbox.

I'm sure I doing something stupid... could someone plz point it out for me?

Peter

Taplar
  • 24,246
  • 4
  • 18
  • 33
Peter
  • 13
  • 3
  • You are trying to use a delegate event listener incorrectly. `on(event, childSelector, callback)` is the correct form. The event is always passed into the callback, not on the `on()` method – Taplar Apr 01 '19 at 16:45
  • Also given that you are binding on the element that is clicked, you don't use a delegate event listener in this case. – Taplar Apr 01 '19 at 16:47
  • 1
    Also should be seeing errors in browser dev tools console from code shown. Always mention specific errors – charlietfl Apr 01 '19 at 16:47
  • Forgot to mention: When I check "this" in the console the properties have not changed. – Peter Apr 01 '19 at 17:13
  • @Taplar: delegate event handler? – Peter Apr 01 '19 at 17:16
  • @Taplar: did try the on(event.childSelektor,callback) method like I mentioned... did not work – Peter Apr 01 '19 at 17:18
  • @charlietfl what errors do you mean? there are no errors in the console – Peter Apr 01 '19 at 17:19
  • S.O. post about delegate event listeners: https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Taplar Apr 01 '19 at 17:20
  • @Peter that comment was written before you edited the incorrect syntax – charlietfl Apr 01 '19 at 17:20
  • @charlietfl I did notice some errors.... did edit the fiddle and message... sorry bout that – Peter Apr 01 '19 at 17:31
  • @Taplar about indeterminate: https://css-tricks.com/indeterminate-checkboxes/ chrome and firefox render it just fine, will read up on delegate event handlers – Peter Apr 01 '19 at 17:34
  • @Taplar the checkbox is static... its not added dynamicly – Peter Apr 01 '19 at 17:37
  • All my statements in regards to delegate event listeners stem from your original post containing an invalid `on()` declaration. I'm not telling you to use them. – Taplar Apr 01 '19 at 17:44
  • @taplar my bad in that case... sorry – Peter Apr 01 '19 at 18:20

1 Answers1

0

.preventDefault() is preventing the "normal behavior" of the checkbox being checked or unchecked... But it seems like it does not affect the checkbox properties... Which are changed anyway. Your snippet proves that.

What I expected was that the properties checked and indeterminate would not change...

I would have too! I didn't know... And I can't explain why that is. So, in my opinion, that's a very good question! But I think I found the way to walk-around that issue...

The trick is to store the checkbox state on mousedown. That's before the properties change. On click, which is occuring right after... Restore thoses properties.

Then do what you like...

$(".chk").prop("indeterminate", true);
$("#out").append("Checked "       + $('#chk_1').prop('checked') + "<br>");
$("#out").append("Indeterminate " + $('#chk_1').prop('indeterminate') );


var checkbox_state_on_mousedown = {};
$(".chk").on("mousedown click",function(event){
  event.preventDefault();
  
  if(event.type=="mousedown"){
    // Store checkbox state before the click changes them
    checkbox_state_on_mousedown = {
      checked:this.checked,
      indeterminate:this.indeterminate
    };
    // Stop the handler's execution here
    return;
  }
  
  
  $("#out").empty();
  console.log(this);
  $("#out").append("<b>On mousedown:</b><br>");
  $("#out").append("Checked "       + checkbox_state_on_mousedown.checked + "<br>");
  $("#out").append("Indeterminate " + checkbox_state_on_mousedown.indeterminate);
  $("#out").append("<br><br>");
  
  $("#out").append("<b>On click:</b><br>");
  $("#out").append("Checked "       + this.checked + "<br>");
  $("#out").append("Indeterminate " + this.indeterminate );
  $("#out").append("<br><br>");
  
  // Restore the "before click" properties
  $(this).prop(checkbox_state_on_mousedown);
  
  $("#out").append("<b>Properties restored:</b><br>");
  $("#out").append("Checked "       + this.checked + "<br>");
  $("#out").append("Indeterminate " + this.indeterminate );
  
  // Do what you like with the restored properties from here...
  // ...
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>3-way checkbox</p>
<input type="checkbox" class="chk" id="chk_1" >
<div id="out"></div>

CodePen

Louys Patrice Bessette
  • 27,837
  • 5
  • 32
  • 57
  • I did read that a comment is not intended for a thank you. But that seems crude to me. So @Louys I say thank you [bow]. Thank you for proving me not being crazy... thank you for a nice workaround, did not come up with the mouse down solution. My little project can go on – Peter Apr 02 '19 at 18:54
  • *«I did read that a comment is not intended for a thank you. But that seems crude to me. »* -- ?? Maybe there was I comment I didn't even see and was deleted. I'm happy that you now have a solution for your project. That's what SO is for. ;) Can you [accept the answer](https://stackoverflow.com/help/someone-answers)? – Louys Patrice Bessette Apr 02 '19 at 20:25