UNIT 10 - Building Forms

Objectives

After completing this unit you will be able to build your own FarCry forms to edit and save content objects.

Formtool Tag Library

Up until this point, all of our forms have been generated for us by the system. But what if we need more flexibility? We must be able to create our own edit forms.

FarCry has its own set of tags enabling you to build forms to add, edit and save content yourselves. This tag library is located at /farcry/core/tags/formtools and is imported into your webskin using:

<cfimport taglib="/farcry/core/tags/formtools" prefix="ft" />

We are going to look at this unit in 2 stages:

  1. Building the Form
  2. Processing the Form

Wizard Tools

A similar custom tag library exists for building Wizards, but these are not covered in this unit.

Building the Form

The first stage is to simply build the form. The following code is all we need to do:

<ft:form>
        <ft:object objectid="#stobj.objectid#" lFields="" />
        
        <ft:button value="Save" />
        <ft:button value="Cancel" validate="false" />
</ft:form>

You will see 3 simple tags:

<ft:form />

This tag virtually replaces the html <form> tag. Behind the scenes, however, it is setting up all the necessary plumbing so that FarCry knows what object you are saving, hooks for client-side and server-side validation and so on.

<ft:object />

This tag actually renders each of the requested properties in edit mode. All the properties passed through in the lFields attribute will be available for editing. If you want to edit ALL fields, you can leave this attribute blank.

This tag also has a number of attributes that you can use to affect the output. Most interesting is the legend attribute. This will allow you to create your own fieldsets.

<ft:button />

This tag will provide the buttons to perform actions on the form, essentially replacing the standard <input type="submit" /> html markup.

Source of a Sample Form

Below you will see an example of the generated html markup that the simple form tags we used above generates. Although it may look a bit intimidating, there is a method to the madness (wink). You do not need to understand the output at all to use formtools, but curious minds should feel free to quiz the instructor.

<form 
  action="/webtop/conjuror/invocation.cfm?objectid=BC139D3D-C12A-A68F-5AD1A9660401F83A" 
  method="post" 
  id="farcryForm590063094" 
  name="farcryForm590063094" 
  enctype="multipart/form-data" 
  onsubmit="" 
  class="formtool" 
  style="">

     <input type="hidden" name="FarcryFormPrefixes" value="BC139D3DC12AA68F5AD1A9660401F83A">

     <fieldset class="formSection ">

	<legend class="">General Details</legend>

	<div class="fieldSection string ">
	<label for="BC139D3DC12AA68F5AD1A9660401F83Atitle" class="fieldsectionlabel ">Title</label>
	<div class="fieldAlign">
	<input type="Text" 
		name="BC139D3DC12AA68F5AD1A9660401F83Atitle" 
		id="BC139D3DC12AA68F5AD1A9660401F83Atitle" 
		value="Andrew Spaulding" class="" style="">
	</div>
        <br class="clearer">
        </div>

        <div class="fieldSection string ">
	<label for="BC139D3DC12AA68F5AD1A9660401F83Asecrethideout" class="fieldsectionlabel ">Secret Hideout</label>
	<div class="fieldAlign">
	<input type="Text" 
		name="BC139D3DC12AA68F5AD1A9660401F83Asecrethideout" 
		id="BC139D3DC12AA68F5AD1A9660401F83Asecrethideout" 
		value="Sydney, Australia" class="" style="">
	</div>
	<br class="clearer">
	</div>

    </fieldset>

    <input type="hidden" name="BC139D3DC12AA68F5AD1A9660401F83AObjectID" 
	value="BC139D3D-C12A-A68F-5AD1A9660401F83A">
    <input type="hidden" name="BC139D3DC12AA68F5AD1A9660401F83ATypename" 
	value="superhero">
    <input type="hidden" name="FarcryFormPrefixes" 
	value="BC139D3DC12AA68F5AD1A9660401F83A">

    <span id="f-btn-BE7AC5F1-ED26-9DBF-49B46B4A5036804A-wrap">
	<button id="f-btn-BE7AC5F1-ED26-9DBF-49B46B4A5036804A" 
		name="FarcryFormsubmitButton=Save" 
		type="submit" value="Save" class="f-btn-text">Save</button>
    </span>
    <span id="f-btn-BE7AC5FA-9506-5268-D038424D119EAD9A-wrap">
	<button id="f-btn-BE7AC5FA-9506-5268-D038424D119EAD9A" 
		name="FarcryFormsubmitButton=Cancel" 
		type="submit" value="Cancel" class="f-btn-text">Cancel</button>
    </span>

    <input type="hidden" name="FarcryFormPrefixes" value="">
    <input type="hidden" name="FarcryFormSubmitButton" id="FarcryFormSubmitButton" value="">
    <input type="hidden" name="FarcryFormSubmitButtonClickedfarcryForm590063094" 
	id="FarcryFormSubmitButtonClickedfarcryForm590063094" class="fc-button-clicked" value="">
    <input type="hidden" name="FarcryFormSubmitted" value="farcryForm590063094">
    <input type="hidden" name="SelectedObjectID" class="fc-selected-object-id" value="">
    <input type="hidden" name="farcryFormValidation" id="farcryFormValidationfarcryForm590063094" value="1">

