dragula icon indicating copy to clipboard operation
dragula copied to clipboard

Direction as function. Solving problem #165

Open alvarotrigo opened this issue 8 years ago • 12 comments

As detailed in https://github.com/bevacqua/dragula/issues/165, it would be nice to have a way to tell dragula if we are sorting vertically or horizontally.

This provides a function that gives us the control of dynamically deciding it.

alvarotrigo avatar Mar 13 '16 19:03 alvarotrigo

I like the approach of making the direction 'pluggable'! It makes it possible to combine vertical and horizontal containers on the same page.

But: this pull request is not backwards-compatible. It assumes that the 'direction' option is always a function, which breaks when people already use direction: 'horizontal'. It would be better to check whether 'direction' is a function and only then call it as such: var horizontal = (typeof o.direction === 'function' ? o.direction(_item, dropTarget, _source) : o.direction) === 'horizontal';

mdenburger avatar Mar 16 '16 08:03 mdenburger

I agree. I realized about that after adding the PR. I'll fix it now with your recommendation.

alvarotrigo avatar Mar 17 '16 12:03 alvarotrigo

Done. Thanks for your feedback!

alvarotrigo avatar Mar 17 '16 12:03 alvarotrigo

@bevacqua is there anything I can do to help getting this pull request accepted? We really need per-container direction in our product, and it would be a pity if we'd have to fork Dragula just for that.

mdenburger avatar May 11 '16 10:05 mdenburger

@alvarotrigo You can pass options to dragula by reference, and it'll not clone them, that is you can do this:

var service = {};

service.options = {
    direction: 'horizontal',
};

service.drake = dragula(service.options);

// add containers dynamically, or via argument, doesn't really matter

your_app.on('app_specific_event', function () {
  var direction = MY_COOL_COMPUTATION;
  service.options.direction = direction;
}

andreiglingeanu avatar Jul 15 '16 08:07 andreiglingeanu

@andreiglingeanu yeap, you are right. Although that way you can't benefit from the params _item, dropTarget, _source.

Here's a demo online.

var dragSections = [
  document.querySelector('#one'),
  document.querySelector('#two'),
  document.querySelector('#three')
];

var options = {
    direction: 'vertical'
};

var hot = dragula(dragSections, options);

hot.on('drag', function(el, source){
   //your logic should go here
   options.direction = 'horizontal'
});

alvarotrigo avatar Jul 15 '16 09:07 alvarotrigo

@alvarotrigo Why not, you can always attach a handler to the drag event, which happens the dragula will try to read the direction in from options and change the direction at this phase of the widget's lifetime.

The only caveat is that you'll have only _item and source at this point, without a way to know something about the dropTarget, which, I'll agree, may be a big deal in some cases.

andreiglingeanu avatar Jul 15 '16 10:07 andreiglingeanu

The only caveat is that you'll have only _item and source at this point, without a way to know something about the dropTarget, which, I'll agree, may be a big deal in some cases.

Yep, that was my point.

alvarotrigo avatar Jul 15 '16 11:07 alvarotrigo

Hows the progress? :)

guzmo avatar Aug 02 '16 17:08 guzmo

@andreiglingeanu that's a nice insight!

It is possible to update the direction based on both the source and target container: use both the drag and over events. In the drag event the Dragula direction can be set based on the source container. In the over event the Dragula direction can be set based on the (potential) drop target. Together it results in a dynamic direction per container.

I'd say this pull request is therefore no longer needed.

mdenburger avatar Aug 10 '16 08:08 mdenburger

@alvarotrigo @andreiglingeanu

Now I have encountered such a demand. I need to dynamically get the direction from the target container to tell dragula. Is there a way to do it?

rookie125 avatar Mar 27 '20 09:03 rookie125

As mentioned above, just extract the options object in a variable and pass it by reference to dragula. Then, in your app logic update this object and dragula will use the most actual value as it doesn't clone objects but uses the old reference.

Hope that helps.

andreiglingeanu avatar Mar 27 '20 18:03 andreiglingeanu