Version 1 (modified by trac, 17 years ago)

--

Quickstart 5: Validating a Form

Our translation form doesn't require the user to enter a value. Our application doesn't fail, but it'd be nice to server-side validate the form.

(Actually, it's not just nice, it's something you should do for every form, every time.)

Using the translateForm function, it's easy to check if the form as been filled out. However, how do we alert the user? How do we take them back to the form, instead of showing the result?

The <event-handler> tag has a third child tag, <results>, that's custom made for things like this.

Adding a <results> and <result> tag to our translationFormAction event handler, we end up with the following xml:

<event-handler name="translationFormAction">

<broadcasts>

<message name="NeedTranslation" />

</broadcasts>

<views>

<include name="body" template="dspPhrase.cfm">

<value name="xe.translationForm" value="translationForm" />

</include>

</views>

<results>

<result name="ValidationError" do="translationForm" redirect="true" />

</results>

</event-handler>

What does that <result> tag mean? It means that if I somehow state that the event has a validation error, immediately stop processing the event and redirect to the translationForm event.

So how do we indicate that there's a validation error? We test a condition in our controller, and if necessary, add the result to arguments.event:

Doing this, the TranslatePhrase function now reads:

<cffunction name="TranslatePhrase" access="public" returntype="void" output="false">

<cfargument name="event" type="any">

<cfset var translator = createObject("component", "translator.model.PigLatinTranslator").init("aeiou") />

<cfset var phrase = arguments.event.getValue("phrase") />

<cfset var result = translator.translate(phrase) />

<cfif not len(trim(phrase))>

<cfset arguments.event.addResult("ValidationError") />

</cfif>

<cfset arguments.event.trace("TranslatePhrase Results", result) />

<cfset arguments.event.setValue("translatedPhrase", result) />

</cffunction>

Try the submitting the form without filling in a phrase. You'll wind up right back at the form. That's OK, but we need to provide an error message.

Remember, we can use controller functions to add values to the viewstate that view templates can display. Let's first add an error message to TranslatePhrase:

<cffunction name="TranslatePhrase" access="public" returntype="void" output="false">

<cfargument name="event" type="any">

<cfset var translator = createObject("component", "translator.model.PigLatinTranslator").init("aeiou") />

<cfset var phrase = arguments.event.getValue("phrase") />

<cfset var result = translator.translate(phrase) />

<cfif not len(trim(phrase))>

<cfset arguments.event.setValue("phraseError", "Please enter a phrase to translate.") />

<cfset arguments.event.addResult("ValidationError") />

</cfif>

<cfset arguments.event.trace("TranslatePhrase Results", result) />

<cfset arguments.event.setValue("translatedPhrase", result) />

</cffunction>

Then, change frmPhrase.cfm to display the phrase error, if one has been set:

<cfset submit = viewstate.getValue("myself") & viewstate.getValue("xe.translate") />

<cfform action="#submit#">

<cfinput type="text" name="phrase" required="false" value="#viewstate.getValue("phrase")#" />

<input type="submit" value="Ok" />

<cfif viewstate.exists("phraseError")>

<cfoutput><p><font color="red">#viewstate.getValue("phraseError")#</font></p></cfoutput>

</cfif>

</cfform>