</form>

Walkthrough: Building a Super Hero Custom Edit Form

We are going to create a simple custom edit form for our Super Hero content type. You will remember that the system will look for a webskin edit.cfm when editing a content type. If it can't find one, it will build the form dynamically based on the metadata. In this walkthrough, we are going to create the edit.cfm to override the default behaviour.

  1. Create a new file projectName/webskin/superHero/edit.cfm
  2. Paste the following code into the new file
    <cfsetting enablecfoutputonly="true" />
    <!--- @@displayname: Super Hero Edit --->
    
    <!--- importing Tag Libraries --->
    <cfimport taglib="/farcry/core/tags/formtools" prefix="ft" />
    
    <!--- Render the Edit Form --->
    <cfoutput><h1>Super Hero Edit Form</h1></cfoutput>
    
    <ft:form>
    
        <ft:object objectid="#stobj.objectid#" lFields="" />
    
        <ft:button value="Save" />
        <ft:button value="Cancel" validate="false" />
    
    </ft:form>
    
    <cfsetting enablecfoutputonly="false" />
    
  3. Update your application to register the new edit.cfm view (i.e. Update App!)
  4. Go into the webtop and Edit a Super Hero content item
  5. Notice your new form: it is almost complete except it has not broken down the fields into fieldsets; unfortunately, we will need to do this manually, but it's not that tough
  6. Replace the current <ft:object /> tag with the following:
    <ft:object objectid="#stobj.objectid#" lFields="title,secretHideout,teaser,biography" legend="General Details" />
    <ft:object objectid="#stobj.objectid#" lFields="imgHero" legend="Imagery" />
    
  7. Reload the form and review
  8. But what if you don't like the HTML that is rendered by default? In a desperate bid for control, replace the second <ft:object /> tag with:
    <ft:object objectid="#stobj.objectid#" lFields="imgHero" legend="Imagery" r_stFields="stMyFieldInfo" />
    <cfdump var="#stMyFieldInfo#" />
    
  9. Discuss with your instructor what you see and the potential

Form Processing: Dealing with POST Events

So now we have our lovely looking form, what happens when we press the save button...? At the moment NOTHING.

This brings us to the second part of the unit: we need to process the form POST.

<!--- Form processing --->
<ft:processForm action="Save">
	<ft:processFormObjects objectid="#stobj.objectid#" />
</ft:processForm>

Here we are introduced to 2 new tags:

<ft:processForm />

This tag is used to capture an event raised by a <ft:button />. You will notice in our form we had a <ft:button value="Save" />. If someone was to click on that button, the "Save" action will be raised and will be captured by the <ft:processForm action="save" /> tag. Any code inside of the tag will only be run IF the [Save] button is pressed.

<ft:processFormObjects />

This is where the action is at. This tag does all the heavy lifting... well saving anyway. This tag says to the framework: if any fields belonging to an object with the objectid of "#stobj.objectid#" has been submitted by a FarCry form, then save the values of those fields to the object in the database.

So lets put it all together.

Walkthrough: Saving the Super Hero

  1. Paste the following code below the <cfimport /> tag but above our form:
    <!--- Form processing --->
    <ft:processForm action="Save">
    	<ft:processFormObjects objectid="#stobj.objectid#" />
    </ft:processForm>
    
  2. Now go and edit a Super Hero and this time when you press Save, notice that your data has, in fact, been saved
  3. Great, but when we hit Save or Cancel, we don't actually just want to keep refreshing the page; we need it to exit out to where we came from or wherever the calling page tells us to go
  4. Paste the following code below our current <processForm /> tag
    <ft:processForm action="Save,Cancel" exit="true" />
    
  5. Now go and save your Super Hero and see what happens

Bonus Lab: Building Forms in the Front End

In addition to changing the default behaviour of forms in the webtop, its also possible to build forms using formtools directly in the front end of your website.

  • Build a type webskin listing content items of a particular type
  • Put in an "ADD" button and link to a type webskin for adding new content (eg. displayTypeAdd.cfm)
  • Create a temporary session object using the "key" attribute so you don't have to create a database record every time someone just views the form
  • Call a custom edit handler to update the new record
  • Process the form POST and redirect the user to your type listing page