Search code examples
jquery-uijquery-ui-draggablejquery-ui-droppable

JQueryUI - droppable.touch change


I am currently trying to make an extended droppable area but I got some problem. Here is the code (explanation below) :

$('div#1').find('div[cid="draggable"]').each(function(i, e) {
    $(e).after("<div id='drp' style='width:100%;'></div>");
    $('div#drp').droppable({
        drop:function(event, ui) {
            ajaxCall = false;
            ui.draggable.css("left", "0");
            ui.draggable.css("top", "0");
            $(event.target).after(ui.draggable);

            $(this).css("height", "0px");
            $(this).removeClass("isDroppable");
            $(this).removeClass("mb-1");

            var t = ui.draggable.attr("i");

            // callPage(81758758, 'POST', {t:t,s:0}, '');
        },
        over:function(event, ui) {
            $(this).css("height", (parseInt(ui.helper.css("height")) + 50)+"px");
            $(this).addClass("isDroppable");
            $(this).addClass("mb-1");

            if($(this).prev().attr("o") < ui.helper.attr("o")) {
                // Move to top : Un padding s'ajoute, étrangement.

            }
        },
        out:function(event, ui) {
            $(this).css("height", "0px");
            $(this).removeClass("isDroppable");
            $(this).removeClass("mb-1");
        },
        accept:function(d) {
            if(d.attr("cid") == "draggable" && d.attr("i") != $(this).prev().attr("i")) {
                return true;
            }
        },
        tolerance:'touch'
    });
});

So actually, I am creating, for each child of div#0, a div#drp. It means that if I have, in div#0, 5 div#card, I will have, for each div#card, a div#drp (width:100%, height:0), for a total amount of 5 div#drp. As you should have understand, each div#drp is a DROPPABLE AREA (and each div#card can be dropped on each div#drp).

But here is the problem : The only way to get this working is to set the tolerance, as it is on my code, to "touch", as long as "pointer", "intersect" & "fit" will never work because of div#drp is set to height=0px.

Now, imagine the following structure :

<div id="card" i="1" style="width:100%;height:300px;">CARDTEST</div>
<div id="grp" i="1" style="width:100%;height:0;"></div>
<div id="card" i="2" style="width:100%;height:100px;">CARDTEST</div>
<div id="grp" i="2" style="width:100%;height:0;"></div>
<div id="card" i="3" style="width:100%;height:100px;">CARDTEST</div>
<div id="grp" i="3" style="width:100%;height:0;"></div>

Here, if I move the 2nd or 3rd card, everything will be alright. But if I move the first card (with height:300px) :

First, the id#grp height will be set to "(parseInt(ui.helper.css("height")) + 50)+"px"", it means 350px.

Second, even with that, my first card will trigger the first div#drp and the second div#drp as long as it height is too big. It's like if changing the height of my div#drp doesn't extend my DROPPABLE AREA.

So, my question is : Is there a way to "actualise" the DROPPABLE AREA within the "over" event ? I tried to change the droppable event within the "over" event, I also tried to change the tolerance within the "over" event, but nothing seems to work.

Any idea ?


Solution

  • Solution :

    There isn't anything in Droppable() making this possible. However, it is possible to update DROPPABLE AREA positions within Draggable options. See below :

    $( ".selector" ).draggable({
        refreshPositions: true
    });
    

    I didn't expect a DROPPABLE property to be editable through DRAGGABLE elements. Note that, according to the documentation :

    "If set to true, all droppable positions are calculated on every mousemove. Caution: This solves issues on highly dynamic pages, but dramatically decreases performance."

    Tested on multiples devices, it doesn't cause lags or freez, so it should be fine.

    Note that this config value will also fix margins caused by any Element added on Droppable.over if the Draggable Element is under the Droppable element (In example, if you want to do the same as what Sortable() do, but with Draggable() & Droppable()).

    Problem solved !