New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable Drag for Inputs and Anchors #20

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

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye May 31, 2014

Owner

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);
});
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

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh May 31, 2014

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.

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye May 31, 2014

Owner

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'
});
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

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh Jun 1, 2014

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

jordandh commented Jun 1, 2014

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

@taye

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jun 1, 2014

Owner

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...).

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jun 1, 2014

Owner

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.

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

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh 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.

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jun 1, 2014

Owner

I've added your suggestion to the ignoreFrom test.

Owner

taye commented Jun 1, 2014

I've added your suggestion to the ignoreFrom test.

@jordandh

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh Jun 1, 2014

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

jordandh commented Jun 1, 2014

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

@taye

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jun 1, 2014

Owner

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

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

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh 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;
    });
}

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jun 1, 2014

Owner

That should be done now :D

Owner

taye commented Jun 1, 2014

That should be done now :D

@jordandh

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh Jun 1, 2014

The AMD change is working.

jordandh commented Jun 1, 2014

The AMD change is working.

@taye

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jun 1, 2014

Owner

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

Thanks for the great suggestions.

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

This comment has been minimized.

Show comment
Hide comment
@jordandh

jordandh Jun 1, 2014

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

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