verbb / formie

The most user-friendly forms plugin for Craft CMS.
Other
94 stars 72 forks source link

In a multi-pages form, I can't go back to the previous page if required fields of the current page are not filled #866

Closed romainpoirier closed 2 years ago

romainpoirier commented 2 years ago

Description In a multi-pages form, I can't go back to the previous page if required fields of the current page are not filled.

Steps to reproduce

  1. Setup a multi-pages form
  2. Add some required fields on each page
  3. Use {{ craft.formie.renderForm() }} in template
  4. Fill in the first pages
  5. Leave current page's fields blank
  6. Try to go back to the previous page
  7. Get the required field error

Form settings

Additional info

engram-design commented 2 years ago

Are you able to inspect the payload after submitting? In order to go to the previous page, there needs to be a goingBack param (even if it equals null), which disables validation.

For instance, mine looks like: image

romainpoirier commented 2 years ago

Hi Josh, Multi-pages form page 1 is filled; On page 2, try to go Back: I can; Then go to page 2 again, and close the form; Go back to the form, redirect to page 2; Try to go Back again: got the required fields error on page 2; I can see the goingBack to true in the Payload (of page 2).

Romain

Le 6 mai 2022 à 07:21, Josh Crawford @.***> a écrit :

Are you able to inspect the payload after submitting? In order to go to the previous page, there needs to be a goingBack param (even if it equals null), which disables validation.

For instance, mine looks like: https://user-images.githubusercontent.com/1221575/167071857-3b63c7f7-d5a1-4101-a8eb-42fd62a9719c.png — Reply to this email directly, view it on GitHub https://github.com/verbb/formie/issues/866#issuecomment-1119269542, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABDLMUDKJLX2VFO6CXUIAGDVIST7NANCNFSM5VCEECKQ. You are receiving this because you authored the thread.

engram-design commented 2 years ago

Closing the form and coming back shouldn't do anything, as you'll be taken back to where you left off in your session. I assume that's also what you mean by Go back to the form, redirect to page 2; and not you're redirecting users to the second page?

If you can send through your exact payload going back, hopefully that'll help me recreate it, as it seems to be working all okay on my end despite restarting and picking up the submission.

romainpoirier commented 2 years ago

Yes I'm not redirecting users to the page 2. I mean, leave the form's page, then go back to the form's page.

Sorry I'm not sure what you're expecting: the export JSON file of the form settings (got from /admin/formie/settings/import-export) and/or the database and/or the form template (which mostly uses the default renderForm())?

This is a complex multi-pages form with a lot of fields, so a bit hard to find a logic under what is filled.

engram-design commented 2 years ago

What I meant was the network request payload when you try to submit the form after coming back to it - which is similar to the screenshot I sent through (taken from Chrome developer tools). I'm wanting to see what data is being sent to the server so I can try and replicate what might be going on. Even if you form is a page reload form, on the destination page, the very first request will be the page that was requested and you can inspect that. It sounds like something is trying to submit the page, instead of navigating backwards, which is controller by some params in the request.

romainpoirier commented 2 years ago

This is one example of payload I get with a page Back stuck in its step:

