Solved

Post a form page to itself and change the URL

Posted on 2006-11-02
14
192 Views
Last Modified: 2013-12-24

 My challenge is to have a wizard-like interface.  That is, a 5 step process.  Each step is a page with a series of form fields on it.  All form fields are submitted to the next page until the last step where everything is submitted for processing.

 I have written plenty of wizards before so no need to delve into the how-to's of carrying form fields over, etc.

 Here's my specific challange for this task; it's all about the URL shown for each page (step).

 I would like the URL to show the step we are on.

 www.mysite.com/index.cfm?page=step3

 But here's the hard part:  

   I must Submit and validate the fields of each step before moving to the next page/step.  If there is a failure in the validation, I want to show the same page again (with the same URL).   If validation is successful, I want to show the next page with the next page's URL.

  I am submitting my page to itself so I can check for errors, if there are erros, I  simply redisplay the same page; but if all is well, I need to be able to get to the next page and change the URL.  Typically I would do this with a <CFLOCATION URL="">  but that won't take all the form fields with me..

 It seems to me this requires some type of double submit, once for validating (because if it fails I can just "drop through" to the original page), and then a follow-up form post to change the URL.

 Alternatively, if I can change while the page is drawing, but I don't think that's possible :)

 My goal is to do this without cookies or session variables.

 
0
Comment
Question by:gdemaria
  • 6
  • 3
  • 3
  • +1
14 Comments
 
LVL 15

Accepted Solution

by:
danrosenthal earned 500 total points
Comment Utility
Here is what you do:
Submit the form to itself like you are doing for validation.
If everything passes validation you create a form with all hidden values and then create an onload event to submit that form.
Let me know if you need more info than that.
0
 
LVL 20

Expert Comment

by:trailblazzyr55
Comment Utility
What about something like this....

Forms page = Wizard (5 steps)
Validation page = Validation (has all hidden fields no view - auto submits based on validation)

Enter Page --> Wizard (step1) --> submit --> Validation --> pass submit --> Wizard (step2) --> submit --> Validation --> pass submit-->  etc...
                                                                       |                                                                                         |
                      Wizard (step1) <--  submit    <-- fail submit                          Wizard (step2) <--  submit    <-- fail submit



Validation page would look like this....
----------------------------------------------
<!--- all validation logic here --->
<!--- create action variable based on validation - defines URL based on validation --->

<form name="validation" action="#ActionVariable#" method="post">
      <input type="hidden" name="FormName" value="ValueFromWizard" />
      <input type="hidden" name="FormName" value="ValueFromWizard" />
      <input type="hidden" name="FormName" value="ValueFromWizard" />
</form>

<script>
      document.forms['validation'].submit();
</script>
0
 
LVL 20

Expert Comment

by:trailblazzyr55
Comment Utility
the validation page acts like a middle man, you submit to it and it'll either increment your step in the URL and submit you back to the wizard, or it'll keep the step the same and submit you back to your wizard, if the validation checks out on the 5th step it can then submit you to the confirmation page, by having the middle man in there, you can keep all the logic seperate from the wizard page and basically this validation page maintains all form values, you could even define error messages here to pass back should validation fail... you bascially maintain the step between pages, if validation passes it increments the step, otherwise it'll keep it the same in the URL.

"ActionVariable" would be in the format ----> index.cfm?page=step3
0
 
LVL 39

Author Comment

by:gdemaria
Comment Utility

 Thanks to both for some good responses.

  It seems the way to go is to do this "double" submit; either after validating or based on validation as Trail suggested.

  I'm curious if you guys have done this in practice and if its a command and frequently used strategy.   It seems a little risky (not sure why) to load a page to the browser and have it immediately re-submit.  

 Does this negatively effect the user experience in any way?  

 Does the browser ever get hung-up on the intermitten submit and show the user a "dead" screen?  

 What about the back-button?  If I were to hit back, would it go to the intermitten page or back to the form page?

 Thanks for your thoughts..
0
 
LVL 20

Expert Comment

by:trailblazzyr55
Comment Utility
there could be potential issues leaving the page say for instance if in that second or two when on the validation the user hits stop on the browser, however if you got a little tricky and submitted to a hidden iFrame for validation rather than another page (similar logic as above), then you could avoid that issue, the iFrame can control the parent window either submitting along or submitting to the same wizard step based on validation.
0
 
LVL 15

