0

I am using jquery sortable to sort my photos on my web app and it's perfectly doing the job as required. However, I am not being able to fire click() or dblclick() or on('click'), basically any click event, on the elements of the sortable list items, which here are images.

HTML

<ul id="sortable" class="reorder-gallery mt-5">
  <li class="ui-state-default mediaSort" id="1" data-name="1.png">
    <img src="images/1.jpg" alt="">
  </li>
  <li class="ui-state-default mediaSort" id="2" data-name="2.png">
    <img src="images/2.jpg" alt="">
  </li>
  <li class="ui-state-default mediaSort" id="3" data-name="3.png">
    <img src="images/3.jpg" alt="">
  </li>
  <li class="ui-state-default mediaSort" id="4" data-name="4.png">
    <img src="images/4.jpg" alt="">
  </li>
</ul>

JS

// JQUERY SORTABLE
$("#sortable").sortable({
  axis: 'x,y',
  containment: "parent",
  tolerance:'pointer',
    update: function(event, ui) {
    var item_order = new Array();
    $('ul.reorder-gallery li').each(function() {
        item_order.push($(this).attr("id"));
    });
    $.ajax({
        type: "POST",
        url: "processes/sort.php",
        data: 'order='+item_order,
        cache: false,
      success: function(data){}
    });
    }
}).disableSelection();


// DOUBLE CLICK TO DELETE IMAGE (NOT WORKING)
$(".mediaSort").dblclick(function(){
  alert("Double Clicked!!");
});

The above double click function is not working. However, just to test, I tried commenting out the Sortable function above completely to void it's effect. And voila! Double clicked worked perfectly. This means that Sortable function is blocking the click events from firing up. Any solution for this?

Omar
  • 32,302
  • 9
  • 69
  • 112
Mr. Crypto
  • 39
  • 5

1 Answers1

1

It seems Touch Punch does not handle "Double Click" very well, if I am reading this correctly: https://github.com/furf/jquery-ui-touch-punch/issues/25

Consider this: jQuery on 'double click' event (dblclick for mobile)

I created the following fiddle for testing:

https://jsfiddle.net/Twisty/uhyzgaL7/

Mobile Testing:

https://jsfiddle.net/Twisty/uhyzgaL7/show/

JavaScript

$(function() {
  function myLog(string) {
    $("#log").prepend("<span>" + string + "</span>");
  }

  function doubleClick(event, callback) {
    var touchtime = $(event.target).data("touch-time");
    console.log("DC:", touchtime);
    if (touchtime == undefined || touchtime == 0) {
      // set first click
      $(event.target).data("touch-time", new Date().getTime());
    } else {
      // compare first click to this click and see if they occurred within double click threshold
      if (((new Date().getTime()) - touchtime) < 800) {
        // double click occurred
        console.log("DC Callback triggered");
        callback();
        $(event.target).data("touch-time", 0);
      } else {
        // not a double click so set as a new first click
        $(event.target).data("touch-time", new Date().getTime());
      }
    }
  }

  function removeItem(selector) {
    var item = $(selector);
    var parent = item.parent();
    item.remove();
    parent.sortable("refresh");
  }

  $("#sortable").sortable({
    axis: 'x,y',
    containment: "parent",
    tolerance: 'pointer',
    update: function(event, ui) {
      var item_order = $(this).sortable("toArray");
      myLog("Array Created: " + item_order.toString());
      $.ajax({
        type: "POST",
        url: "processes/sort.php",
        data: {
          list: "gallery",
          order: item_order
        },
        cache: false,
        success: function(data) {
          myLog("Success");
        }
      });
    }
  }).disableSelection();

  // DOUBLE CLICK TO DELETE IMAGE (NOT WORKING)
  /*
  $(".mediaSort").dblclick(function(event) {
    console.log("Double Click Detected");
    myLog("Double Click " + $(this).attr("id"));
  });
  */
  $(".mediaSort").click(function(e) {
    console.log(new Date().getMilliseconds());
    var self = $(this).get(0);
    doubleClick(e, function() {
      myLog("Remove Item: " + $(self).attr("id"));
      removeItem(self);
    });
  });
});

This does work yet not well in Mobile, testing with Chrome on Android.

I would suggest you add an Icon to each that can work as a Close / Delete button. Please see:

https://jqueryui.com/droppable/#photo-manager

Update

You can add a Handle and this addresses it much better.

Example: https://jsfiddle.net/Twisty/uhyzgaL7/68/

Mobile: https://jsfiddle.net/Twisty/uhyzgaL7/68/show/

HTML

<div class="ui-helper-clearfix">
  <ul id="sortable" class="reorder-gallery mt-5">
    <li class="ui-state-default mediaSort" id="item-1" data-name="1.png">
      <h5>Item 1</h5>
      <img src="https://dummyimage.com/100x100/cecece/2e2e2e.jpg&text=Item+1" alt="Item 1">
    </li>
    <li class="ui-state-default mediaSort" id="item-2" data-name="2.png">
      <h5>Item 2</h5>
      <img src="https://dummyimage.com/100x100/cecece/2e2e2e.jpg&text=Item+2" alt="Item 2">
    </li>
    <li class="ui-state-default mediaSort" id="item-3" data-name="3.png">
      <h5>Item 3</h5>
      <img src="https://dummyimage.com/100x100/cecece/2e2e2e.jpg&text=Item+3" alt="Item 3">
    </li>
    <li class="ui-state-default mediaSort" id="item-4" data-name="4.png">
      <h5>Item 4</h5>
      <img src="https://dummyimage.com/100x100/cecece/2e2e2e.jpg&text=Item+4" alt="Item 4">
    </li>
  </ul>
</div>
<div id="log">
</div>

JavaScript

$(function() {
  function myLog(string) {
    $("#log").prepend("<span>" + string + "</span>");
  }

  function doubleClick(event, callback) {
    var touchtime = $(event.target).data("touch-time");
    console.log("DC:", touchtime);
    if (touchtime == undefined || touchtime == 0) {
      // set first click
      $(event.target).data("touch-time", new Date().getTime());
    } else {
      // compare first click to this click and see if they occurred within double click threshold
      if (((new Date().getTime()) - touchtime) < 800) {
        // double click occurred
        console.log("DC Callback triggered");
        callback();
        $(event.target).data("touch-time", 0);
      } else {
        // not a double click so set as a new first click
        $(event.target).data("touch-time", new Date().getTime());
      }
    }
  }

  function removeItem(selector) {
    var item = $(selector);
    var parent = item.parent();
    item.remove();
    parent.sortable("refresh");
  }

  $("#sortable").sortable({
    axis: 'x,y',
    containment: "parent",
    tolerance: 'pointer',
    handle: "h5",
    update: function(event, ui) {
      var item_order = $(this).sortable("toArray");
      myLog("Array Created: " + item_order.toString());
      $.ajax({
        type: "POST",
        url: "processes/sort.php",
        data: {
          list: "gallery",
          order: item_order
        },
        cache: false,
        success: function(data) {
          myLog("Success");
        }
      });
    }
  }).disableSelection();

  // DOUBLE CLICK TO DELETE IMAGE (NOT WORKING)
  $(".mediaSort").dblclick(function(event) {
    console.log("Double Click Detected");
    myLog("Double Click " + $(this).attr("id"));
    removeItem(this);
  });
  /*
  $(".mediaSort").click(function(e) {
    console.log(new Date().getMilliseconds());
    var self = $(this).get(0);
    doubleClick(e, function() {
      myLog("Remove Item: " + $(self).attr("id"));
      removeItem(self);
    });
  });
  */
});
Twisty
  • 30,304
  • 2
  • 26
  • 45
  • @Mr.Crypto sounds like possible a Handle issue. Since no handle is definedf for the Sortable, the entire LI is the handle and that gets the Click events for Sortable. Defining a handle could help. – Twisty May 27 '21 at 18:45
  • It isn't just about double click. As I mentioned in my question, it's not working with `.click()` or `.on('click')` as well..!! :( Also I don't think Touch Punch is the issue because as I already mentioned in the question that if I comment out the sortable function and try the double click function alone it works like a charm on mobile. The problem occours when sortable is used. Looks like jquery ui's drag sort is mutually exclusive to clicks. Hence, I am trying to find a solution to allow both work together. – Mr. Crypto May 27 '21 at 18:50
  • Handle as in targeting the image inside the `li` for sorting? Tried that already. Doesn't work. – Mr. Crypto May 27 '21 at 18:51
  • Tested with added title as handle, works as expected: https://jsfiddle.net/Twisty/uhyzgaL7/66/ – Twisty May 27 '21 at 19:00
  • Tested with included DoubleClick and it works too: https://jsfiddle.net/Twisty/uhyzgaL7/68/ @Mr.Crypto – Twisty May 27 '21 at 19:04
  • In the new update double click works but sorting is now disabled...! – Mr. Crypto May 27 '21 at 19:26
  • I have a doubt.. why h5 handle and not img handle in sortable function?? – Mr. Crypto May 27 '21 at 19:35
  • @Mr.Crypto Since the Image is the primary target; it may have the same issue with DoubleClick event not being able to bubble up over drag event. You can try it if you like. I tested and both work on Chrome for Mobile. – Twisty May 27 '21 at 19:59
  • You mean both sort and double click worked together on your phone? Because I tried your fiddle and only double click worked. Sorting didn't. – Mr. Crypto May 27 '21 at 20:19
  • @Mr.Crypto yes in version 68, I can Sort and natively DoubleClick and both work properly. – Twisty May 28 '21 at 14:38
  • Didn't work when I tried your fiddle on my android using chrome... Anyways, decided a separate approach for my app. But thanks a lot for taking your time out :) Really appreciated :) – Mr. Crypto May 29 '21 at 04:51
  • @Mr.Crypto there must be other code that is interfering. If this helped, I hope you will upvote the answer. – Twisty May 31 '21 at 17:13
  • Unfortunately it didn't. Not even did your fiddle work. It only worked on double click and sorting didn't work at the same time in your fiddle. But, for all your efforts that I really appreciate, +1 for you :) – Mr. Crypto Jun 01 '21 at 02:01