views:

162

answers:

2

In grails, I use the mechanism below in order to implement what I'd call a conditional server-side-triggered dialog: When a form is submitted, data must first be processed by a controller. Based on the outcome, there must either be a) a modal Yes/No confirmation in front of the "old" screen or b) a redirect to a new controller/view replacing the "old" screen (no confirmation required).

So here's my current approach:

  1. In the originating view, I have a <g:formRemote name="requestForm" url="[controller:'test', action:'testRequest']", update:"dummyRegion"> and a <span id="dummyRegion"> which is hidden by CSS
  2. When submitting the form, the test controller checks if a confirmation is necessary and if so, renders a template with a yui-based dialog including Yes No buttons in front of the old screen (which works fine because the dialog "comes from" the dummyRegion, not overwriting the page). When Yes is pressed, the right other controller & action is called and the old screen is replaced, if No is pressed, the dialog is cancelled and the "old" screen is shown again without the dialog. Works well until here.
  3. When submitting the form and test controller sees that NO confirmation is necessary, I would usually directly redirect to the right other controller & action. But the problem is that the corresponding view of that controller does not appear because it is rendered in the invisble dummyRegion as well. So I currently use a GSP template including a javascript redirect which I render instead. However a javascript redirect is often not allowed by the browser and I think it's not a clean solution.

So (finally ;-) my question is: How do I get a controller redirect to cause the corresponding view to "break out" of my AJAX dummyRegion, replacing the whole screen again?

Or: Do you have a better approach for what I have in mind? But please note that I cannot check on the client side whether the confirmation is necessary, there needs to be a server call! Also I'd like to avoid that the whole page has to be refreshed just for the confirmation dialog to pop up (which would also be possible without AJAX).

Thanks for any hints!

A: 

This sounds like a good use-case for using web flows. If you want to show Form A, do some kind of check, and then either move onto NextScreen or show a Dialog that later redirects to NextScreen, then you could accomplish this with a flow:

def shoppingCartFlow = {
    showFormA {
       on("submit") {
             if(needToShowDialog())return
       }.to "showNextScreen"
       on("return").to "showDialog"         
    }
    showDialog {
       on("submit").to "showNextScreen"
    }

    showNextScreen {
       redirect(controller:"nextController", action:"nextAction")
    }
}

Then you create a showDialog.gsp that pops up the dialog.

--EDIT--

But, you want an Ajax response to the first form submit, which WebFlow does not support. This tutorial, though, will teach you how to Ajaxify your web flow.

Mike Sickler
Sounds interesting! But will I be able to have the dialog in showDialog.gsp pop up in front of the "old" screen in an AJAX manner or will it refresh the whole screen?
werner5471
WebFlow doesn't support it out of the box, but you can follow the tutorial I added to enable Ajax with webflows.
Mike Sickler
I'm afraid at this point I'm stuck exactly at my original problem. If you're using the ajaxButton for the first submit, you have to provide an update region for this, and this will apply to the potential confirmation as well as the next screen, so again there's no way to "break out" of that region. Or have I missed something here?
werner5471
Ah, I think you're right. Then you could either hand-roll some Javascript as Daniel suggested, or you could update the whole page and show the dialog...
Mike Sickler
Ok, I think I will then refresh the whole page. Thank you for your help!
werner5471
+1  A: 

I know, it's not an "integrated" solution, but have you considered to do this "manually" with some JS library of your choice (my personal choice would be jQuery, but any other of the established libraries should do the trick)? This way you wouldn't depend on any update "region", but could do whatever you want (such as updating any DOM element) in the response handler of the AJAX request.

Just a thought. My personal experience is that the "built-in" AJAX/JS stuff in Grails often lacks some flexibility and I've always been better off just doing everything in plain jQuery.

Daniel Rinser
I wanted to stick with grails functionality as much as possible for simplicity reasons and because I'm not familiar with JS libraries like jQuery. But as I seem to touch the limits of grails in this respect, you might be right that I need to consider heading in this direction...
werner5471