Preserving form state in widget after an Http Post

Topics: Customizing Orchard, Writing modules
Apr 11, 2013 at 1:43 AM
I have a widget which contains a form. I want to do server-side validation and display validation errors as part of the widget.

However, since my widget could appear on any URL, I don't think I can return a View() from my controller action ([HttpPost] CreatePOST). So I have to return this.RedirectLocal(returnUrl).

Doing this means my form loses all its state and the user has to re-enter everything.

How can I preserve the form state after a post?

Also, for validation... can I get the validation errors to show up in @Html.ValidationMessageFo() areas? This doesn't work if I am returning a RedirectLocal either.

I really don't want to return a redirect, but if I am just working within a widget I can't return an entire View(), as I would then lose the context of the page the widget is being rendered in.

I did look at one example in the Comments module - it preserves form state by returning the values in TempData[], and manually populating them back into the form if they exist. This is not a good solution in my opinion, and my form is way too complex to be doing that.
Apr 12, 2013 at 11:29 PM
Currently, I don't think there's a good way to handle this nicely. Perhaps we should think about adding support for postbacks within drivers like we have for the Editor methods: we have 2 versions of it: one for rendering the editor, and another one for handling postback. It would be nice to have a second version of Display as well, that handles postbacks for front-end scenarios.

But until that dream becomes true, I'm afraid your best bet is to use TempData or AJAX.
Unless you can figure out how to return the view that originally rendered the output.
Apr 12, 2013 at 11:52 PM
What if we displayed a shape from an Editor on the front end (much like with the Custom Forms module)... then could the update Editor() handle the postback?
Apr 13, 2013 at 10:37 AM
That could probably work, provided that the current page is a content item being rendered by the default ItemController. It will not work if the page is being rendered by some other controller. For example, if the page is rendered from a custom FooController, and your widget submits its form to ItemController (which invokes ContentManager.UpdateEditor), then ItemController will return a shape result. But that's not exactly what you wanted: you want to render whatever was rendered by FooController.