CRAFT_CSRF_TOKEN: dBKXX4mgr9iQOm9JfIiMFGh6QzGRfcvC-6O3BtGvDHeMysK7UCyQTbzHfbSrwyPy2pKeyK7Y_3siPLVF3MKd_dXGzHpRkWXrjrcB2tTuQjPe6Pr6Tb3dt1R9S08FIuTzYT4GTIdBmt0zXSfZAAbPRQeXvQ9MBZvxLlVoBpaESPgzx7bMynPiI66NQKk2CCk2thOYHkGvHrzT9rD2UCw_O73eVRE4emDQDL-rnu_bWZDMQxS-pY_kG2fVCMD2Sdab9BeR4vT_-8-7nElHCYNx6Pf_xLfz-Ek0oVbT64E2uObaIVC8icLJdIXvgmRNeSxmQ9WVUVsxLeYlo-sKN3ThQTO8HG_x10w6Qq6jbywqP8fFOYxaovqglTKBbM2_L-RpQ2Jz82-p
action: formie/submissions/save-submission
handle: myForm
siteId: 1
submissionId: 139079
fields[firstName]: John
fields[lastName]: Doe
fields[email]: john@doe.com
fields[internationalTitle]: Molestias et mollit 
fields[titleInOriginalLanguage]: Sequi eiusmod in sin
fields[format]: TV special
fields[minutes]: 28
fields[seconds]: 19
fields[animationTechniques]: 
fields[animationTechniques][]: 2D computer
fields[animationTechniques][]: 3D computer
fields[animationTechniques][]: Clay
fields[animationTechniques][]: Cut-out
fields[otherAnimationTechniques]: Ea consectetur debi
fields[transmedia]: Yes
fields[medias]: 
fields[targetAudience]: Upper Preschool 5-6
fields[customTargetAudience]: Laudantium aliquam 
fields[finishedSynopsis]: 
fields[finishedSynopsis]: 1
fields[numberOfEpisodeFinishedSynopsis]: 
fields[finishedFinalScripts]: 
fields[finishedStoryboards]: 
fields[finishedStoryboards]: 1
fields[numberOfEpisodesFinishedStoryboards]: 
fields[scriptInformation]: Adaptation from an original script
fields[originalWorksTitle]: Ut consequatur Adip
fields[startDate][datetime]: 2022-06-16 00:00:00
fields[endDate][datetime]: 2022-08-24 00:00:00
fields[membersOfCreativeTeam]: 
fields[checklist]: 
fields[nameMainProductionCompany]: Yates and Dale Trading
fields[addressMainProductionCompany]: Waters and Ruiz LLC
fields[postCodeMainProductionCompany]: Butler Oconnor Traders
fields[cityMainProductionCompany]: Crawford Sweeney Plc
fields[countryMainProductionCompany]: French Southern Territories
fields[generalPhoneNumberMainProductionCompany][number]: 484 71 31 89
fields[generalPhoneNumberMainProductionCompany][country]: BE
fields[emailMainProductionCompany]: dodejup@rgagegc.com
fields[websiteMainProductionCompany]: Lyons and Le LLC
fields[relevantFilmographyMainProductionCompany]: Sit cupiditate optio
fields[titleMainProducersDetails]: Ms.
fields[firstNameMainProducersDetails]: Buffy
fields[lastNameMainProducersDetails]: Spence
fields[emailMainProducersDetails]: fydakulet@azggth.com
fields[phoneNumberMainProducersDetails][number]: 484 76 44 58
fields[phoneNumberMainProducersDetails][country]: BE
fields[mobileMainProducersDetails][number]: (393) 887-8628
fields[mobileMainProducersDetails][country]: US
fields[coProducers]: 
fields[titlePersons]: Ms.
fields[firstNamePersons]: Ishmael
fields[lastNamePersons]: Ortdaega
fields[companyPersons]: Foster and Cameron Inc
fields[emailPersons]: wyzuc@hkksdaa.com
fields[phoneNumberPersons][number]: 484 87 77 81
fields[phoneNumberPersons][country]: BE
fields[synopsisInput]: Eveniet lorem magna
fields[mainTopicOfTheProjectInput][]: Disability
fields[mainTopicOfTheProjectInput][]: Drama
fields[mainTopicOfTheProjectInput][]: Fantasy
fields[mainTopicOfTheProjectInput][]: Female character
fields[mainTopicOfTheProjectInput][]: Folklore
fields[mainTopicOfTheProjectInput][]: Gender
fields[mainTopicOfTheProjectInput][]: Historical
fields[mainTopicOfTheProjectInput][]: Inclusion
fields[mainTopicOfTheProjectInput][]: Musical
fields[mainTopicOfTheProjectInput][]: Sci-Fi
fields[mainTopicOfTheProjectInput][]: Sustainability
fields[mainTopicOfTheProjectInput][]: Well-being
fields[mainTopicOfTheProjectOther]: Anim praesentium ver
fields[projectFileInput][]: (binary)
fields[letterOfInterestNameOfTheCompanyShowingInterest]: Noble Watson Traders
fields[letterOfInterestFirstNameOfTheContact]: Hamilton
fields[letterOfInterestLastNameOfTheContact]: Stephenson
fields[letterOfInterestEmailAddressOfTheContact]: qywaquhij@zdaah.com
fields[fileUpload][]: (binary)
fields[squareStill][]: (binary)
fields[verticalStill][]: (binary)
fields[horizontalStill][]: (binary)
fields[urlVideo]: Fugit nisi dolor qu
fields[passwordVideo]: Ut eaque omnis dolor
fields[estimatedTotalBudget]: 20
fields[productionStartDate][datetime]: 2022-12-08 00:00:00
fields[filmOtherCrossmediaApplicationsReleaseDate][datetime]: 2022-05-11 00:00:00
fields[projectReceivedSupportFromCreativeEurope]: Yes
fields[projectReceivedSupportFromNationalFilmFund]: Yes
fields[nameOfTheFundNationalFilmFund]: 
fields[projectReceivedSupportRegionalFilmFund]: Yes
fields[nameOfTheFundRegionalFilmFund]: 
fields[readAndAgree]: 
fields[authorisation]: 
fields[submitted]: 
goingBack: true
engram-design commented 2 years ago

