jquery input checkbox checked weird behavior

705 Views Asked by At

i've got a weird behavior with jquery and checkboxes. In my form i build a table with some data. user can click on row or on input checkbox for select a row and add them to the selection. I build this fiddle for example So when you click on row it's ok, the row is selected and i've got my id. But when you first click on the input, so the input go checked, but when we release the button he got unchecked. After if we click again, the behavior is correct. I know i've done something wrong, but can't find out what. I need to use mousedown event for multiple selection, and allow user to select multiple id only with one click.

_isMouseDown = false;
jQuery(document).on('mousedown',function(event) {
    _isMouseDown = true;
});
jQuery(document).on('mouseup',function(event) {
    _isMouseDown = false;
});
(function($) {
var sTableId = 'lois_server_select';
var aAvailableServerClicked = new Array();
var aServerSelectedClicked = new Array();

$('.lois_server_select tr').hover(
    function () {
       if(_isMouseDown == true){
           //exec onmousedown
           $(this).trigger('mousedown');
       }
   },function (){}
);

//bug with the first click on checkbox unchecke the input 
$('.lois_server_select input').click(function(evt){
    _that = $(this);

    if(_that.closest('tr').hasClass('clicked')){
        _that.prop('checked',true);
    } else {
        _that.prop('checked',false);
    }
});

$('.lois_server_select tr').bind('mousedown',function(evt) {
    console.log('this',this);
    var _that = $(this);
    var _checkbox = $(':checkbox',_that);
    console.log('checkbox',_checkbox);
    console.log('start checked:',_checkbox.attr('checked'));
    if(_checkbox.val() == undefined) return;

    console.log('checked:',_checkbox.prop('checked'));
    if(_that.hasClass('clicked')){
        //remove class
        _that.removeClass('clicked');
        //uncheck checkbox
        _checkbox.prop('checked',false);
        //remove to aAvailableServerClicked
        if(sTableId == 'lois_server_select'){
            aAvailableServerClicked.splice($.inArray(_checkbox.val(), aAvailableServerClicked),1);
        } else {
            aServerSelectedClicked.splice($.inArray(_checkbox.val(), aServerSelectedClicked),1);
        }

    } else {
        //add selected class
        _that.addClass('clicked');
        //check checkbox

        _checkbox.prop('checked',true);

        //add to aAvailableServerClicked
        if(sTableId == 'lois_server_select'){
            aAvailableServerClicked.push(_checkbox.val());
        } else {
            aServerSelectedClicked.push(_checkbox.val());
        }
    }
    console.log('end checked:',_checkbox.attr('checked'));
    //evt.stopPropagation();
});

})(jQuery);

Thx for your help.

1

There are 1 best solutions below

3
On

After reading a few other stack posts (Detect left mouse button press, Check if mouse button is down while hovering?) it looks like the detecting buttons can be a little tricky. The following worked for me in Chrome. Based on the posts, it might (should) also work in other browsers.

$(function() {
  function detectLeftButton(event) {
    if ('buttons' in event && event.buttons) {
      return event.buttons === 1;
    } else if ('which' in event) {
      return event.which === 1;
    } else {
      return event.button === 1;
    }
  }
  $('input[type=checkbox]').hover(function(ev) { 
    console.log(ev)
    if (detectLeftButton(ev)) {
      console.log("left button is down")
      $(ev.target).trigger('click')
    }
  }, function() { });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="cb1">cb1</label><input id="cb1" name="cb1" type="checkbox"/>
<br/>
<label for="cb2">cb2</label><input id="cb2" name="cb2" type="checkbox"/>
<br/>
<label for="cb3">cb3</label><input id="cb3" name="cb3" type="checkbox"/>
<br/>
<label for="cb4">cb4</label><input id="cb4" name="cb4" type="checkbox"/>
<br/>

This might help simplify your code a bunch since you really only need the helper methods in the hover callback. You don't need to keep track of the state of the mouse since the Event has that information (under either buttons or which).

As you can see, I wrote some HTML that is similar to yours but simplified. Hopefully this will map to your use case.

I also didn't add the logic to manage which servers were selected but it seems like a helper method that was something like

function getAvailableServers(table) {
  return $(table).find(':checked')
});

could be used to grab the selected items. You might need to run that through a map function to get the values from the selection, but the helper could then be called only when you actually need the list of servers.