# Quickstart 4: Handling a Form

Ok, we've built a form. It submits to an event handler named "translationFormAction." Now, we need to create that event.

Let's do it now. Add the following new event handler XML to /translator/config/ModelGlue.xml:

<event-handler name="translationFormAction">

</event-handler>

Ok, fire up a browser, go to http://localhost/translator/index.cfm?event=transationForm, fill in a phrase, and click Ok.

Not much happened, eh?

Obviously, we need to tell the application to translate the phrase that's been entered. Our first step is to add a message to the translationFormAction. A message is like a town crier: it's the event handler's way of saying "I need the phrase to be translated!" The event handler itself doesn't care who does the translation.

Let's add the message:

<event-handler name="translationFormAction">

<broadcasts>

<message name="NeedTranslation" />

</broadcasts>

</event-handler>

Try the form again if you like. Still nothing. That's because the event handler can ask for translations until it's blue in the face (or view), but nothing's going to happen unless something listens to the message.

At the top of ModelGlue.xml, there's a <controllers> block we haven't talked about yet. It declares a list of <controllers>, which in turn contain a list of <message-listeners>.

It sounds complicated, but it isn't.

You'll see that each <controller> tag has a TYPE attribute. That attribute points to a CFC known as a "Controller CFC". When Model-Glue starts, it creates an instance of each Controller CFC listed.

The <message-listener> tags simply tell the controller "Whenever an event handler broadcasts a message named MESSAGE, execute your function named FUNCTION."

So, to get something to translate, we need to tell our Controller to listen for the NeedTranslation message. Add a new <message-listener> tag to the default <controller> block, making it look like this:

<controller name="MyController" type="modelglueapplicationtemplate.controller.Controller">

<message-listener message="OnRequestStart" function="OnRequestStart" />

<message-listener message="OnRequestEnd" function="OnRequestEnd" />

<message-listener message="NeedTranslation" function="TranslatePhrase" />

</controller>

Ok, now try the form. Again.

Still nothing? There's one last piece to the puzzle: write a TranslatePhrase function in the Controller that asks our Model to translate a phrase! That's easy enough - just open /translator/controller/Controller.cfc and add the following <cffunction>:

<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) />

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

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

</cffunction>

So what does all that do?

First, arguments.event is like the twin sibling of the viewstate variable in a view. It has a getValue() method to get variables from the FORM and URL scopes. However, it also has a setValue() method that can set values into the viewstate, readable in views or later message listener functions.

Second, it creates an instance of our application's Model CFC:

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

Third, it gets the value of FORM.phrase

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

Fourth, it asks the model to translate the phrase:

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

Fifth, it adds the results of the translation to the Model-Glue debugging output, so that we can see that it's been translated properly:

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

Last, it sets the results of the translation into the viewstate so that our view templates can display the data:

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

Ok, finally, run the form! Seriously, something will happen this time! You won't get much, but you'll see a line in the Model-Glue debugging trace labelled "TranslatePhrase Results" that shows the translated phrase.

As a last step, let's add a view that shows our translated phrase. That'd probably make users happy, because we'll turn the debugging trace off when we deploy this application.

Following the same steps as we did when we built the form, first add a dspPhrase.cfm file to /translator/views. You'll notice that we again use an eXit Event, this time to build a link back to the translation form. To the link, we append the "phrase" value. If you look back at frmPhrase.cfm, the VALUE attribute of our <cfinput> tag was set to viewstate.getValue("phrase"). getValue(), by default, returns an empty string if a value is not defined. By appending the phrase to the URL, we can set the default value of the input box.

<cfset translationForm = viewstate.getValue("myself") & viewstate.getValue("xe.translationForm") & "&phrase=" & viewstate.getValue("phrase") />

<cfset translatedPhrase = viewstate.getValue("translatedPhrase") />

<cfoutput>

Translated Phrase: #translatedPhrase#

<br />

<a href="#translationForm#">Translate Again.</a>

</cfoutput>

Second, tell the event handler to <include> the view:

<event-handler name="translationFormAction">

<broadcasts>

<message name="NeedTranslation" />

</broadcasts>

<views>

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

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

</include>

</views>

</event-handler>

Wow. You now know about half of Model-Glue. There's really only another quarter or so that's fundamental knowledge, and the remaining bit after that is just icing on the cake that you'll use every now and then.