Replies: 2 comments · 6 replies
-
|
Just had another thought: the proposed solution I've given above is specific to layers, but maybe it shouldn't be. Maybe the "navigate on successful submission" should be configured on the form rather than the layer-opening link. Something like |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
I think I've finally figured out how to make this work: up.on('up:request:loaded', (event: any) => {
if (
event.request.method === 'POST' &&
event.response.method === 'GET' &&
event.request.url !== event.response.url
) {
up.render('[up-main]', {
document: event.response.text,
layer: 'root',
});
}
}); |
Beta Was this translation helpful? Give feedback.
6 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
👋🏻
One of the reasons I am a big fan of Unpoly is that it (mostly) allows you to progressively enhance an existing server-rendered multi-page app. By just adding
up.link.config.followSelectors.push('a[href]')and configuring anup-maintarget, the app immediately starts to "feel" like a SPA.My usual approach is to not use Unpoly for form submissions: instead, just allow the browser to submit the form as normal. Because form submissions are generally less common than navigating around an application by following links, this normally works fine and doesn't interrupt the flow. We almost never use the Unpoly server protocol.
We use Django as our backend, and the pattern ingrained into every Django developer is to use post-redirect-get for successful form submissions. By default, Django doesn't do anything special with form errors in terms of HTTP status: if there's a validation error, it rerenders the form with a 200 status code. On successful submission, it 302 redirects to somewhere else.
However, sometimes you do need to submit a form through Unpoly. An example of this from the project I'm working on currently: imagine a CRUD interface with a list of widgets at
/widgets/, and a link above the list which takes you to a form to add a new widget at/widgets/add/. But instead of navigating to a different page, the form needs to appear in a modal. Validation errors in the form should keep the modal open, but a successful submission should close the modal and refresh the list view to show the newly added row.This almost, but not quite, works without any backend changes. I have added
up-submitto the<form>, and on the link I've addedup-layer="new" up-accept-location="/widgets/". When the form is submitted successfully, the backend redirects to/widgets/, and the modal closes. As per the docs, I've also addedup-on-accepted="up.reload('[up-main]')">to reload the list.However, this feels a bit janky to me. For one thing, there's a double
GETrequest: the browser (transparently) follows the 302 from a successfulPOST /widgets/add/toGET /widgets/, but the response from thatGETrequest is thrown away, and then theup-on-acceptedhandler triggers and Unpoly requestsGET /widgets/again to refresh the list.Would it instead be possible to somehow tell Unpoly that it should use the response received from a successful form submission as if it had been triggered by following a link?. So in my example above: the modal would close, and Unpoly would then replace the
up-mainon the parent layer with the first response that came back from the successful form submission?I think you could almost do this without having to make any changes to the backend at all. I believe that the XHR interface doesn't expose the information about whether a request has been redirected (although I think
fetchdoes), but I don't think that matters because you can use the URL to determine whether the submission was successful: if the URL was the same as the original URL that the form was loaded from then it must be an error response, but if the URL is different then it must be a successful submission (ie a redirect has happened). This must be possible because otherwiseup-accept-locationwouldn't work.I'm hoping that the above might be possible with a bit of custom JavaScript that I can write, but I can't quite figure it out. If not, is it worth considering adding something like the above to Unpoly itself, so it just works out of the box? Maybe
<a href="/widgets/add/" up-accept-location="/widgets/" up-use-response-on-accept>(or something less verbose!)Anyway, any thoughts gratefully received 🙂
Beta Was this translation helpful? Give feedback.
All reactions