dragula
dragula copied to clipboard
Direction as function. Solving problem #165
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.
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';
I agree. I realized about that after adding the PR. I'll fix it now with your recommendation.
Done. Thanks for your feedback!
@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.
@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 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 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.
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.
Hows the progress? :)
@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.
@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?
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.