Expert Comment

by:danrosenthal
Comment Utility
I have done this method before and have not had any problems.
Most logins also use a "double" submit, one page to set the cookie, and then a second to redirect to the appropriate home page.
0
 
LVL 2

Expert Comment

by:theamzngq
Comment Utility
you could always use session variables to maintian all of your user's input until you are ready to take final action.  For example, at the top of your wizard page, you could include a block like this:

<cfif isDefined("Form.FieldNames")>
   <cfloop list="#Form.FieldNames#" index="thisField">
      <cfset 'Session.TheWiz.#thisField#'  = evaluate('Form.' & thisField)>
   </cfloop>
</cfif>

Any time a form is submitted to your wizard page, any additional form fields would be added to your session.  You could increment the step via a URL var as suggested above, posting to the very same page every time.  When all the steps are done, you'll have session.thewiz with all the form fields the user submitted.

Here's a simplified working example.  Save this in a file called wizard.cfm:

<cfif isDefined("Form.FieldNames")>
   <cfloop list="#Form.FieldNames#" index="thisField">
      <cfset 'Session.TheWiz.#thisField#'  = evaluate('Form.' & thisField)>
   </cfloop>
</cfif>

<cfparam name="form.step" default="1">

<cfoutput>
<cfswitch expression="#form.step#">
      <cfcase value="1">
            <form method="post" action="wizard.cfm">
                  Step 1 form field: <input type="text" name="Step01Form" value="Value from Step 01" /><br />
                  <input type="hidden" name="step" value="#form.step + 1#">
                  <input type="submit" />
            </form>
      </cfcase>
      <cfcase value="2">
            <form method="post" action="wizard.cfm">
                  Step 2 form field: <input type="text" name="Step02Form" value="Value from Step 02" /><br />
                  <input type="hidden" name="step" value="#form.step + 1#">
                  <input type="submit" />
            </form>
      </cfcase>
      <cfcase value="3">
            <form method="post" action="wizard.cfm">
                  Step 3 form field: <input type="text" name="Step03Form" value="Value from Step 03" /><br />
                  <input type="hidden" name="step" value="#form.step + 1#">
                  <input type="submit" />
            </form>
      </cfcase>
      <cfcase value="4">
            Here is your session, complete with all form fields from each step:
            <cfdump var="#session.TheWiz#">
      </cfcase>
</cfswitch>
</cfoutput>
0
Free Gift Card with Acronis Backup Purchase!

Backup any data in any location: local and remote systems, physical and virtual servers, private and public clouds, Macs and PCs, tablets and mobile devices, & more! For limited time only, buy any Acronis backup products and get a FREE Amazon/Best Buy gift card worth up to $200!

 
LVL 2

Expert Comment

by:theamzngq
Comment Utility
using this example, you're only using one page which submits to itself, and all your variables are available to any other processing page you choose to use.
0
 
LVL 2

Expert Comment

by:theamzngq
Comment Utility
btw, it could easily be modified to use the url variable instead of a form variable, like this:

<cfif isDefined("Form.FieldNames")>
   <cfloop list="#Form.FieldNames#" index="thisField">
      <cfset 'Session.TheWiz.#thisField#'  = evaluate('Form.' & thisField)>
   </cfloop>
</cfif>

<cfparam name="url.step" default="1">

<cfoutput>
<cfswitch expression="#url.step#">
      <cfcase value="1">
            <form method="post" action="wizard.cfm?step=2">
                  Step 1 form field: <input type="text" name="Step01Form" value="Value from Step 01" /><br />
                  <input type="submit" />
            </form>
      </cfcase>
      <cfcase value="2">
            <form method="post" action="wizard.cfm?step=3">
                  Step 2 form field: <input type="text" name="Step02Form" value="Value from Step 02" /><br />
                  <input type="submit" />
            </form>
      </cfcase>
      <cfcase value="3">
            <form method="post" action="wizard.cfm?step=4">
                  Step 3 form field: <input type="text" name="Step03Form" value="Value from Step 03" /><br />
                  <input type="submit" />
            </form>
      </cfcase>
      <cfcase value="4">
            Here is your session, complete with all form fields from each step:
            <cfdump var="#session.Thewiz#">
      </cfcase>
</cfswitch>
</cfoutput>
0
 
LVL 2

Expert Comment

by:theamzngq
Comment Utility
sorry for the disparate comments...

