Saving Form Variables as Session Variables the Wrong Way

A student approached me the other day. She were gathering search criteria in a form and wanted to save the criteria to a session variable. But when she moved from page to page, her session variable lost its values.

<cfif isdefined('form.submit')>
<cfset session.saveformvars = structnew()>
<cfset session.saveformvars = form>
</cfif>

The issue is with the the variable scoping that takes place on a form structure. Forms have a local "non-persistent" variable scope (they are only specific to that page, or the page called from the form and don't hang around).

Session variables are by nature persistent, or can exist beyond a single page, lasting for the user's session length.

When the entire form structure was saved as a session variable structure as above, that session structure received the same scoping as the form structure.

So...

<cfset session.saveformvars = form>
<!--- makes session.saveformvars now a local scoped variable and not a session scoped variable --->

Since this student wanted to only save those form fields that were had been completed and do some data tweaking on the information, I had her rewrite the snipped of code to loop through the form, pick out the variables to keep, then save those to the session variable.

<cfset session.plansearch = structnew()>
<cfloop collection="#form#" item='key'>
<!--- pick out null fields, and son't save the submit button or the "FieldNames" key from the form struct --->
<cfif form[key] neq '' and form[key] gt 0 and key neq 'fieldnames' and key neq 'submit'>
<cfset "session.plansearch.#key#" = form[key]>
</cfif>
</cfloop>

Now this student had her trimmed form list saved as a structure in the format she wanted.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Carl Von Stetten's Gravatar Since Form scope variables typically contain only simple values, wouldn't this be simpler?

<cfif StructKeyExists(form, "submit")>
<cfset session.plansearch = StructCopy(form)>
</cfif>
# Posted By Carl Von Stetten | 10/11/11 10:53 AM
anonymous's Gravatar Did StructAppend() disappear from CF or something? The loop is unnecessary.

<cfif structKeyExists(form,'submit')>
<cfset structAppend(session.saveformvars,FORM,'YES')>
<cfset structDelete(session.saveformvars,'fieldnames')>
</cfif>

As long as you're not naming the form field names so that they overwrite each other (tho, the way you have it would do the same), you'll be fine.
# Posted By anonymous | 10/11/11 11:23 AM
Henry's Gravatar the code are too small. pls fix the css. thx
# Posted By Henry | 10/11/11 2:53 PM
Tami's Gravatar @Anonymous,
Yes, STRUCTAppend would work, but remember, the student didn't want to save form fields that were not filled in. This method would have saved all of the text input form fields, even if they were empty strings.
# Posted By Tami | 10/11/11 3:34 PM
Tami's Gravatar @Carl,
Yes, that would have worked too, but again. Since the student only wanted to save those fields with search criteria entered, not the empty form fields, she needed to evaluate the contents. If she did a structcopy(), she would have also received the empty text fields.
# Posted By Tami | 10/11/11 3:37 PM
Bradley Moore's Gravatar There's something about the if statement that bugs me.

The idea seems to make a generic solution, so I took it a couple of steps further.

https://gist.github.com/1284209
# Posted By Bradley Moore | 10/13/11 9:42 AM
Tami's Gravatar Thanks @Bradley. Implementing a function is a much cleaner way of going about it, esp. if it is code that will be used repeatedly :)
Tami
# Posted By Tami | 10/13/11 1:25 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.002. Contact HHWD