Hmmm, so seeing as though you're submitting to formie/submissions/save-submission means that you're editing a completed submission. Otherwise, if you're still editing an incomplete submission, that'd be to formie/submissions/submit.

So for the moment, that's expected behaviour, simply due to the nature of editing a submission. When you're editing an incomplete submission, it's essentially like a draft. But editing a completed submission, even going back to a previous page without filling in required fields is risky, because the user could just quit editing the submission after saving a required field without any content - if that makes sense?

I'll give it some further thought.

romainpoirier commented 2 years ago

Ok, I understand. The problem is that I have this unexpected behavior on submissions that are still Incomplete. Tn that case, the user should be able to go to the previous page to check its data, and edit them if necessary.

Related to #871, I thought it could be caused by my Submissions::EVENT_AFTER_INCOMPLETE_SUBMISSION or Submission::EVENT_AFTER_SAVE or Submissions::EVENT_AFTER_SUBMISSION events. But even after commenting everything, I still can't go back.

engram-design commented 2 years ago

When you're trying to go back on an incomplete submission, can you post the above request params like you did previously? I can't replicate that behaviour when going back on an incomplete submission, and it should never try and validate an incomplete submission going back to a previous page. So I'm wondering if maybe there's something not quite right with the data being send for the submission.

romainpoirier commented 2 years ago

I have this issue when trying to go back on every page, so I don't think it's related to a specific page. Please find below an example of payload I get (here, at the last page of my form).

CRAFT_CSRF_TOKEN: oG97pPJ4SF_EfHwwVzfm36s-vp0s0RD02iuQMcI_cyBTd458WnMgiqYSCbXat-BHiS9UcoAEa5SA5VLWblJgX_917LJpJ3yRggGWYLPxGyYXlF55n4IS2_E_zoSF8Xws5obFD3Dy-je-yvKRjv5OeeCBYpII2yqToQZcvjqqabUVPF_AQOQ0CIvJ430iDb2Z9pX1yjxD5ccLETeiFj9GEAK0ntJ8h8xtoGSdv2f8boNcPENhGMMjEThlz9ojPdfqgNQksUk1QeFnCKbl0GTiWmcCZp1A2IEMF0-p5zehAoHFeEV19WZKprog7sEP_OfmkE1K1uPybhGWwwGHoKGpz8s9IIjnCNF-nB_B4H8eh2vrGMF8WROsH6VXR-j7jDB9Rvbcs-nE
action: formie/submissions/save-submission
handle: myForm
siteId: 1
submissionId: 143183
redirect: 69682e332ca51d41fda3184c27600d302c9be5e188733e1387f630c690e074c6https://secret.local/my-projects
fields[firstName]: John
fields[lastName]: Doe
fields[email]: john@doe.com
fields[internationalTitle]: Tempore ratione dol
fields[titleInOriginalLanguage]: Molestias possimus 
fields[format]: TV special
fields[minutes]: 
fields[seconds]: 
fields[animationTechniques]: 
fields[animationTechniques][]: Painting
fields[animationTechniques][]: Stop-motion
fields[animationTechniques][]: Puppets
fields[animationTechniques][]: Clay
fields[animationTechniques][]: Live action
fields[otherAnimationTechniques]: Sunt duis rerum et p
fields[transmedia]: Yes
fields[medias]: 
fields[targetAudience]: Teenagers 12-15
fields[customTargetAudience]: Duis suscipit incidi
fields[finishedSynopsis]: 
fields[finishedSynopsis]: 1
fields[numberOfEpisodeFinishedSynopsis]: 
fields[finishedFinalScripts]: 
fields[finishedStoryboards]: 
fields[finishedStoryboards]: 1
fields[numberOfEpisodesFinishedStoryboards]: 
fields[scriptInformation]: Original script
fields[startDate][datetime]: 2022-04-22 00:00:00
fields[endDate][datetime]: 2022-05-12 00:00:00
fields[membersOfCreativeTeam]: 
fields[checklist]: 
fields[nameMainProductionCompany]: Rodriguez Shaw Traders
fields[addressMainProductionCompany]: Shaffer Irwin Traders
fields[postCodeMainProductionCompany]: Chambers and Key LLC
fields[cityMainProductionCompany]: Manning and Avila Co
fields[countryMainProductionCompany]: Mayotte
fields[generalPhoneNumberMainProductionCompany][number]: 484 22 84 87
fields[generalPhoneNumberMainProductionCompany][country]: BE
fields[emailMainProductionCompany]: dutoxy@mailinator.com
fields[websiteMainProductionCompany]: Mueller and Carver Traders
fields[relevantFilmographyMainProductionCompany]: Facilis minus adipis
fields[titleMainProducersDetails]: Mx.
fields[firstNameMainProducersDetails]: Kelsie
fields[lastNameMainProducersDetails]: Strong
fields[emailMainProducersDetails]: rycisacis@mailinator.com
fields[phoneNumberMainProducersDetails][number]: 484 13 87 69
fields[phoneNumberMainProducersDetails][country]: BE
fields[mobileMainProducersDetails][number]: (782) 603-7177
fields[mobileMainProducersDetails][country]: CA
fields[coProducers]: 
fields[titlePersons]: Mr.
fields[firstNamePersons]: Ori
fields[lastNamePersons]: Harding
fields[companyPersons]: Byers and Steele Associates
fields[emailPersons]: fyhale@mailinator.com
fields[phoneNumberPersons][number]: 484 73 18 88
fields[phoneNumberPersons][country]: BE
fields[synopsisInput]: Aliqua Et non sed i
fields[mainTopicOfTheProjectInput][]: Adventure
fields[mainTopicOfTheProjectInput][]: Comedy
fields[mainTopicOfTheProjectInput][]: Disability
fields[mainTopicOfTheProjectInput][]: Documentary
fields[mainTopicOfTheProjectInput][]: Friendship
fields[mainTopicOfTheProjectInput][]: Historical
fields[mainTopicOfTheProjectInput][]: Inclusion
fields[mainTopicOfTheProjectInput][]: Musical
fields[mainTopicOfTheProjectInput][]: Sustainability
fields[mainTopicOfTheProjectOther]: Nisi officiis ipsa 
fields[projectFileInput][]: (binary)
fields[letterOfInterestNameOfTheCompanyShowingInterest]: Curtis and Barrera Trading
fields[letterOfInterestFirstNameOfTheContact]: Basil
fields[letterOfInterestLastNameOfTheContact]: Brady
fields[letterOfInterestEmailAddressOfTheContact]: lycakaza@mailinator.com
fields[fileUpload][]: (binary)
fields[squareStill][]: (binary)
fields[verticalStill][]: (binary)
fields[horizontalStill][]: (binary)
fields[urlVideo]: Id magni voluptas re
fields[passwordVideo]: Cum cupiditate est 
fields[estimatedTotalBudget]: 19
fields[productionStartDate][datetime]: 2022-03-24 00:00:00
fields[filmOtherCrossmediaApplicationsReleaseDate][datetime]: 2022-05-11 00:00:00
fields[projectReceivedSupportFromCreativeEurope]: No
fields[projectReceivedSupportFromNationalFilmFund]: No
fields[projectReceivedSupportRegionalFilmFund]: No
fields[readAndAgree]: 
fields[authorisation]: 
fields[submitted]: 
goingBack: null
romainpoirier commented 2 years ago