Form validation can take place either at the top of that page before the cfswtich, or you could use javascript (my preference) inside of each case statement to validate before submitting the form.  If you validate at the top of the page, you can easily display your error message and reset the url.step var so that it shows the proper case again, filling any form fields that need to be filled from the persistant session variable.

Hopefully that makes sense...
0
 
LVL 2

Expert Comment

by:theamzngq
Comment Utility
one last comment (well, maybe not the last :)

using a persistant session variable to hold all the form submissions also gives you the ability to provide a 'back' button so that users can fix any previous entries.  The back button would simply be a form submitting button with the previous step's number in the url.  If the user clicks 'back', what they've already entered on the page is saved to the session.TheWiz variable, and they are free to change any of the previous step's input, then proceed forward again.

Its a very functional & flexible way of doing wizard-style, multi-step data entry (if I do say so myself)...
0
 
LVL 39

Author Comment

by:gdemaria
Comment Utility

 theamzngq,  I very much appreciate your comments and the time you've taken to provide working examples and your thoughtful comments.

 Your approach probably works well, but, with respect, I must say it would not be my choice.  I will elaborate for the purpose of us all sharing ideas..

 As I said in my question, I prefer not to use session variables for the task.  I feel its bad form as I have worked on other programmer's code that uses session variables heavily and its a nightmare to debug.   Session variables persiste long after you've moved away from the page that was using them (unless you delete them when the user navigates to another area; a difficult task).  Also since sessions can be shared in more than one browser window, it may cause all sorts of bugs by having variables change in one window and thus effect the other.  My feeling is that session variables should do little more than maintain a login.

  Your idea of submitting to the same page is a good one for a wizard with the steps as you've indicated.   In this case, it would be very easy to not use session variables, but simply use the form variables.  They are, after all, submitted to the page, so why convert them from form to session?   All you need to do is track which variables are used on the page for each step, then create a hidden form input tags for each form value Not shown in that step.  I do this my having a couple lists:   variables.allFields = "a,b,c,d,e,f,g..."  is a list of all fields used throughout the wizard.  varibales.thisStepFields="a,b,c" is a list of the fields used in the current step.  Any field in variables.allFields but not in variables.thisStepFields would have a hidden input form field created.  Of course, the entire page would be under one <FORM> tag.  No need for the multiple forms.

  In any case, I don't believe the page submitting to itself concept (whether using your approach or mine) would address the problem.  I am trying to keep the URL from changing (what the user sees in the address line) unless in fact the step has been successfully validated.  That means the URL is always showing the actual step you are on.   I believe the submit to yourself approach would have to submit either to step 2 or to step 1, either may be wrong depending on the success or failure of validating the step.

  Validation using javascript is not my preference, particularly if using the annoying pop-up alerts().  Javascript cannot do some necessary database inquiries (unless using ajax or the like) and other server-side processing like file upload.

 Again, thanks for you comments.

 I feel danrosenthal hit the mark.  I've done some research and found it to be a common and effective approach.

0
 
LVL 39

Author Comment

by:gdemaria
Comment Utility

 I placed this meta tag in the header of my layout page.  I set the variable to the URL I would like to redirect to.

 <cfif IsDefined("attributes.RefreshPageURL") and Len(attributes.RefreshPageURL)>
    <cfoutput>
    <META HTTP-EQUIV='Refresh' CONTENT='0;URL=#attributes.RefreshPageURL#'>
    </cfoutput>
 </cfif>


 Some Macintosh users seem to have some problem's with it.  Is this cross-browser / platform or is there a better way?
0
 
LVL 2

Expert Comment

by:theamzngq
Comment Utility
I understand where you're coming from, gdemaria.  Your method will most certainly work.  I have used the session method in many situations, and very successfully.  The problems you mentioned have never been an obstacle for me; there are easy way to control each of those situations.  I believe I learned that session wizard methodology from one of Ben Forta's books...

At any rate, glad to contribute to the brain trust of CF!  Thank you for you comments, and good luck!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

One of the typical problems I have experienced is when you have to move a web server from one hosting site to another. You normally prepare all on the new host, transfer the site, change DNS and cross your fingers hoping all will be ok on new server…
Periodically we have to update or add SSL certificates for customers. Depending upon your hosting plan you may be responsible for the installation and/or key generation. In the wake of Heartbleed many sites were forced to re-key. We will concen…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now