Asynchronous call to confirm (actual and tests passed ok)#196
Asynchronous call to confirm (actual and tests passed ok)#196akzhan wants to merge 7 commits intorails:masterfrom
Conversation
|
Take a note that tests were ran and passed on these browsers:
Another note: call-remote: allow empty form "action" have been marked as failed but is OK actually ('?' character added to URL), if tests runned using URL without ?. Fixed by #197. |
|
Woo that's a lot of changes :-) On first glance though, this looks pretty good. I'll have to run the tests also through IE when I get a chance. Any chance I can get you to squash these commits down into one? |
|
Ok, will renew as separated pull requiest with one commit. |
|
No, don't do that. Just do a |
|
Wow! I did it. @JangoSteve, thanks for your advice, I learned new git magic 🆒 |
|
Just ran test suite under:
|
|
Yes, that sounds about right. The cross-domain stuff doesn't work well in IE, not much we can do about it. It's basically just there for those who wanna use it for whatever it's worth. |
…de confirm in an asynchronic fashion.
|
Pull request slightly updated to be more accurate. |
|
I was going through this code a little more thoroughly and there is one major problem which is preventing me from pulling this in at the moment. Unfortunately, I'm not sure off-hand what a good solution would be. The problem is with this, this, and this. I see what is happening is that we are manually stopping all link clicks and form submissions to which we're bound, and then manually re-triggering the events for the elements that should not have been stopped in the first place (being sure to skip our own event handlers the second time around). I understand that this is necessary in order to invoke and "wait" for the asynchronous confirm deferred object. However, this is pretty obtrusive and could break people's applications. Because all of our functionality is bound to the With the code in this pull request, jquery-ujs would cause the following to happen:
We can easily skip our own event handlers the second time the event is triggered (manually by us). But to require everyone else to do the same in all of their own scripts is too obtrusive. Like I said before, I'm really not sure what a good solution is. This is precisely the difficulty with using an asynchronous function for functionality that is supposed to be synchronous; this is why this still hasn't been implemented despite multiple requests for it (like this and this). One possible solution could be to cache the event object (with the clicked/submitted element in the target attribute, but propagated up to the If you have any other ideas, please let me know (it's entirely possible I'm missing something obvious here). This is certainly the most thorough and promising attempt at this so far, and the code looks really good otherwise. I'll leave the pull request open for now. |
|
You are absolutely right. So we can add something like "data-async-behavior" attribute and realize asynchronous behaviour as an option. A lot of applications does nothing except UJS and require custom confirmation dialogs. |
|
confirm and allowAction can stay Promise'd. We need to add both sync/async variations to event handlers only. Is it good trade-off? |
|
Hm. I thinking hard and prefer to maintain both sync. and async. versions of rails.js as separate scripts. This is less painful. |
|
How would you suggest having them as separate scripts? I.e. how would you structure or maintain such a thing? |
profit. |
|
@JangoSteve, any comments? |
|
I like the idea of having this functionality in some way available for people who need it. However, I don't think putting this code in a separate file that has to be separately maintained and updated is the way to go. I think a better approach may be to keep the synchronous |
|
Ok, will do until 9 oct. We need this functionality in errbit. |
|
So, a couple things.
As described above, we're unilaterally stopping the click event for all links to which we're bound (those being However, firing the Therefore, re-triggering the click event via JS on a link does not actually cause the browser window to follow the link. This can be illustrated with this: Run that on any page and click any link. Notice that in the console, the click event properly gets triggered twice. However, the browser window will never follow the link.
|
|
I was able to get rid of re-triggering of link clicks and form submits for non-remote links and forms. Links: Instead of re-triggering the link click for non-remote links (which doesn't work anyway since JS won't allow the window to follow the link when the click event is triggered via JS), I re-used the I think this will be fine, because all of the click bindings have already been triggered and executed by this point, and we don't have to worry about any ajax callbacks, because this is only happening for non-remote links with Forms: Instead of re-triggering the form's This can be illustrated with the following: I'm now working through the test suite to see if any side-effects arise from this approach, but I wanted to at least document my progress so far. |
…riggering of directly bound handlers outside of jquery-ujs. See rails#196.
|
OK, so I think I have something working. However, it takes a somewhat creative approach to solving the issues outlined above, so I want to get people's feedback in the form of a sanity check before pulling this into master. |
|
We need additional tests to cover edge cases described by your comment above. |
|
I just created two test cases for making sure direct bindings are only triggered once in the scenarios described above, one for links and one for forms. |
|
Looks like OK. I vote for. |
|
Any chance to see it landed?) |
|
@nfm, thanks for your update. @lest catched that error yesterday: http://screencast.com/t/XrBcu9u8Ak just sent PRq to errbit (errbit/errbit#126). And it's landed. |
|
Pull request updated by @JangoSteve and @nfm commits. |
|
So, you guys have been using this branch with some success then? |
|
@JangoSteve Yes, it works good. |
|
@nfm, can you take the typo commit out of this branch and put it in a separate pull request, I want to go ahead and pull that in with the next release. |
|
@nfm, oops nevermind, I'm dumb. I thought that was a typo in the master branch of jquery-ujs, forgot that that line was added only in this branch. |
|
@JangoSteve all good. I've been using this branch too, working without issue for me. |
|
@JangoSteve, one issue was found by users and fixed by @nfm. No more issues. Now it is used in Errbit application. |
|
@JangoSteve, I think that we can rebase this pull request to meet current master and merge into. Am I right? |
|
Bump :) |
|
I've also been using this in production for the last ~3 weeks without issue. |
|
Great to see the progress made on this! Looking forward to it being integrated into master. I'd like to use the async version on the branch: https://github.com/JangoSteve/jquery-ujs/tree/async-confirm Would it be possible to update the branch with the latest code on master so I can test with an "official" version rather than a hand-merged version? |
|
Any chance if this making it into master sometime soon? Currently we're using a horrible, horrible hack to get an async confirmation dialog to work and I'm be quite keen to get rid of it. |
|
@k33l0r Please use the branch mentioned in this thread. I don't don't yet have plans to merge this in the near future due to the lack of people using it, and the fact that it's a large rewrite that depends on some low-level undocumented stuff in jquery. The only thing that would really make it better, would be to have a lot of people using it in production with not problems for a while. |
|
Does anyone have a recent rebase of this branch onto master in their own fork? |
|
Sorry, I'll update my branch shortly and push it up. |
|
Sorry for the delay, that was much more involved than expected. The async-confirm branch of jangosteve/jquery-ujs has now been updated to be on-par with the latest master. |
|
@JangoSteve any update on this issue ? |
|
@neerajdotname Yes, if a lot of people start using the fork (which I'll continue to maintain), then there's a chance I'll merge this in. Until then, I'd like to keep this open. |
|
On second thought, the code for this has come a long way since this pull request was created. I'm going to close this pull request and add a page to the wiki for the async-confirm branch. Everything else I said above stands. |
|
@JangoSteve ping! Any update here? |
|
Hi guys, i know this issue is closed, but i have a few questions about the code. First off, this new asynchronous way of handling confirmation messages is pretty nice. I see how you have easily used the $.Deferred() to handle the confirm callbacks and stuff, which fits in nicely with the whole tri-state Promise paradigm. Today i set out to write my own $.rails.confirm method so i can use the handy-dandy bootstrap modal plugin to confirm if users are sure about the action they were going to perform. It fits better on mobile screens, popup blockers don't hide the box, all that good stuff. Okay. So, after writing it, adding in my own $.Deferred() stack for handling the clicks on the okay/cancel buttons, i realized there was something missing. The actual bits of the asynchronous stack were not being called to actually do the click when i resolve()d the promise. I discovered that if instead of passing the direct message to My question is two part:
Thanks again. I definitely get how this is a difficult problem to solve. In my specific situation, however, i intend to banish the usage of window.confirm in my application, so async is for the win! |
|
Finally found the 'correct' place to this specific question, but I'm still confused how to implement myself. It is possible that there is a built in option (e.g. merge this pull request)? |
|
Im also looking forward for this feature in the future! Any chance that someone implements it again? :) |
Although it is possible to override the default confirm method, it doesn't make much sense, because the built-in window.confirm blocks the execution of code and waits for the user input. If we want to replace the default confirm with something else, for example jquery ui dialog or apprise, it would not work, because the modal box method returns immediately, and the result is returned via callback. And there is no way as far as I know to block the execution of script until the user chooses for "yes" or "no". I've made a proof-of-concept for asynchronous confirm, which uses Deferrable (jQuery 1.5 or above).
All tests passed. Based on proof-of-concept - #178.