简体   繁体   中英

ColdFusion 11: How do I check if a form field value is found in a Struct object without re-loading the page?

Scenario: I have a signup form with a Promo Code field. I need to check that a promo code entered by the user is valid without reloading the page.

The promo codes are all saved in a Struct like so (not actual values, but same format):

<cfset sysPromoCode = structNew()>
<cfset tmp = StructInsert(sysPromoCode,"PC1","1.00")>
<cfset tmp = StructInsert(sysPromoCode,"PC5","5.00")>
<cfset tmp = StructInsert(sysPromoCode,"PC10","10.00")>
<cfset tmp = StructInsert(sysPromoCode,"PC15","15.00")>
<cfset tmp = StructInsert(sysPromoCode,"PC20","20.00")>
<cfset REQUEST.PromoCodeStruct = sysPromoCode>

In my component file ('cmp-settings.cfc') I've created this function:

<cffunction name="ValidatePromoCode" access="remote" returnformat="json" output="false">
    <cfargument name="PromoCode" type="string" required="true">
    <cfif StructKeyExists(REQUEST.PromoCodeStruct, arguments.PromoCode)>
        <cfset isvalidPromoCode = true>
    <cfelse>
        <cfset isvalidPromoCode = false>
    </cfif>
    <cfreturn isvalidPromoCode />
</cffunction>

And the section of the form I'm working with:

<label for="fPromo">Promo Code</label>

<input type="text" class="form-control" id="id_PromoCode" name="PromoCode" maxlength="10"> 
<a href="javascript:void();" onclick="applyPromo();" class="btn btn-success btn-sm">Apply</a>
                                
<div id="pInvalid" style="display:none;color:##ff0000;font-weight:bold;">Invalid code!</div>
<div id="pValid" style="display:none;color:##66cc00;font-weight:bold;">You've entered a valid code!</div>

'applyPromo()' is a basic javascript function that runs a show/hide process on the pInvalid and pValid fields. That is is the script I'm replacing as it currently exposes the list of promo codes in the page source. I expect it has to be replaced with an AJAX call, but I'm really not familiar enough with JQuery and AJAX to find the solution myself.

Any advice and help would be greatly appreciated from a newbie to StackOverflow.

When you onclick="applyPromo();" , this function needs to make an Ajax request to the server to verify the promo code, return the discount amount and apply it in the UI.

When you submit the form, you need to re-verify the discount code on the server-side. Make sure the adjusted total is calculated on the server as well. Don't trust that the form isn't just taking whatever the client-side code says as the adjusted total.

You have the ColdFusion variable sysPromoCode that defines the codes and that only exists in at the time of execution on the server. The quick and dirty approach would be to create a PromoCodeService.cfc :

<cfcomponent>

    <cffunction name="init" access="public" output="false" returntype="any">
        <cfset variables.PromoCodeStruct = {
            "PC1" : 1,
            "PC5" : 5,
            "PC10" : 10,
            "PC15" : 15,
            "PC20" : 20
        } >
        <cfreturn this>
    </cffunction>

    <cffunction name="getDiscountCodes" access="public" output="" returntype="struct"
        hint="I return all available discount codes.">
        <cfreturn variables.PromoCodeStruct>
    </cffunction>

    <cffunction name="getDiscountByCode" access="public" output="false" returntype="numeric"
        hint="I return a valid discount or -1 for invalid codes.">
        <cfargument name="dicsount_code" type="string" required="true">
        <cfif structKeyExists( variables.PromoCodeStruct, arguments.dicsount_code )>
            <cfreturn variables.PromoCodeStruct[arguments.dicsount_code]>
        <cfelse>
            <cfreturn -1>
        </cfif>
    </cffunction>

</cfcomponent>

Your Ajax call would target some URL like /api/check_promo_code.cfm :

<cfcontent type="application/json">
<cfif structKeyExists(form, "PromoCode")>
<cfset oPromoCodeService = new path.to.PromoCodeService()>
<cfoutput>#oPromoCodeService.getDiscountByCode(form.PromoCode)#</cfoutput>
<cfelse>
-1
</cfif>

This code verifies if a code was submitted via an HTTP POST and then checks the struct for a matching key and returns the discount amount. If there's no match, it the function getDiscountByCode() returns a -1. If the required data is missing, the request still returns -1 .

Your Ajax call can then apply the discount amount in the UI or show that the code was invalid (-1).

You can then replace your existing definition of <cfset REQUEST.PromoCodeStruct = sysPromoCode> like so:

<cfset oPromoCodeService = new path.to.PromoCodeService()>
<cfset REQUEST.PromoCodeStruct = oPromoCodeService.getDiscountCodes()>

So you can continue using REQUEST.PromoCodeStruct as is after that.

What this also does is give you a path to moving discount codes to the database if needed. You just update those functions with queries and you're good to go.

One last note:

he's resistant to being charged for the time it would take to fix much of the mess under the hood

You either pay to fix the mess as needed or you live with the more likely greater costs the mess incurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM