1

I know this seems strange because there already is an update event. But I'm using the touch-punch library to make jQuery UI Functions work on touch devices. But for example on Nexus 7's Chrome browser the update event doesn't fire. That's why I try to fix it with triggering the sortupdate event from the sortover event.

The problem is, that I don't know how to get the index of the element below the dragged element. ui.item only returns the index of the dragged element. Is there any jQuery UI inbuilt function for this? Getting the index by mouseover/hover checks wouldn't work because the dragged element is bigger than the mousecursor. Getting the elements index by cursor position also seems very tricky...

Here is a fiddle: https://jsfiddle.net/8sjLw6kL/2/

Code: HTML:

<div id="sortable">
  <div class="sortable"> bla </div>
  <div class="sortable"> ble </div>
  <div class="sortable"> blu </div>
</div> 

JS:

var start_sort_index,
    over_sort_index,
    update_sort_index;

$('#sortable').sortable({
    helper: 'clone',                    
        containment: 'parent',
        cursor: 'move'
});

$('#sortable').on('sortstart', function(event, ui){
   start_sort_index = ui.item.index();
   console.log('start: '+start_sort_index);
});
$('#sortable').on('sortover', function(event, ui){
   over_sort_index = ui.item.index();
   console.log('over: '+over_sort_index);
   $('#sortable').trigger('sortupdate');
});
$('#sortable').on('sortover', function(event, ui){
    update_sort_index = (typeof ui !== 'undefined')?ui.item.index():over_sort_index;
  over_sort_index = undefined;
  //my other code here
});

CSS:

#sortable{
  width: 100%;  
    background-color: #ebebeb;  
    position: relative;
    margin-top: 10px;
  height: 60px;
 }  

.sortable{
  padding: 5px 10px;
  background-color: red;
  margin: 5px;
  float: left;
} 
MDaniyal
  • 1,097
  • 3
  • 13
  • 29
user2718671
  • 2,866
  • 9
  • 49
  • 86
  • 1
    The classic way for getting under any draggable element is to `.hide` the helper, get `.elementFromPoint` of the mouse, then `.show` the helper again. In this case however it would probably be better to figure out why the post-update-handler isn't triggered in the first place – blgt Apr 01 '16 at 11:22
  • Thanks for the tip! I wish I would know why the sortupdate event doesn't fire sometimes but I couldn't figure it out yet. The "elementFromPoint" function can't do the job that easily because the cursor is not at the position where the divs are overlapping and so it mostly selects the parent element even when set pointer-events:none and the ui-sortable to pointer-events: auto. The calculation to get to the overlapping position is a bit complicated. ... – user2718671 Apr 01 '16 at 15:27
  • ...Pointer events also not work IE and when trying to get the position there also may be differences between touch and mouse. Too complicated for a little sortable element. ;) But thanks for the tip anyway! :) – user2718671 Apr 01 '16 at 15:27

1 Answers1

1

I am not quite sure this is what you want. But at least the code is able to figure out which element you are hovering. I also tested it with touch punch on my Samsung S6 and it detects which element is hovered.

I added some code from another post on stackoverflow to detect which element is being hovered. And then I take the html from that element.

I am not sure which index you refer to, but at least this gives you the element.

JSFiddle: JSFiddle

var start_sort_index,
over_sort_index,
update_sort_index;

$('#sortable').sortable({
        containment: 'parent',
        cursor: 'move',
    start: function(event, ui) {
      var draggedItem = ui.item;
      $(window).mousemove(function(e){
        moved(e, draggedItem);
      });
    },
    stop: function(event, ui) {
      $(window).unbind("mousemove");
    },
});

//Code from http://stackoverflow.com/questions/3298712/jquery-ui-sortable-determine-which-element-is-beneath-the-element-being-dragge
function moved(e, draggedItem) {
  //Dragged item's position++
  var dpos = draggedItem.position();
  var d = {
    top: dpos.top,
    bottom:    dpos.top + draggedItem.height(),
    left: dpos.left,
    right: dpos.left + draggedItem.width()
  };

  //Find sortable elements (li's) covered by draggedItem
  var hoveredOver = $('.sortable').not(draggedItem).not($( ".ui-sortable-placeholder" )).filter(function() {
    var t = $(this);
    var pos = t.position();

    //This li's position++
    var p = {
      top: pos.top,
      bottom:    pos.top + t.height(),
      left: pos.left,
      right: pos.left + t.width()
    };

    //itc = intersect
    var itcTop         = p.top <= d.bottom;
    var itcBtm         = d.top <= p.bottom;
    var itcLeft     = p.left <= d.right;
    var itcRight     = d.left <= p.right;

    return itcTop && itcBtm && itcLeft && itcRight;
  });

  if(hoveredOver.length){
    $('.hovering-output').html(hoveredOver.html() + " is being hovered");
    console.log(hoveredOver);
  } else{
    $('.hovering-output').html("");
  }
};
Kristian Barrett
  • 3,574
  • 2
  • 26
  • 40
  • Thanks for your help! I tested my sortable div on many devices and it's a strange behaviour but sometimes the update event just doesn't fire. I tried your code and figured out that the stop function also doesn't fire. I tried some stuff but I finally give up. It would have been a dirty hack anyway :D Seem just to be a few old devices and browser's that doesn't have a big market share... – user2718671 Apr 04 '16 at 13:06
  • @user2718671 Alright. Too bad you couldn't use it, but I agree with you, that this seems like a hacky way of detecting the hover event. – Kristian Barrett Apr 04 '16 at 13:13