How would you do step forms the Remix way? #2211
-
Obviously it seems Remix is great at doing single forms. But is there a way to do divide a form into multiple steps, each with validation? Then at the last step submitting it. Obviously this is easy with any react form library, saving the state from each step and then submitting it at last step. |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 11 replies
-
I would submit every step and save state in session like we did before SPA's. |
Beta Was this translation helpful? Give feedback.
-
Also interested in this. This would make a great example. Anyone figured this out already and would want to share some example code or anyone of the 'core team' could provide an example in the https://github.com/remix-run/examples ? React final form has an example on multi step form wizard. Not sure how to implement in remix. |
Beta Was this translation helpful? Give feedback.
-
I don't feel like there is a clear answer yet. For instance, I have a form that doesn't really ever get saved on my severs, I'm doing a bunch of interactions with 3rd parties but need to still have a multi step form. |
Beta Was this translation helpful? Give feedback.
-
Hey all - I have created a really simple library that makes creating wizard forms much easier https://github.com/dan-cooke/remix-wizard
export const onboardingWizard = createWizard({
name: 'onboarding-wizard',
routes: [
'/onboarding/org',
'/onboarding/users',
'/onboaring/finish'
],
});
import { onboardingWizard } from './onboarding.server'
export const action = ({ request }) => {
const { save, nextStep, jumpToStep, prevStep } =
await onboardingWizard.register(request);
// Save arbitary data to the wizard session
save('userProfile', { name: 'John Doe' });
// Jump to a specific step
if (request.url.searchParams.get('skip')){
// You can do it by string
return jumpToStep("/onboarding/finish");
// Or by index
// return jumpToStep(3);
}
// Go to the next step
return nextStep();
}
Its nothing more than a really small wrapper around the But I always found this process very boiler-platey. So I will be using this library for all future projects |
Beta Was this translation helpful? Give feedback.
-
I found a solution that works for me and I want to pass it on. The short answer
The long answer // states
const [currentQuestion, setCurrentQuestion] = useState<number>(0);
const [showSummary, setShowSummary] = useState<boolean>(false);
const [formValues, setFormValues] = useState<{
fieldName: string;
}>({
fieldName: '',
}); For my form navigation, I would check if the current question was the last question and display the proper Next button. If it wasn't the last step, the button type was // functionality to display the next question
const handleNext = async () => {
if (currentQuestion < questions.length - 1) {
setCurrentQuestion(currentQuestion + 1);
} else {
setShowSummary(true);
}
}; For my case, I displayed the hidden input field in the summary section. That way the button type is
I hope this helps anyone who needs it. |
Beta Was this translation helpful? Give feedback.
-
I'm starting with a hard-coded routes approach for each step. We will revisit later. We're fortunate in our case the stepper matches our database design so at every step we will save data before moving the user to the next step. I'm not a fan of storing state on the client or in a session. I think there are advantages to having partial data in the db but that's just my opinion based on my use case. I think a nested route approach might be nice to try... |
Beta Was this translation helpful? Give feedback.
-
How you handle revert when any of the step fails or user navigates away without completing the final step? |
Beta Was this translation helpful? Give feedback.
I would submit every step and save state in session like we did before SPA's.