Inline form submissions using Fragment Plugin #761
-
|
Hi, I have added the plugin, and set it up as follows: import Swup from 'swup';
import SwupFragmentPlugin from '@swup/fragment-plugin';
const swup = new Swup({
containers: ['#main'],
plugins: [
new SwupFragmentPlugin({
rules: [
{
from: '/',
to: '/',
containers: ['#test-form'],
debug: true
}
]
})
]
});And have a form on my homepage that looks like this (simplified here for ease): <form id="test-form" action="https://mywebsite.com" method="POST">
<label for="first-name">First name</label>
<input type="text" value="" id="first-name" name="userfield_first-name_0_text_true">
<label for="second-name">Second name</label>
<input type="text" value="" id="second-name" name="userfield_second-name_1_text_true">
<label for="message">
Message
</label>
<textarea name="userfield_message_2_textarea_false" id="message"></textarea>
<label for="email-address">
Email address
</label>
<input type="email" value="" id="email-address" name="userfield_email-address_3_email_false">
<input type="hidden" name="csrf_token" value="68040e9e2311f610d421022a4129a91011285d11b9546a76d4c0f9f4e28918ba">
<input type="text" name="website" tabindex="-1" autocomplete="off">
<input type="hidden" name="uniform-honeytime" value="cgL/jlHfhErAgNnqI4N+hKODC3xdQsywdi92RpnqBQztt90YD+dhOMzDWLFxMjB7SIOhpR6WDBG/HsMxVAv8uA==">
<input type="hidden" value="432a0438-1e96-4437-b0df-731c246d6f84" name="formid">
<input type="hidden" value="" name="formtitle">
<input type="submit" value="Send it!">
</form>When I load the page I am probably missing something, if anyone has any thoughts that would be awesome |
Beta Was this translation helpful? Give feedback.
Replies: 15 comments 9 replies
-
|
Have you tried the forms plugin? That should work out of the box for normal swup navigations, i.e. it will replace the default content containers. It might work together with the fragment plugin, but I haven't yet tested them im combination. Let us know if that works or if it needs further tweaks to enable your use case. Edit: To clarify, the forms plugin is required to get form submissions to work via swup. The question is whether the fragment plugin can pick it up from there without issues. |
Beta Was this translation helpful? Give feedback.
-
|
Hi, Edit: Ah ok, I didn't realise you meant to try them together. I will give that a spin now |
Beta Was this translation helpful? Give feedback.
-
|
Hi, I am hoping this is possible, as it will be a use case consistent across all my projects. In short, I want to use swup transitions for changing pages, but a separate transition just for my form where the rest of the page is left unchanged. |
Beta Was this translation helpful? Give feedback.
-
|
@MikeHarrison As a side note: import Swup from 'swup';
import SwupFragmentPlugin from '@swup/fragment-plugin';
const swup = new Swup({
containers: ["#main"],
plugins: [
new SwupFragmentPlugin({
rules: [
{
from: "/",
to: "/",
containers: ["#test-form"],
},
],
debug: true, // global option
}),
],
}); |
Beta Was this translation helpful? Give feedback.
-
|
I think we found and fixed your issue. Or at least one possible issue: In our tests, we noticed that fragment visits to the same URL (so, basically reloads) didn't go through, preventing the form from firing a fragment visit when it is being submitted to the current URL. Could you install |
Beta Was this translation helpful? Give feedback.
-
|
We'll need to add docs about @swup/forms-plugin being required for fragment visits from forms. That's quite possibly not clear to users. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks both for your help - that recent update to the fragment plugin has done the trick. The form is successfully submitting, and only the form fragment is refreshing on the page. Excellent! I will be working on building on this tomorrow so will shout if I hit any other issues, thanks again for your support |
Beta Was this translation helpful? Give feedback.
-
|
Hi, I now would like (if possible) to extend this a bit. I am working on a site with a CMS, which means that any page could have a form, and there could be any number of forms on the page. I can control the id of the forms (e.g. I can prepend all with My only other thought was it would be great if the form reverted to its original state when the page it is on is navigated away from and then back to - currently my "thanks for getting in touch" message is still displayed in this case. This behaviour is what I would expect given how Swup works, but it would be great to switch the form back to its original state somehow. Is it possible to reset the fragment? I realise I might be pushing things too far, but have been super impressed with Swup and the support here so far so thought I would ask! |
Beta Was this translation helpful? Give feedback.
-
|
Hi, In answer to your second question first, I am outputting the result on the page after a POST request. For wider context I am using this PHP-based CMS - https://getkirby.com/, and this forms plugin to handle things like validation, email sending etc. - https://kirby-uniform.readthedocs.io/en/latest/. But yes on form submission I am reloading the same page with a success message (or any errors if that is the case). I am not really sure which of the two options in your first question would be best, Javascript isn't my strong suit so I am not sure what either would entail. In an ideal scenario (for me!) I think it would be cool for forms within Swup to work like this:
|
Beta Was this translation helpful? Give feedback.
-
|
Hi @MikeHarrison , first of all, great to hear your ideas! This will make Fragment Plugin much more robust and flexible. We'll need to think about a good solution for this. I also had the idea at some point for a function |
Beta Was this translation helpful? Give feedback.
-
|
We should definitely think about the case where there are two forms on a page that both submit to the current URL. Ideally it would be possible to tell swup to only replace the submitted form and leave the other one untouched. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks very much for your support, if I can be of any help testing anything out please shout. For now I am proceeding with just the forms plugin, and looking at trying to get as close as possible to my desired behaviour. I have got the cache clearing using this: Which checks if the page I am leaving has any forms on it, and if so prunes the cache. Now when I return to the page the form is back to its original state., which is great. What is the best way of maintaining the scroll position when a form is submitted, without using the fragment plugin? Would I use the Edit: Actually I think I have it with this: |
Beta Was this translation helpful? Give feedback.
-
|
@MikeHarrison Could you test-run the following approach, using swup's API directly:
<form id="form-1" data-swup-form method="POST">
<input name="test"></input> <input type="submit"></input>
</form>
<form id="form-2" data-swup-form method="POST">
<input name="test"></input> <input type="submit"></input>
</form>
swup.hooks.on(
"visit:start",
(visit) => {
const { el } = visit.trigger;
if (!el?.matches("form")) return;
const selector = `#${el.id}`;
visit.containers = [selector];
visit.animation.scope = "containers";
visit.animation.selector = selector;
visit.scroll.target = selector;
},
{ priority: 1 }
);
form.is-changing {
transition: opacity 300ms;
}
form.is-animating {
opacity: 0;
}If this works, we will probably add a new API attribute to the forms plugin. Maybe |
Beta Was this translation helpful? Give feedback.
-
|
That seems to be working great! This is all my swup js now: const swup = new Swup({
containers: ['#main'],
plugins: [
new SwupFormsPlugin()
]
});
swup.hooks.on(
"visit:start",
(visit) => {
const { el } = visit.trigger;
if (!el?.matches("form")) return;
const selector = `#${el.id}`;
visit.containers = [selector];
visit.animation.scope = "containers";
visit.animation.selector = selector;
visit.scroll.target = selector;
},
{ priority: 1 }
);
swup.hooks.on('animation:out:start', () => {
const formsOnPage = document.querySelectorAll('.block-type-form-builder');
if(formsOnPage.length > 1) {
swup.cache.prune((url, page) => true);
}
});I have 3 forms on the page, and they are animating in and out individually on submit, and scroll position is being maintained. When they animate back in they are showing the success / error messages, and I am getting all the form data. When I navigate away from the page and back all the forms are reset to their original state, so the cache pruning is working. Brilliant! |
Beta Was this translation helpful? Give feedback.
-
|
@MikeHarrison We just released a new version of @swup/forms-plugin that adds support for inline forms: https://github.com/swup/forms-plugin/releases/tag/3.2.0 Install it using npm install @swup/forms-plugin@3.2.0The docs also have been updated: https://swup.js.org/plugins/forms-plugin/#inline-forms Thanks so much for your input! It's great to discover what the visit object in swup4 is capable of! |
Beta Was this translation helpful? Give feedback.
@MikeHarrison We just released a new version of @swup/forms-plugin that adds support for inline forms:
https://github.com/swup/forms-plugin/releases/tag/3.2.0
Install it using
The docs also have been updated: https://swup.js.org/plugins/forms-plugin/#inline-forms
Thanks so much for your input! It's great to discover what the visit object in swup4 is capable of!