Update: I have done another Back, which failed, but on this one the goingBack value was correctly set to true. Don't know why it wasn't set previously, while it was in the same context.

CRAFT_CSRF_TOKEN: 1hnRFdzYB6X7DJWD-W8i2vMqn_HbF-LTNKGzt0cGjDzgoztyL8gsYt-AGbbdeHEBj282FTyeJkzc6KnQVyiL3cN-rRJVyRMdk3k-eLawV5Tf8a5n9Nhb2pBBzN-B5Vub3FXZ1v5z_yIRdiOouD5QelOY7NhEKqoLoj0nqPLVkaPiAO3f09ZrxbkvMglvJUmUEbZ9vErpVOmrXs2dZtb1vlpwm4popqCaZpa6Ue3f6AZlw1_SzHYtZINpJ6OxLdTtT0VitwlXJl39RX653Z_kYx3p5KFLmSEw-SAl9k8JGoSENPe9kJZUzeBp76Bx_rzihGr97DDut58XxhQoHHCQ-QsjIzv-hpsybZ9Z40RlkaOU4NeLZaGzjJcIitodXUQwbgLRVMpM
action: formie/submissions/save-submission
handle: myForm
siteId: 1
submissionId: 143183
redirect: 69682e332ca51d41fda3184c27600d302c9be5e188733e1387f630c690e074c6https://secret.local/my-projects
fields[firstName]: John
fields[lastName]: Doe
fields[email]: john@doe.com
fields[internationalTitle]: Tempore ratione dol
fields[titleInOriginalLanguage]: Molestias possimus 
fields[format]: TV special
fields[minutes]: 
fields[seconds]: 
fields[animationTechniques]: 
fields[animationTechniques][]: Painting
fields[animationTechniques][]: Stop-motion
fields[animationTechniques][]: Puppets
fields[animationTechniques][]: Clay
fields[animationTechniques][]: Live action
fields[otherAnimationTechniques]: Sunt duis rerum et p
fields[transmedia]: Yes
fields[medias]: 
fields[targetAudience]: Teenagers 12-15
fields[customTargetAudience]: Duis suscipit incidi
fields[finishedSynopsis]: 
fields[finishedSynopsis]: 1
fields[numberOfEpisodeFinishedSynopsis]: 
fields[finishedFinalScripts]: 
fields[finishedStoryboards]: 
fields[finishedStoryboards]: 1
fields[numberOfEpisodesFinishedStoryboards]: 
fields[scriptInformation]: Original script
fields[startDate][datetime]: 2022-04-22 00:00:00
fields[endDate][datetime]: 2022-05-12 00:00:00
fields[membersOfCreativeTeam]: 
fields[checklist]: 
fields[nameMainProductionCompany]: Rodriguez Shaw Traders
fields[addressMainProductionCompany]: Shaffer Irwin Traders
fields[postCodeMainProductionCompany]: Chambers and Key LLC
fields[cityMainProductionCompany]: Manning and Avila Co
fields[countryMainProductionCompany]: Mayotte
fields[generalPhoneNumberMainProductionCompany][number]: 484 22 84 87
fields[generalPhoneNumberMainProductionCompany][country]: BE
fields[emailMainProductionCompany]: dutoxy@mailinator.com
fields[websiteMainProductionCompany]: Mueller and Carver Traders
fields[relevantFilmographyMainProductionCompany]: Facilis minus adipis
fields[titleMainProducersDetails]: Mx.
fields[firstNameMainProducersDetails]: Kelsie
fields[lastNameMainProducersDetails]: Strong
fields[emailMainProducersDetails]: rycisacis@mailinator.com
fields[phoneNumberMainProducersDetails][number]: 484 13 87 69
fields[phoneNumberMainProducersDetails][country]: BE
fields[mobileMainProducersDetails][number]: (782) 603-7177
fields[mobileMainProducersDetails][country]: CA
fields[coProducers]: 
fields[titlePersons]: Mr.
fields[firstNamePersons]: Ori
fields[lastNamePersons]: Harding
fields[companyPersons]: Byers and Steele Associates
fields[emailPersons]: fyhale@mailinator.com
fields[phoneNumberPersons][number]: 484 73 18 88
fields[phoneNumberPersons][country]: BE
fields[synopsisInput]: Aliqua Et non sed i
fields[mainTopicOfTheProjectInput][]: Adventure
fields[mainTopicOfTheProjectInput][]: Comedy
fields[mainTopicOfTheProjectInput][]: Disability
fields[mainTopicOfTheProjectInput][]: Documentary
fields[mainTopicOfTheProjectInput][]: Friendship
fields[mainTopicOfTheProjectInput][]: Historical
fields[mainTopicOfTheProjectInput][]: Inclusion
fields[mainTopicOfTheProjectInput][]: Musical
fields[mainTopicOfTheProjectInput][]: Sustainability
fields[mainTopicOfTheProjectOther]: Nisi officiis ipsa 
fields[projectFileInput][]: (binary)
fields[letterOfInterestNameOfTheCompanyShowingInterest]: Curtis and Barrera Trading
fields[letterOfInterestFirstNameOfTheContact]: Basil
fields[letterOfInterestLastNameOfTheContact]: Brady
fields[letterOfInterestEmailAddressOfTheContact]: lycakaza@mailinator.com
fields[fileUpload][]: (binary)
fields[squareStill][]: (binary)
fields[verticalStill][]: (binary)
fields[horizontalStill][]: (binary)
fields[urlVideo]: Id magni voluptas re
fields[passwordVideo]: Cum cupiditate est 
fields[estimatedTotalBudget]: 19
fields[productionStartDate][datetime]: 2022-03-24 00:00:00
fields[filmOtherCrossmediaApplicationsReleaseDate][datetime]: 2022-05-11 00:00:00
fields[projectReceivedSupportFromCreativeEurope]: No
fields[projectReceivedSupportFromNationalFilmFund]: No
fields[projectReceivedSupportRegionalFilmFund]: No
fields[readAndAgree]: 
fields[authorisation]: 
fields[submitted]: 
goingBack: true
romainpoirier commented 2 years ago

