Check if argument exist in the structure, if not set to NULL?

719 views Asked by At

I have a set of radio buttons that I would like to validate on the server side. First I created structure that has the argument names for the key. Then each name is set to different values that the radio button can have. Here is an example:

<cfargument name="frmhs_rad1" type="string" required="false" default="">
<cfargument name="frmhs_rad2" type="string" required="false" default="">
<cfargument name="frmhs_rad3" type="string" required="false" default="">

<cfset validateRadio = {
        frmhs_rad1 = 0,
        frmhs_rad1 = 1,
        frmhs_rad2 = 0,
        frmhs_rad2 = 1,
        frmhs_rad2 = 2,
        frmhs_rad3 = 0,
        frmhs_rad3 = 1,
        frmhs_rad3 = 2
    }>

Here is an example of one of my cfqueryparam lines:

<cfqueryparam value="#trim(structKeyExists(validateRadio, arguments.frmhs_rad1) ? validateRadio[arguments.frmhs_rad1]:"")#" cfsqltype="cf_sql_char" null="#yesNoFormat(!len(trim(arguments.frmhs_rad1)))#" />

If I don't check the radio button the value in my Database will remain NULL. If I check the radio button then I see a blank space in this field. I think that my code should prevent that. If value exists then I check if it's valid in validateRadio structure. If value doesn't exist then it should be set to NULL. I'm not sure why my code is failing. Can anyone see the problem with my code?

3

There are 3 answers

0
Miguel-F On

I think I see part of the problem and hopefully this will get you headed in the right direction. I think you are attempting to build a structure containing all of the possible values for your radio buttons. The problem is that you have more than one possible value for the same name (key). Structures do not support that.

You have this code:

<cfset validateRadio = {
    frmhs_rad1 = 0,
    frmhs_rad1 = 1,
    frmhs_rad2 = 0,
    frmhs_rad2 = 1,
    frmhs_rad2 = 2,
    frmhs_rad3 = 0,
    frmhs_rad3 = 1,
    frmhs_rad3 = 2
}>

But if you dump the validateRadio structure you will see that it only contains the last values that you set for a particular name (key).

FRMHS_RAD1 1  
FRMHS_RAD2 2  
FRMHS_RAD3 2  

The other values are lost.

Next, I don't believe your queryparam logic will work either. You have this condition:

structKeyExists(validateRadio, arguments.frmhs_rad1)

In that code the arguments.frmhs_rad1 variable will hold the value of the radio button (1, 2, or 3). Those values are not the keys of your structure so they will never be found. The keys of your structure are frmhs_rad1, frmhs_rad2 and frmhs_rad3.

1
Benster On

Are you defaulting the radio buttons to blank on the page that processes the form post? If a radio button is not checked on the form, it is not sent.

Try adding this on the top of your processing page

<cfparam name="MyRadioButtonName" default="" >

Just put one in for each of your radio buttons. If they are not checked they will be null.

If you want a unchecked radio button to default to zero you can try this:

    <cfparam name="MyRadioButtonName" default="0" >

Let me know if that works.

0
Scott Jibben On

@Miguel-F has valid points as to why the struct that you were creating will not work, that is, a key in a struct will only be allowed one time. I'm implementing something similar; a struct that has a list of valid values for each radio button name. The code below should have enough comments in it to explain how it works. If your goal is to protect against form spammers who just submit trash to your action page, you may consider using cfthrow/cfreturn instead of allowing the garbage to get into your database. Note the comment that tells where the cfthrow should go if this is the case.

<cffunction name="myFormAction" access="public">
    <cfargument name="frmhs_rad1" type="string" required="false" default="">
    <cfargument name="frmhs_rad2" type="string" required="false" default="">
    <cfargument name="frmhs_rad3" type="string" required="false" default="">

    <!--- the keys in this struct must match keys in the arguments struct --->
    <cfset local.validateRadio = {
        frmhs_rad1 = "0,1"
        ,frmhs_rad2 = "0,1,2"
        ,frmhs_rad3 = "0,1,2"
    }>

    <!--- loop over radio button validate struct --->
    <cfloop collection="#local.validateRadio#" item="local.key">
        <!--- if the radio button value is not valid, set it to a empty string which will then become NULL in the cfqueryparam --->
        <cfif arguments[local.key] NEQ "" && !listFind("#local.validateRadio[local.key]#", arguments[local.key])>
            <!--- this could easily be a cfthrow or some other process for handling invalid data --->
            <cfset arguments[local.key] = "">
        </cfif>
    </cfloop>

<!--- now the null argument will fire for unused or invalid radio buttons --->
<cfquery>
INSERT/UPDATE ...
<cfqueryparam value="#arguments.frmhs_rad1#" cfsqltype="cf_sql_char" null="#yesNoFormat(!len(trim(arguments.frmhs_rad1)))#" />
</cfquery>

</cffunction>