1

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.

Dejora
  • 44
  • 6

1 Answers1

0

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.

Community
  • 1
  • 1
mr rogers
  • 3,200
  • 1
  • 19
  • 31
  • Thx for the tip, but for example if you start to click on cb1 and them you scroll (the left button still down of course) on the other input, cb1 is not checked. This is why i use onmousedown. Thanks for the getAvailableServers fonction it's help :D – Dejora Dec 18 '14 at 08:54
  • Ah yes. That is true that you miss the first one. Tricky. It seems like one of the difficulties here is that you are fighting against the default behavior of the checkbox which is already looking for a click to toggle its state. Have you considered using divs or something else that are not inherently watching the mouse? I'm not sure if that would help, but maybe... – mr rogers Dec 18 '14 at 09:01
  • Yep i found a trick put an event on the input checkbox, but it's kind of dirty. Yep my chief want to have to same behavior as Excel, so i do a lot a weird stuff on the project :( – Dejora Dec 18 '14 at 09:26