How do I avoid a click event firing after dragging a gridster.js widget with clickable content?

StackOverflow https://stackoverflow.com/questions/14301026

  •  15-01-2022
  •  | 
  •  

Question

I'm using Gridster (http://gridster.net/) which able to drag the content inside the li . In my li there is a clickable div.

<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
    <a href=' '>
    <div>
       content
    </div>
    </a>
</li>

so here is the problem I'm facing, when I stop and release the dragging, it will invoke the click in the div, how can I just dragging the div, but not invoking the click after drag stop&release. I do not want it to redirect to another page after dragging( user drag and release ..since when drag,it need to click the div,meanwhile, the div can be clicked, so when stop&release the drag, it will invoke the click )

$(function(){ //DOM Ready

    var gridster = $(".gridster ul").gridster(
    {
          widget_margins: [5, 5],
        widget_base_dimensions: [128, 130],
        max_size_y: 2,
        max_size_x: 2,
        extra_cols: 6
    }
    ).data('gridster');
    //which i tried but failed
    gridster.draggable.stop(){
        onclick = "false";
    }


//   gridster.resize_widget($('.gridster li').eq(0), 1,1);

});

or anyone can give hints about how to invoke or use the function that provided by gridster

draggable.stop: function(event, ui){} A callback for when dragging stops.

I guess there will be some implementation on here.

initial solution but still not working yet

    var gridster ,draggable ;
   $(function () {
        gridster = $(".gridster > ul").find("> li ").click(function(e){
            !draggable && alert(1) //ipad2 ,not show alert
            draggable=0;
            alert(draggable);
            }).end()
            .gridster({widget_margins: [5, 5],
            widget_base_dimensions: [128, 130],min_cols: 10,min_rows: 20
            ,serialize_params: function($w, wgd) {
                return {
                    id: wgd.el[0].id
                    //,col: wgd.col
                    //,row: wgd.row
                };
            }
            ,draggable: {
                start:function(event, ui){ 
                //  alert("hekio);");
                    draggable=1; }
            }
        }).data('gridster');
    //gridster.disable();
//   gridster.resize_widget($('.gridster li').eq(0), 1,1);
         if(!dragged){
            $("a#blue.grid").click(function(){
            window.location = '../yokotachi/category_list.php?category=yokosmart';
        });
            }
    // RESET DRAGGED SINCE CLICK EVENT IS FIRED AFTER drag stop
            dragged = 0
    });
Was it helpful?

Solution 2

I fixed it with a trigger variable: var dragged = 0 Add the following to your gridster initialization which sets the variable to 1 on drag start:

...
    draggable: {
        start: function(event, ui) {

            dragged = 1;
            // DO SEOMETHING
        }
    }
....

In your click event on the same object, check:

...
    if(!dragged){
        // DO SOMETHING
    }
    // RESET DRAGGED SINCE CLICK EVENT IS FIRED AFTER drag stop
dragged = 0
....

OTHER TIPS

The problem is that the click event is fired after the mouseup event that is passed to draggable.stop.

You therefore need to briefly trap that click event and stop it propagating, then untrap it once you've finished so people can subsequently click on the item.

You can do this like so (click for working JSFiddle):

$(document).ready(function () {
  // Basic event handler to prevent event propagation and clicks
  var preventClick = function (e) { e.stopPropagation(); e.preventDefault(); };
  $(element).gridster({
    draggable: {
      start: function (event, ui) {
        // Stop event from propagating down the tree on the capture phase
        ui.$player[0].addEventListener('click', preventClick, true);
      },
      stop: function (event, ui) {
        var player = ui.$player;
        setTimeout(function () {
          player[0].removeEventListener('click', preventClick, true);
        });
      }
    }
  });
})

This is a much better solution than the currently accepted answer, because it avoids having a variable with state being set/checked across multiple components/handlers.

you should try that :

var gridster = $(".gridster ul").gridster().data('gridster');
gridster.disable();

Without digging into the JS, adding onclick = "return false;" to your <a> tag should stop the click from triggering.

For stopping just the drag, try:

gridster.draggable.stop(){
   return false;
}

or

gridster.draggable.stop(e){
   e.preventDefault();
}

There now is a native support to disable the drag and drop operation on Gridster.

$(".gridster ul").gridster().data('gridster').disable();

For those that came across this thread looking for a solution in Gridster2 using Angular, the following is based on Alastair Maw's answer but updated to work for Gridster2 by using the initCallBack option.

ngOnInit() {
    const preventClick = (e) => { e.stopPropagation(); e.preventDefault(); };
    this.gridsterOptions = {
      initCallback: (gridster: GridsterComponentInterface) => {
        gridster.options = {
          draggable: {
            delayStart: 100,
            start: (event, ui) => {
              // Stop event from propagating down the tree on the capture phase
              setTimeout(() => {
                ui.el.addEventListener('click', preventClick, true);
              }, 100);
            },
            stop: (event, ui) => {
              setTimeout(() => {
                ui.el.removeEventListener('click', preventClick, true);
              });
            }
          }
        }
      }
    };
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top