• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Trying to dynamically output form fields returns URL values

Explorer ,
Oct 09, 2013 Oct 09, 2013

Copy link to clipboard

Copied

Hello,

If there is a better way to go about this (which is quite likely), please let me know how to go about it.

I'm working on some code that is supposed to dynamically set the form variables as regular variables so that we can be lazy and not have to refer to the variable with form.somevariable name.

That part works perfectly.  Until I start testing for URL conflicts in which a URL variable has the same name.  For instance. . .

I have a form that passes two variables; FirstName and LastName.  If I hit the page, the form shows up, I input a first and last name and click submit.  The code works perfectly.

However, if I have URL variables with the same names, the code reports the url variable values instead of the form values.

Some sample values;

url.FirstName = Joe

url.LastName = Black

form.FirstName = Steve

form.LastName = White

My code that exposes the form variable will correctly find the form field names, but then when I 'evaluate' the value of the given form field, it will return the value of the URL variable of the same name rather than the form variable.

What I am really wanting (as I described briefly up above) is to have code that automatically converts client, URL and Form variables into 'regular variables' so that you don't have to write lots of extra code grabbing them later on.  Frameworks like CFWHEELS and ColdBox do this by default, but at the company I work out, we aren't using any of them.  I need it to expose the URL variables, but give presidence to form variables if they have the same name, because they are likely to be intended to do an update or such.

The code follows  Feel free to ignore the code for the URL and client variables if you wish as they don't directly affect how the form code works, I have tested with them commented out and I get the same result.  I provided all of it to give a more complete idea of what I have been toying with so far.  Please note that I don't normally use 'evaluate'.  There is probably a better way to go, but I don't know what it is.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

<!--- Create a form so that we can post some form variables --->

<form action="" method="post">

    First Name <input type="text" name="FirstName" />

    Last Name <input type="text" name="lastName" />

    <input type="submit" />

</form>

<!--- Set a variable to hold the list of URL variable names --->

<cfset paramsurl = structKeyList(url)>

<cfoutput>

<br />

URL variables:

<!--- Loop through the list of url variables and then dynamically set a new variable to be equal to whatever is held by it --->

    <cfloop index="i" list="#paramsurl#">

        <cfset myDynVar = Evaluate(i)>

       

        <!--- Let's output the dynamically created variable as a test --->

        #i# = #myDynVar#<br />

    </cfloop>

</cfoutput>

<!--- If form fields exist --->

<cfif isdefined("Form.FieldNames")>

    <cfoutput>

        <b>Field Names:</b> #Form.FieldNames#

        <p>

            <b>Field Values:</b><br>

            <cfloop INDEX="TheField" list="#Form.FieldNames#">

                #TheField# = #Evaluate(TheField)#<br>

                <cfset TheField = Evaluate(TheField)>

            </cfloop>

        </p>

        Lets try and output the two form fields without using the "form." notation<br>

        FirstName : #FirstName# <br />

        LastName : #LastName#

    </cfoutput>

</cfif>

<br />

The client variables currently available are:<br />

<cfoutput>

    <cfset nVarCounter = 1>

    <cfloop list="#GetClientVariablesList()#" index="whichClientVar">

        #whichClientVar# : #client[whichClientVar]#<br />

        <cfset whichClientVar = Evaluate(whichClientVar)>

    </cfloop>

</cfoutput>

Views

2.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 09, 2013 Oct 09, 2013

Copy link to clipboard

Copied

Though I highly don't recommend merging variable scopes into 1 melting pot, let me ask a couple questions first.

1. You're posting data, so if you arrive at a page which HAS URL attributes you need to hold onto, you'll need to create a hidden form field and populate it with the CGI.query_string value.  Because if you arrive on test.cfm?this=that or even if your action attribute of your form points to "test.cfm?this=that" but the method is set to post, you're going to lose all your URL scope data when you submit the form.  To keep it, make a hidden field like I mentioned and if you populate it with the CGI.query_string value, you can process this on form submit.

2. If you're throwing everything into the VARIABLES scope, but you want ot be made aware when 2 variables have the same name, you're basically just looking to see if any variable off the root of the CLIENT, FORM, and URL scopes has the same name as in another scope.  Right?  CLIENT.der would collide with URL.der, otherwise, when all is said and done, VARIABLES.der will have the value in it.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 09, 2013 Oct 09, 2013

Copy link to clipboard

Copied

Hello,

Thank you for replying.   For the purpose of this code, I do not need to worry about having a given variable persist between page postings.  The individual pages need to take care of that.

This code is just to make basic coding easier and faster.  It should work much the same way that many of the Frameworks handle it.

Form variables are greater than URL variables.  So if you have a form and URL variable and they both have the same name, then the form version of the variable should 'win'.  Hard coding the example might be something like this. . .

<cfif isdefined("url.FirstName")>

     <cfset FirstName = url.FirstName>

</cfif>

<cfif isdefined("form.FirstName")>
     <cfset FirstName = form.FirstName>

</cfif>

In this example, if FirstName existed as both a url AND a form variable, it would be set to whatever the form value was since it was last.

However, in the dynamic code that I was working on, if the variable exists as both a form and url version, my code will return the url version.  I do NOT want that to happen.

I am guessing that there is a better/different way to go about this, but I'm not sure what it is.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 09, 2013 Oct 09, 2013

Copy link to clipboard

Copied

Try this:

<cfset structAppend( FORM, {

          'alpha' = 'bravo',

          'charlie' = 'delta',

          'echo' = 'foxtrot'

}, true ) />

<cfset structAppend( URL, {

          'alpha' = 'zulu',

          'lima' = 'mike',

          'echo' = 'papa'

}, true ) />

<!--- List the scopes in ascending order of importance. --->

<cfdump var="#FORM#" label="FORM scope" />

<cfdump var="#URL#" label="URL scope" />

<cfset scopes = "url,form">

<cfloop list="#scopes#" index="i">

          <cfloop list="#structKeyList( evaluate( i ) )#" index="j">

                    <cfset structInsert( VARIABLES, j, evaluate( i & '["' & j & '"]' ), true ) />

          </cfloop>

</cfloop>

<cfdump var="#VARIABLES#" abort="1" label="Combined Variables Scope" />

What I did is insert 3 key/value pairs into the FORM and URL scope.  I then dumped the scopes to show their structure and values.  Then I defined a variable (scopes) which is a list of the least important scope to the most important.  After that, the loop I do simply goes through the SCOPES, their exisiting key/values and sets them into the VARIABLES scope.  Then, when it moves to the next scope of importance, it simply puts their value into the variables scope as well (overriding in the event it already exists), thus, the scopes defined later in the list override and replace.

Then I just dump the VARIABLES scope (you'll notice it has the I, J and SCOPES variables in there that I used to create the loop.  If you perform this action in a function, simple make the I, J and SCOPES variables part of the LOCAL scope so they won't be in your VARIABLES scope.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 09, 2013 Oct 09, 2013

Copy link to clipboard

Copied

Thanks!

I will test this and reply back.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 10, 2013 Oct 10, 2013

Copy link to clipboard

Copied

Hello,

I tested it and it appears to be working perfectly.  Can client variables be worked into it the same way?

[edit]

I added client to the list and it is working flawlessly!

Thanks again!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 10, 2013 Oct 10, 2013

Copy link to clipboard

Copied

LATEST

Cool, glad I could help.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation