Disable Drag for Inputs and Anchors #20

Closed
jordandh opened this Issue May 30, 2014 · 15 comments

Projects

None yet

2 participants

@jordandh

Is it possible to have interact.js not allow the dragging of an element if the mousedown occurred on a child input or anchor element?

@taye
Owner
taye commented May 31, 2014

Sorry for the delay in responding. There's no setting for that yet but you can use the following until I implement something easier:

// keep a reference to the default action checker function
var defaultActionChecker = interact('target').actionChecker();

// make a custom action checker
interact('target').actionChecker(function (event) {
    // return null if the event target is an input textarea or anchor
    if (/^input$|^textarea$|^a$/i.test(event.target.nodeName)) {
        return null;
    }
    // return the action that would normally occur
    return defaultActionChecker.apply(this, arguments);
});
@jordandh

Ah, I see what that actionChecker is for now. Another issue I've run into is delegating the events. It sounds like I can use the actionChecker there as well.

I have a ul dom element and I only want to listen to its li elements being dragged around. Currently I am doing this:

interact('ul.list > li')

That is too general, I only care about the list item's in one dom element. Not all .list elements on the page. Ideally I could do something like this:

interact(element, '> li')

But it sounds like I can do this with an actionChecker:

// keep a reference to the default action checker function
var defaultActionChecker = interact('target').actionChecker();

// make a custom action checker
interact('ul.list > li').actionChecker(function (event) {
    // return null if the event target is not in this element
    if (!$.contains(element, event.target)) {
        return null;
    }
    // return the action that would normally occur
    return defaultActionChecker.apply(this, arguments);
});

Does that look like the correct way to handle delegation?

Thanks for your quick response. A 1 day delay hardly seems like a delay at all.

@taye
Owner
taye commented May 31, 2014

That looks good given the constraints of the API.

I'll try to add a context option for selectors that would work like you suggested. I have the following in mind since you can at present pass an options object as a second parameter when creating an Interactable.

interact('ul.list > li', { context: element })
// or
interact('ul.list > li').context(element);

Unfortunately '> li' is an invalid CSS selector so a match for the parent element has to be included.


As for actionChecker, I think it would be good for me to change the way it works so that it calls the new function and passes to it the event object and the default action string. That would probably be a lot more useful and your workaround could be reduced to:

interact('ul.list > li').actionChecker(function (event, action) {
    // return null if the event target is not in this element
    return (!$.contains(element, event.target)
            // or the event target is an input, textarea or anchor
            || /^input$|^textarea$|^a$/i.test(event.target.nodeName))
            ? null: action;
});

Also, to make things more convenient, an ignoreFrom option to take a CSS selector or element would be great. With this and selector context you could finally do something like:

interact('ul.list > li', {
    context: element,
    ignoreFrom: 'a, input, textarea'
});
@jordandh
jordandh commented Jun 1, 2014

That all looks great. Do you have an idea of when that might be available?

@taye
Owner
taye commented Jun 1, 2014

I will probably implement the context and improved actionChecker settings within 2 days. ignoreFrom is a bit more involved and could take a week or two (or three...).

@taye
Owner
taye commented Jun 1, 2014

ignoreFrom wasn't as difficult as I expected at all. All the changes to the API are available here:

https://raw.githubusercontent.com/taye/interact.js/better-settings/interact.js
https://raw.githubusercontent.com/taye/interact.js/better-settings/interact.min.js

Let me know if you notice any bugs or if you have some other good ideas.

@jordandh
jordandh commented Jun 1, 2014

I tested out the new actionChecker code and it worked for me. I am, however, no longer using that with the new ignoreFrom and context options.

There seems to be one problem with ignoreFrom. I have an anchor and a button with children elements. If you drag from those elements then they are not properly ignored. I think the testIgnore function needs to check if the element is within the ignoreFrom selector as well as if it matches the ignoreFrom selector.

I'll let you know how the context option is working for me once I properly test it.

@taye
Owner
taye commented Jun 1, 2014

I've added your suggestion to the ignoreFrom test.

@jordandh
jordandh commented Jun 1, 2014

That fixed it. One other feature I'd appreciate is amd support :)

@taye
Owner
taye commented Jun 1, 2014

Hmm. Would that just be a matter of returning the interact object at the end of the immediately invoked function?

@jordandh
jordandh commented Jun 1, 2014

You should be able to do it like this at the end of immediately invoked function:

if (typeof define === 'function' && define.amd) {
    define('interact', function() {
        return interact;
    });
}
@taye
Owner
taye commented Jun 1, 2014

That should be done now :D

@jordandh
jordandh commented Jun 1, 2014

The AMD change is working.

@taye
Owner
taye commented Jun 1, 2014

Fantastic. I'll merge that branch and close this issue the.

Thanks for the great suggestions.

@taye taye closed this in #21 Jun 1, 2014
@jordandh
jordandh commented Jun 1, 2014

Thanks taye. You were super responsive. Keep up the great work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment