Search code examples
jqueryfocusjquery-events

Conflict between mouseup and mousedown events?


I made a table with different cells (input elements) in it:

<?php 
    echo '<table>';
    echo '<tr>';
    echo '<td><input name="test00" value="0"></td>';
    echo '<td><input name="test01" value="1"></td>';
    echo '</tr>';
    echo '<tr>';
    echo '<td><input name="test10" value="2"></td>';
    echo '<td><input name="test11" value="3"></td>';
    echo '</tr>';
?>

And have the following jQuery code:

$('input[name^="test"]').mousedown(function(event) 
{
    //event.preventDefault();
    var field=$(this);        
    field.css({background : "#BFE7F5"});       
});

$('input[name^="test"]').on( "mouseup", function() 
{
    //var id-cellule;
    //var id-colonne;
    var field=$(this);

    field.css({background : "#AAAAAA"});
});

The problem:

When I release the mouse (mouseup event) outside of the cell, this function still is executed on the cell where the mousedown event occurred.

I want to allow the user to select several cells, so when mousedown occurs on a cell, this will be the first selected cell. Then on mouseup, the cell indicated by the mouse should be the last selected one.

I made the above example with a sample table to make it easier to understand.

I tried using preventDefault(), but then none of the inputs are editable any more.

$('input[name^="test"]').mousedown(function(event) // Pour tous les input qui changeront
                                   {
  //event.preventDefault();
  var field=$(this);        
  field.css({background : "#BFE7F5"});       
});
$('input[name^="test"]').on( "mouseup", function() // Pour tous les input qui changeront
                            {
  //var id-cellule;
  //var id-colonne;
  var field=$(this);
  field.css({background : "#AAAAAA"});

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td><input name="test00" value="0"></td>
    <td><input name="test01" value="1"></td>
  </tr>
  <tr>
    <td><input name="test10" value="2"></td>
    <td><input name="test11" value="3"></td>
  </tr>


Solution

  • The target of the mouseup event is the input element that has the focus, even if your mouse position is on another element. Even with event delegation, or by requesting $(':hover'), you will still get that input element that has the focus.

    Instead, calculate from the mouse position which is the element you are hovering over, and if it is an input element, perform the CSS modification:

    $('input[name^="test"]').mousedown(function(event) {
        $(this).css({background : "#BFE7F5"});       
    });
    $('input[name^="test"]').on( "mouseup", function(e) {
        $hoverElem = $(document.elementFromPoint(e.clientX, e.clientY))
            .filter('input[name^="test"]');
        $hoverElem.css({background : "#AAAAAA"})
                  .focus();
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <table>
      <tr>
        <td><input name="test00" value="0"></td>
        <td><input name="test01" value="1"></td>
      </tr>
      <tr>
        <td><input name="test10" value="2"></td>
        <td><input name="test11" value="3"></td>
      </tr>
    </table>