Form Handling and Validation with ColdBox, ColdSpring, and Transfer (Part 2)

This post is a continuation of another post where I am discussing form handling and validation.

Please see part 1 before you read this post.

So, after my user enters data into the form, they will hit the add/update button and the form will get posted to the next event handler, called items.editPost().

    <cffunction name="editPost" access="public" returntype="void" output="false">
        <cfargument name="Event" type="coldbox.system.beans.requestContext" />
        <!--- Get result bean for error handling --->
        <cfset var result = CreateObject("component", "model.common.result").init() />
        <!--- Get item service and an item Bean --->
        <cfset var itemService = getPlugin("ioc").getBean("itemService") />
        <cfset var itemBean = "" />
        <!--- Get form data from the event object --->
        <cfset var formData = event.getCollection() />
        <!--- Check to see if the eventid exists, if not, not a valid request --->
        <cfif NOT event.valueExists('itemid') OR NOT IsNumeric(event.getValue('itemid'))>
            <cfset setNextEvent('items.edit') />
        <!--- Set item bean from service --->
        <cfset itemBean = itemService.getItem(event.getValue('itemid')) />
        <!--- Call validation method, pass in error handling onject and form data --->        
        <cfset itemBean.validate(formData, result) />
        <!--- If the item Has errors, add them to the message box and return the user to the form --->
        <cfif result.hasErrors()>
            <cfset getPlugin("messageBox").setMessage("error","", result.getErrors()) />
            <cfset Event.setLayout('Layout.Admin')>
            <cfset Event.setView("itemForm") />
            <!--- If there are no errors, persist the bean and return the user to the item list --->
            <cfset />
            <cfset setNextEvent("itemList") />

items.editPost() will first create a result object. This is an idea Brian Kotek gave me in his answer to my question on bean validation.

The result object is a very simple object that can be passed to the validation method to catch any errors and store them internally. I can then use the objects getErrors() method to return the array for display. The result object looks like this:

<cfcomponent output="false">    
    <cffunction name="init" access="public" returntype="model.common.result" output="false">
        <cfset variables.errors = arrayNew(1) />
        <cfreturn this />    
    <!--- Used to get an Array of errors formt he object, for display --->
    <cffunction name="getErrors" access="public" returntype="array" output="false">
        <cfreturn variables.errors>
    <!--- USe to set a new error into the local array --->
    <cffunction name="setError" access="public" returntype="void" output="false">
        <cfargument name="error" type="string" required="true" />
        <cfset ArrayAppend(variables.errors, arguments.error) />
    <!--- Returns boolean telling whether or not there are any errors --->
    <cffunction name="hasErrors" access="public" returntype="boolean" output="false">
        <cfif ArrayLen(variables.errors)>
            <cfreturn true />
            <cfreturn false />

Next my editPost() method will create the itemService and an empty itemBean variable.

Next it grabs the data from the form using ColdBox's getCollection() method and inserts it into a local variable.

The handler then checks to make sure an itemid was actually passed in, if not, it is not a valid request, and it redirects the user.

Next it sets the itemBean from the itemService using the itemid passed in.

This post is continued in part 3

ike's Gravatar This is essentially the same approach to server-side form validation that I take when I don't have access to the form tools in the onTap framework. The down side for me (of not having my tools) is that I know when I write these that they're not i18n and they require more maintenance (and more up-front coding). The i18n thing is less of an issue, because most apps do ultimately end up staying in one language, but designing them with a plan for multi-lingual support to me is like a condom, better to have it and not need it than need it and not have it. :) The other half is what I personally find really frustrating, just because it's a lot of lines of code I that I never need on my own projects. Although the form tools really just are a more advanced way of encapsulating this same idea plus i18n and a few other features. I realize it may sound like I'm hawking my stuff, but I'm also trying to affirm your technique. :)
# Posted By ike | 8/15/08 10:36 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1. Contact Blog Owner