Ok, I finally found that :

engram-design commented 2 years ago

Right, but you're still editing a submission (shown by the endpoint formie/submissions/save-submission which is the cause of this behaviour. You must be doing a {% do submission.form.setSubmission(submission) %} right?

romainpoirier commented 2 years ago

Yes I am editing, and yes I am doing a {% do submission.form.setSubmission(submission) %}.

romainpoirier commented 2 years ago

Do you have any update on this?

I was also wondering if there's any possibility to check for the goingBack state from an event (like Submission::EVENT_AFTER_SAVE)?

I have a complex case where the Submit on Back is causing an unexpected result in my context:

I do it this way in the Twig template, before the renderForm():

{% do submission.setFieldValues(values | merge({
    submitted: (submission.form.isLastPage()) ? '1' : '0'
}), true) %}

After that, the button to access to this form is hidden, and the user can then go to the other steps (which is another form). In that case, it's a bit tricky to play with the status, as it's already a submission that has been submitted previously (so it's no more an isIncomplete and EVENT_AFTER_SUBMISSION has been already triggered).

The problem here is that if the user is on the last page of this form (where a summary is displayed), and if he chose to go Back to edit its values, the Back button is triggering a Submit, which changes the value of the submitted to 1 and closes the form. It has the same behavior as Submit, while I don't need it in this Back context.

After $submission = $event->sender, I tried $submission->goingBack, $submission->form->goingBack and $submission->getForm()->goingBack but none works. And I'm not able to print out all the data returned by $submission.

engram-design commented 2 years ago

Refer to me comment https://github.com/verbb/formie/issues/866#issuecomment-1133826564

So for the moment, that's expected behaviour, simply due to the nature of editing a submission. When you're editing an incomplete submission, it's essentially like a draft. But editing a completed submission, even going back to a previous page without filling in required fields is risky, because the user could just quit editing the submission after saving a required field without any content - if that makes sense?

As you're calling {% do submission.form.setSubmission(submission) %} you are editing a submission, as opposed to submitting a new one.

And there's no event that knows about goingBack especially as all events don't assume its being triggered from the front-end. For example EVENT_AFTER_SAVE is just triggered when saving an element. You might not even be going back or forward in a multi-page form.

But I see your predicament, as you've explained it. So in your case, you really want a "back" button that just navigates to the previous page, instead of submitting values on the current page, and navigating to the previous page. The reason I haven't tackled this yet is the lack of a "Save" button, instead of a "Submit" button.

For example, the user fills out a page, but wants to go back. Navigating back to a previous page would discard any changes made, which isn't great. But requiring the user to submit the page and go forward, isn't great either. I'd like to change this behaviour (for Formie v2 - a breaking change) where clicking Back just navigates backward, discarding any unsaved changes, the ability to add a "Save" or "Save and continue" button to submit and stay on the current page, or a "Submit" button to submit and navigate to the next page.

In that case, it sounds like just a navigable back button would be what you need?

romainpoirier commented 2 years ago

Thank you for all of these explanations. Yes, a navigable back button would be what we need. And it would be even more wonderful if this feature could get part of the Formie V1 version, as V2 will be breaking change...

engram-design commented 2 years ago

I'll do my very best to back-track this change to V1, however, I may struggle to do it in a non-breaking change manner, as currently going back submits the form, and we're changing that.

Will keep you in the loop.

romainpoirier commented 2 years ago

Sorry to ask you this, but do you have any news about an ETA for this for Formie V1 and/or V2?

engram-design commented 2 years ago

So I've been doing a lot of research into the UX behaviour of a back button. To refresh on the proposed change:

But I see your predicament, as you've explained it. So in your case, you really want a "back" button that just navigates to the previous page, instead of submitting values on the current page, and navigating to the previous page. The reason I haven't tackled this yet is the lack of a "Save" button, instead of a "Submit" button.

While we're adding a "Save" button as per https://github.com/verbb/formie/issues/675 and https://github.com/verbb/formie/issues/741 we're also considering changing the behaviour of the back button to just navigate back to the previous page. Any changes will be discarded.

From what I've read, a lot of users expect values to be saved when going back a page in a form, which is what Formie does now. So maybe we need to make that configurable. This is obviously only applicable to Page Reload forms, and for Ajax forms, there's no loss of data as you're not leaving the page.

What concerns me is the UX side of things. Whilst users will receive a warning that their changes are about to be discarded (they might've filled out half the form and forgotten something on a previous page) that's still annoying. It would essentially require people to also include a "Save" button on each page to allow users to save their half-filled content, then navigate back.

engram-design commented 2 years ago

Okay, so after adding the Save button, we've refactored the submit handler to now handle 3 states of submission - submit, save and back. These are now exposed to SubmissionEvent events via the submitAction property, which can be used to tailor submission behaviour to your needs.

I'm probably against making this configurable through the UI, because I think it'll just promote bad practices, or just straight up confuse non-technical users that don't understand what "disable saving when going back" does.

However client-side and server-side validation now no longer kicks in when you're going back, or saving a page, which should address your issue here. Validation (client and server) will only be triggered when you submit the page/form.

I think this gives us the best of both worlds. If you're on a page, and partially fill the page, leaving required fields empty, then navigate back - all your content is saved for when you go back to the page later - but you can still go back leaving those required fields empty. The same scenario applies for clicking the "Save" button.

Added for the next release. To get this early, change your verbb/formie requirement in composer.json to:

"require": {
  "verbb/formie": "dev-craft-4 as 2.0.0-beta.16",
  "...": "..."
}

Then run composer update.

romainpoirier commented 2 years ago

(...) we're also considering changing the behaviour of the back button to just navigate back to the previous page. Any changes will be discarded.

Perfect, it sounds more natural. Like a click on the Previous button of the browser: if you're editing something you get a warning, and if you ignore the warning you lose your edits.

From what I've read, a lot of users expect values to be saved when going back a page in a form

In my opinion, currently it's more a Submit and go back than just a Go back (which would acts like a pagination tool, differently than the tabs).

What concerns me is the UX side of things. Whilst users will receive a warning that their changes are about to be discarded

Is there a way to trigger the native warning of the browser, like when we abandon a form edition without saving it? That's how Craft CMS is doing right now in the CP, at least in Chrome. If it's the native way, it's understandable and accessible.

Okay, so after adding the Save button, we've refactored the submit handler to now handle 3 states of submission - submit, save and back.

Save button : when you save a multi-pages form page before the final submit, or if you're trying to save a single page form without decided to submit it. Submit : the final submit Back : a nav button to go back to a previous page

Not sure if it's so useful, but if we follow this logic, we could also have a Next button which acts like the Back: just a pagination tool without submitting anything.

This would end up something like that, but seems way too much and confused: Back | Save | Submit (& Next) | Next

I think this gives us the best of both worlds. If you're on a page, and partially fill the page, leaving required fields empty, then navigate back - all your content is saved for when you go back to the page later - but you can still go back leaving those required fields empty. The same scenario applies for clicking the "Save" button.

Ok, thank you. I'm more in the side of the native way, using the native warning of the browser. But this should work, I guess, if it's clear for the end user.

I just hope this would not break anything else like unexpected behavior I've got previously: submissions that get completed and EVENT_AFTER_SUBMISSION triggered while there were incomplete, but I think this was related to #758.

engram-design commented 2 years ago

In my opinion, currently it's more a Submit and go back than just a Go back (which would acts like a pagination tool, differently than the tabs).

Correct, and again, this seems to be the general consensus - but that's just people's opinions. Most form examples out there use Ajax which are much easier to retain information. I've even looked as what Freeform does for reference, and they discard (without warning!) when clicking the back button, which I don't find great.

Is there a way to trigger the native warning of the browser, like when we abandon a form edition without saving it? That's how Craft CMS is doing right now in the CP, at least in Chrome. If it's the native way, it's understandable and accessible.

There is, but it's also not customisable. It's the same unload warning you get when filling out the form and refreshing the page. You'll get the following popup:

image

We can't customise that text, which is a bit awkward as you're not really "leaving" the site, just going back.

So the "submit" action is just for when you want to save/validate and proceed to the next page. It's not just for the final page submit. "save" stays on the current page and saves everything as a draft, without validation.

But yeah, I think having a "Next" button might be overkill (I'd debated ditching the "Back" button to be honest, and using the tabs to navigate").

I should also mention it'd be possible to add the navigation back button yourself with custom templates:

{% set previousPage = form.getPreviousPage() %}

<a href="{{ actionUrl('formie/submissions/set-page', { handle: form.handle, pageId: previousPage.id }) }}">Back</a>

I'm more than happy to have the "back" button behaviour configurable. Would you prefer to configure that globally, or per form? I don't think it's something I should have in the UI (personally), but happy to accomodate your needs.

romainpoirier commented 2 years ago

Ok thank you for all this!

I'd debated ditching the "Back" button to be honest, and using the tabs to navigate"

That would be a serious breaking change for our case. We would have to add the tabs, hide them, add a fake Back button that would trigger a click on the previous tab.

Would you prefer to configure that globally, or per form?

Both would be wonderful. One general for all forms, that could be overridden per form, like we can do for the Webhooks. If you can't, setting per form would be more versatile.

engram-design commented 2 years ago

I've added in a plugin setting for this - enableBackSubmission which is enabled by default. This controls whether clicking the "Back" button on front-end forms should submit the current page content. Disabling this will show an "unload" warning and discard any un-saved content. So in your case, you can disable this, and you'll get the behaviour you expect.

To get this early, change your verbb/formie requirement in composer.json to:

"require": {
  "verbb/formie": "dev-craft-4 as 2.0.0-beta.16",
  "...": "..."
}

Then run composer update.

engram-design commented 2 years ago

Added in 2.0.0

romainpoirier commented 1 year ago

I've upgraded from 1.5.16 to 2.0.24, so I'm testing the new enableBackSubmission default setting and I still can't go back when some required fields are not filled in the current page.

Would it be possible to apply this check only if this page has been submitted once? In case the user would like to go back to correct something, but is not yet ready to fill in the current page. Currently, if I fill then in order to go back, I'm going forward instead of backward and I can see submitAction: submit in the payload.

Furthermore, I've tried to disable the new behavior by adding 'enableBackSubmission' => false in config/formie.php file, but I see no change: the form is still submitted when going Back as previously described.

engram-design commented 1 year ago

Are you using custom templates or template overrides? The buttons for Formie's templates will include changing the submitAction param to determine what action is happening. If you're seeing submit when going back, then something isn't right.

romainpoirier commented 1 year ago

Thank you, I've finally found that I was overriding the .fui-prev element which was losing the newly introduced data-submit-action="back" attribute.

However, it looks like when I'm trying to override the content of the button (I'm injecting HTML to add an SVG loading icon) the back action does not works anymore (<input type="hidden" name="submitAction" value="submit"> does not get the back value). It's weird as I'm only editing the content of the button. Any idea why? If too mysterious, I'll stick to CSS.

Here's my not working custom back button html:

<button type="submit" class="fui-btn fui-prev mr-3 px-4 py-3 border-2 border-theme rounded text-theme font-display font-bold uppercase tracking-wider" data-submit-action="back">
    <div class="flex items-center fill-current">
        <span class="order-1 ml-1.5">
            Back
        </span>
        <svg viewBox="0 0 15 15" class="w-4">
            <path fill-rule="nonzero" d="M7.5.5l1.234 1.234L3.85 6.625H14.5v1.75H3.851l4.883 4.891L7.5 14.5l-7-7z"></path>
        </svg>
        <svg viewBox="0 0 24 24" fill="none" class="hidden animate-spin w-5 mx-4">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg></div>
</button>

While this one without edited content is working:

<button type="submit" class="fui-btn fui-prev mr-3 px-4 py-3 border-2 border-theme rounded text-theme font-display font-bold uppercase tracking-wider" data-submit-action="back">Back</button>

FYI I'm using the renderForm() function without custom template, and I'm adding my Tailwind classes using retcon plugin. I was using this method because I'm coming from Formie V1, and that was easier and quicker to theme as I'm using Tailwind. I understand that's not a secure way anymore in Formie V2.

engram-design commented 1 year ago

Hmmm, that's quite odd behaviour - it should just look at data-submit-action and use that - no other changes should matter. Maybe if you can post the JS you're using to inject it, just in case that's a factor?

romainpoirier commented 1 year ago

I'm not using JS to inject it, I'm doing a search / replace / inject using Craft's retcon plugin.

Something like this:

{{ craft.formie.renderForm(form) | retcon([
    ['inject', '.fui-prev', '<div class="flex items-center fill-current">
        <span class="order-1 ml-1.5">
            {term}
        </span>
        <svg viewBox="0 0 15 15" class="w-4" xmlns="http://www.w3.org/2000/svg">
            <path fill-rule="nonzero" d="M7.5.5l1.234 1.234L3.85 6.625H14.5v1.75H3.851l4.883 4.891L7.5 14.5l-7-7z" />
        </svg>
        <svg viewBox="0 0 24 24" fill="none" class="hidden animate-spin w-5 mx-4" xmlns="http://www.w3.org/2000/svg">
            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
            <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg>
    </div>' | t({
        term: 'Back' | t
    }), true]
]) }}
engram-design commented 1 year ago

Ah, sorry - my misunderstanding. That certainly shouldn't be a problem, I'll double-check that on my end though.

romainpoirier commented 1 year ago

While testing the reduced test case from issue #758 using sessionKey, I still found inappropriate Back behavior:

  1. Setup a new multi-pages form with required fields on each page and setup the Submission Method to Page Reload;
  2. Setup the default render with renderForm without custom template: set the sessionKey and do not edit the enableBackSubmission default setting;
  3. Open a new form submission using a unique session key, and fill in the first page;
  4. On the second page that have required fields, do not fill anything and click on the Back button;
  5. You're redirecting to the same second page, instead of the first page;
  6. The required fields are showing errors as they were incomplete before going Back;
engram-design commented 1 year ago

Can't replicate that on my end, sorry! Either clicking the tabs or navigating back submits the form (enableBackSubmission is true by default) and not getting any errors with required fields.

However, I've also just run your Retcon example, and that's indeed triggering the issue. I can see that it's sending submitAction: submit in the payload when clicking the back button. I can see the issue - it's because there are additional elements within the button, and the click event will be triggered on the individual inner elements, not the button.

To get around this, add pointer-events-none on your injected span to prevent events on the inner elements to the button. I'll also look at making an update on my end.

romainpoirier commented 1 year ago

Thank you for the pointer-events-none tip. I'm not using anymore the sessionKey, so can't replicate this issue anymore. I could update later this issue if it's finally included in the final release.