-
Notifications
You must be signed in to change notification settings - Fork 24
The Form Tag Library
- Overview
- Enhanced
event-bean
Command - Configuration and Using the Form Library
- Common Questions About the Form Tag Library
- A Word About Auto-Generated ID Attribute Values
- Standard Attributes, Event Attributes and Custom Attributes Reference
- Additional Information and Considerations
The Mach-II form tag library is an comprehensive set of data binding aware custom CFML tags that produce HTML form elements. Each tag supports all corresponding HTML form element attributes in an familiar and intuitive to use manner. The generated output of each tag is HTML 4.01/XHTML 1.0 compliant. The form tag library was introduced in Mach-II Simplicity (1.8+).
The big difference between other form tag libraries and the Mach-II form tag library is that our library is integrated and designed to work with Mach-II request workflow. This gives our library access to Mach-II related functionality in addition to reducing the effort involved in making an user friendly HTML form. As you will see in the following examples, the form tag library makes developing views with forms easier to develop, maintain and ultimately read when editing code. In the future, this library will integrate with our planned validation framework (which will be independent from the MVC component of Mach-II just like caching and logging) and will provide seamless integration between client and server side validation.
Since illustrated examples are the most convincing, let's look through the library with corresponding HTML output.
We are also developing an enhanced event-bean
command with nested inner-bean
and field
tags. This allows you to populate nested beans (beans of composition) and directly integrates with the form tag library. Check out Event-Beans: Event more fruitier for more information. The event-bean
enhancement was developed off a concept submitted by a community member through our call for features program. Just proves that at Mach-II - we're community driven.
The form library is basically a collection of CFML custom tags. Utilizing it in Mach-II views is as simple as adding an tag library import directive to the top each view that uses the library:
<cfimport prefix="form" taglib="/MachII/customtags/form" />
We indicated that we will use the "form" prefix in all of our tags. More on this later.
Due to the fact that CFML engines import tag libraries at the time .cfm files are compiled, the Mach-II framework cannot "magically" include the library for you on each page.
This tag renders a HTML <form>
tag and sets a bind location so that all nested form library tags can bind to an object or the Mach-II event object automatically dynamically at runtime. It is ok if this does not make complete sense at the moment as you will see data binding in action shortly.
For the sake of having a concrete example, lets build a form that models an User
bean. Some attributes of User
are firstName
, lastName
, birthDate
, favoriteSeason
, favoriteHoliday
and favoriteColors
. Our User
has all the corresponding getters/setters that model those attributes. Let's take a peek at our form if we just ask for first and last names:
<cfimport prefix="form" taglib="/MachII/customtags/form" />
<form:form actionEvent="processUser" bind="user">
<h4>First Name</h4>
<p><form:input path="firstName" /></p>
<h4>Last Name</h4>
<p><form:input path="lastName" /></p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Notices that our form
tag has two attributes. The actionEvent
attribute indicates the event name our form will post to and the bind
attribute is telling the library that we want to use the User
bean that is currently in the Mach-II Event object. Let's pretend that our User
bean already has the first name of Bella
and the last name of Swan
already in the bean. This is the HTML the form library would generate:
<form method="post" encType="multipart/form-data" action="index.cfm?event=processUser">
<h4>First Name</h4>
<p><input id="firstName" value="Bella" type="text" name="firstName"/></p>
<h4>Last Name</h4>
<p><input id="lastName" value="Swan" type="text" name="lastName"/></p>
<p><input type="submit" value="Save Changes" /></p>
</form>
As you can see, we did not have to do the tedious process having to manually get data from our user bean among other things. This is an error-prone process and hard to maintain. This is what our source code would look like if we had to do everything manually:
<form method="post" encType="multipart/form-data" action="#BuildUrl('processUser')#">
<h4>First Name</h4>
<p><input id="firstName" value="#event.getArg('user').getFirstName()#" type="text" name="firstName"/></p>
<h4>Last Name</h4>
<p><input id="lastName" value="#event.getArg('user').getLastName()#" type="text" name="lastName"/></p>
<p><input type="submit" value="Save Changes" /></p>
</form>
Currently, the bind
attribute of the form tag allows for three different ways to provide a bind for the form.
- Simple dot path shortcut -- ex.
bind="user"
is equivalent shortcut to the M2 EL syntax ofbind="${event.user}"
- M2 EL syntax - ex.
bind="${event.user}"
orbind="${event.user.address}"
(added in after the release of Mach-II 1.8 Beta 1) - Pass in a bean directly using CFML -- ex.
bind="#variables.someBean#"
(added in after the release of Mach-II 1.8 Beta 1)
A few notes to be aware of:
- If you do not specify the
bind
attribute, theform
tag will try to bind to the Mach-II Event object. - If you need to bind to multiple beans that are not in a single bean composition hierarchy (i.e.
User
has anAddress
), you will need to use thebind
tag which allows for multiple bind contexts in a single form. See more information below.
By default, the form will auto-focus the user cursor to the first form field in the form. This feature can by programmatically turned off or set to a different field id
. If two forms exists on the page, the first form will get the auto-focus unless it is turned off. Best of all, this feature gracefully degrades if javascript is not enabled in the browser.
Setting the auto-focus to focus on a different element
This is easy to accomplish by indicating the id
that the form should focus to by using the autoFocus
attribute of the form
tag. In this example, we are focusing to the last form element (lastName
) in the form:
<cfimport prefix="form" taglib="/MachII/customtags/form" />
<form:form actionEvent="processUser" bind="user" autoFocus="lastName">
<h4>First Name</h4>
<p><form:input path="firstName" /></p>
<h4>Last Name</h4>
<p><form:input path="lastName" /></p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Disabling auto-focus on a form
Sometimes more than one form will exist on the final output to a browser. Most commonly this might be a login form that exists at in the page header. Usually you will not want to auto-focus the user input to this form all the time. To disable auto-focus for a particular form, just use a boolean value (i.e. false
or 0
) in the autoFocus
attribute:
<cfimport prefix="form" taglib="/MachII/customtags/form" />
<form:form actionEvent="processUser" bind="user" autoFocus="false">
<h4>First Name</h4>
<p><form:input path="firstName" /></p>
<h4>Last Name</h4>
<p><form:input path="lastName" /></p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Name | Required | Default | Description |
---|---|---|---|
actionEvent | true | n/a | Name of event to process this form. |
actionModule | false | name of current module | Name of module to use with the event to process this form. |
actionUrlParams | false | none | Name value pairs in pipe ( |
autoFocus | false | defaults to first form element id | By default, the form will auto-focus to the first form element. You can provide an id of another element in this attribute to auto-focus to something other than the default. Providing a value of false or 0 disables auto-focus on the form entirely. |
encType | false | multipart/form-data |
Specifies the encType of the form. |
method | false | post |
Specifies the type of form post to make (get or post). |
bind | false | Mach-II Event object | Specifies the name of the event arg to try to bind to. |
p | optional | n/a | Name / value pair list or struct of URL parameters to build the URL with. Use the p namespace (see custom attributes. |
q | optional | n/a | Name / value pair list or struct of query string parameters to append to the end of a route (only valid with route ). Use the q namespace (see custom attributes
|
x | optional | n/a | Name / value pair list or struct of additional non-standard attribute to insert into the rendered tag output. Use the p namespace (see custom attributes. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported. Additional supported event attributes are onsubmit()
and onreset()
. Please remember that event attribute such as onclick
are supported in our implementation (as they are part of the W3C specifications) however they are not much use since a form
tag does not get any direct user interaction.
This tag renders an HTML input
tag with the type of text
. We've seen it in action already in the previous section, however this tag supports all attributes that our HTML counterpart supports.
The path
attribute is the magic behind the tag. It transverses a given path that could be a nested set of beans. For example, if our User
bean had an Address
bean inside of it all you needed to do is this:
<form:form actionEvent="processUser" bind="user">
<h4>First Name</h4>
<p><form:input path="firstName" /></p>
<h4>Last Name</h4>
<p><form:input path="lastName" /></p>
<h4>State</h4>
<p><form:input path="address.state" /></p>
<h4>Zip Code</h4>
<p><form:input path="address.zipCode" /></p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
The path
attribute takes a dot path in which it uses to obtain the value. For example, the path of address.state
in the above code would equal to event.getArg('user').getAddress().getState()
. So using the above source code, the following would generate this HTML output provided that the getters for state and zip code returned WA
and 98331
respectively:
<form method="post" encType="multipart/form-data" action="index.cfm?event=processUser">
<h4>First Name</h4>
<p><input id="firstName" value="Bella" type="text" name="firstName"/></p>
<h4>Last Name</h4>
<p><input id="lastName" value="Swan" type="text" name="lastName"/></p>
<h4>State</h4>
<p><input id="address.state" value="WA" type="text" name="address.state"/></p>
<h4>Zip Code</h4>
<p><input id="address.zipCode" value="98331" type="text" name="address.zipCode"/></p>
<p><input type="submit" value="Save Changes" /></p>
</form>
As you can see, the name
attribute value was generated based off the last value of the dot path. However, there are certain situations where you want the data binding provided by the form library but need to explicitly set the form element name.
<form:input path="firstName" />
<form:input path="firstName" name="fName" />
Defining the a path
without a name
attributes causes the tag to automatically generate a name based off the path. However on the second line, we are still using the data binding, but we are explicitly setting the name of the input to fName
. Also, the form library automatically sets the value of the id
of the form element to the same value as the name
if you do not define an id
attribute.
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
value | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The value to use. |
disabled | false | ||
readonly | false | false (takes boolean) | Set to true to make the form element read only. |
maxlength | false | attribute is not set if not defined (takes numeric) | Sets the maximum input length of the form element. |
size | false | attribute is not set if not defined (takes numeric) | Sets the size of the form element. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag renders an HTML input
tag with the type of button
, reset
, submit
, or image
depending on the type and attributes provided. The button
tag supports the path
attribute for data binding as do all the form custom tags. Here is a simple example of the button
tag being used as a submit button in a form with the name
and value
attributes being explicitly provided. As with other form tags, if a path
attribute is provided, this will set the name
, value
, and id
attributes of the HTML input tag.
<form:form actionEvent="processUser" bind="user">
<p><form:button name="submit" value="Save Changes" /></p>
</form:form>
This produces the following HTML output:
<form method="post" action="index.cfm?event=processUser">
<p><input type="submit" name="submit" value="Save Changes" /></p>
</form>
Note that if a type
attribute is not provided in the button
tag, the type will default to submit
. Types of button
and reset
are also supported.
An input type of image
is also supported, and as in HTML, this will always be a submit button. To render an image as a submit button, simply include the src
attribute in the button tag.
<form:form actionEvent="processUser" bind="user">
<p><form:button src="/path/to/image.gif" name="submit" value="Save Changes" /></p>
</form:form>
If you provide a type other than submit
in addition to providing the src
attribute, an exception will be thrown.
The image
input type also supports an alt
attribute, and if this is not provided the value
attribute is used as the value of alt
.
If you are using the HtmlHelperProperty
, you can use the same shortcut paths for images with the addition of asset timestamps that the property offers. If you have not defined the HtmlHelperProperty
, a full web path to the image for the button must be defined.
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
value | false (use if no path is defined of custom element value is required) |
value from path
|
The value of the input tag. This is also used as the alt attribute for image inputs if alt is not provided. |
type | false | submit |
The type of button. Valid values are button , reset , and submit . |
src | false | n/a | The path to an image to use for the button. This results in an HTML input type of image . Image inputs will always acts as submit buttons. |
alt | false | n/a | The alt text to associate with an image input. |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag renders an HTML input
tag with the type of checkbox
. Let's continue with the premise outlined above and let the user select their favorite colors.
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, etc. --->
<h4>Your Favorite Colors</h4>
<p><form:checkbox path="favoriteColors" value="red"/> Red</p>
<p><form:checkbox path="favoriteColors" value="green"/> Green</p>
<p><form:checkbox path="favoriteColors" value="blue"/> Blue</p>
<p><form:checkbox path="favoriteColors" value="yellow"/> Yellow</p>
<p><form:checkbox path="favoriteColors" value="pink"/> Pink</p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Which produces HTML output like this:
<form method="post" encType="multipart/form-data" action="index.cfm?event=processUser">
<p>
<input id="favoriteColor_red" value="red" type="checkbox" name="favoriteColors"/>
<input name="_-_favoriteColors" type="hidden" value="" /> Red
</p>
<p>
<input id="favoriteColor_green" value="green" type="checkbox" name="favoriteColors"/>
<input name="_-_favoriteColors" type="hidden" value="" /> Green
</p>
<p>
<input id="favoriteColor_blue" value="blue" type="checkbox" name="favoriteColors"/>
<input name="_-_favoriteColors" type="hidden" value="" /> Blue
</p>
<p>
<input id="favoriteColor_yellow" value="yellow" type="checkbox" name="favoriteColors"/>
<input name="_-_favoriteColors" type="hidden" value="" /> Yellow
</p>
<p>
<input id="favoriteColor_pink" value="pink" type="checkbox" name="favoriteColors"/>
<input name="_-_favoriteColors" type="hidden" value="" /> Pink
</p>
<p><input type="submit" value="Save Changes" /></p>
</form>
As you can see, the name of the checkbox elements has been generated of the path and the id (which must be unique) was generated off the name attribute value plus the data in the value attribute. The checkbox form tag will also auto-check an element if the value is in the list of values in the specified path.
The data binding for the checkbox
tag is not case sensitive.
You might have noticed that the above are the hidden fields after each checkbox element. This is because HTML has a quirk in it. When a checkbox is not checked, the value is not part of the form post that the web browser sends to the server. We use the hidden field to indicate to Mach-II that checkbox was on the HTML page and that all elements were "unchecked" when we do the data binding on the server side. We use the convention of prefixing the hidden field's name with one underscore, one dash and finally one underscore (_-_
) and then fellowed by the full name of the checkbox. This lets Mach-II know that a checkbox was visible in the form and that you want to bind a value to object on the other side (using <event-bean>
) and to reflect the state of the checkbox whether or not the web browser posted the checkbox (because it was unchecked).
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
value | false (use if no path is defined) |
value from path
|
The value of the checkbox |
checked | false | n/a | Explicitly checks the checkbox (boolean) |
checkValue | false | n/a | The current value of the target to try to match against the value if data binding is not being use with the path attribute (Uses ListFindNoCase for lists). |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
The checkboxGroup
tag renders multiple HTML input
tags with the type of checkbox
and corresponding formatting / display information. Compared with the single checkbox
tag above, the checkboxGroup
tag allows for simpler syntax in the generation of multiple checkbox
inputs.
For example, the checkbox
sample code from above:
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, etc. --->
<h4>Your Favorite Colors</h4>
<p><form:checkbox path="favoriteColors" value="red"/> Red</p>
<p><form:checkbox path="favoriteColors" value="green"/> Green</p>
<p><form:checkbox path="favoriteColors" value="blue"/> Blue</p>
<p><form:checkbox path="favoriteColors" value="yellow"/> Yellow</p>
<p><form:checkbox path="favoriteColors" value="pink"/> Pink</p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Would be written as follows using the checkboxGroup
tag:
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, etc. --->
<h4>Your Favorite Colors</h4>
<form:checkboxGroup path="favoriteColors" items="red,green,blue,yellow,pink">
<p>${output.checkbox} <label for="${output.id}">${output.label}</label></p>
</form:checkboxGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
As you can glean from this example, the checkboxGroup
tag loops over a collection and outputs a group of checkbox inputs. Let's look at each attribute of the checkboxGroup
tag and how the output works.
The path
attribute functions as with all the form tags. Since the form is bound to user
, the attribute favoriteColors
of user
will determine which checkbox inputs are checked. Since no name
attribute is provided, favoriteColors
will also be the name of each checkbox input. The name
and path
attribute may both be provided if you want the name of the checkbox inputs to be different than the name of the CFC attribute to which the selected value is bound.
Two separate attributes, items
and labels
, are used to indicate the value and display label for each checkbox input. The items
and labels
attributes may be one of the following data types:
- A list. You may specify the list delimiter by using the
delimiter
attribute of thecheckboxGroup
tag (comma is used as a default). - A struct. If a struct is provided the struct key is used as the value for the checkbox input, with the struct value being used as the label for the checkbox input. Note that if a struct is provided as the
items
attribute thelabels
attribute is redundant and therefore is ignored if provided. You can control the sorting of the struct (since structs are unordered datatypes) via thedisplayOrder
attribute. - One-dimensional array with simple values (e.g. strings) as the array elements.
- One-dimensional array of structs, with struct keys named
label
(default or configured vialabelKey
attribute) andvalue
(default or configured viavalueKey
attribute) in each struct. - A query. If a query is provided for
items
and contains query columns oflabel
andvalue
, those will be used as the label and value for each checkbox input. If the query does not contain columns namedlabel
andvalue
, thelabelCol
andvalueCol
attributes of thecheckboxGroup
tag must be provided. As with the struct example outlined above, if a query object is used as theitems
attribute, thelabels
attribute is redundant and therefore is ignored if provided.
Note that if both the items
and labels
attributes are provided they must be of the same data type.
The items
attribute is required, and is used to indicate the value used for each member of the checkbox group. Items can of course be dynamic (e.g. items="#myVar#"
), and if a labels
attribute is not provided the item values are used as the checkbox input labels as well.
The labels
attribute, which is omitted in the example above, may be provided when a list or one-dimensional array containing simple values is used as the items
attribute. To reiterate what was stated above, if items
and labels
are both provided, they must be of the same data type. Review the bullet list of data types above for cases in which labels
is ignored.
Note the special syntax for outputting the checkbox, label tag, and label text. Rather than the checkboxGroup
tag pre-determining the formatting of the output, the use of ${output}
style syntax allows you to control the HTML output generated by the checkboxGroup
tag. This functions as follows:
-
${output.checkbox}
is the checkbox tag itself, which includes the name and value of the checkbox. -
${output.id}
is the HTML ID for the checkbox. This is generated automatically by thecheckboxGroup
tag and follows the formatnameOfCheckboxGroup_HTMLSafeVersionOfValue
. -
${output.label}
is the label to display for the checkbox input.
The following data types are supported as either the path
value or the checkValue
attribute, which indicates the checkboxes in the group to be checked:
- A list. You may use a delimiter other than a comma (the default) by providing a
delimiter
attribute to thecheckboxGroup
tag, but note that only onedelimiter
attribute is supported so if you are also supplyingitems
orvalues
as a list and using a deilmiter other than a comma, the delimiter must match between thecheckValue
attribute and other lists being used as tag attributes. - A struct. In the struct used for the
checkValue
attribute, the key is the value to match against the item list, and the value of the struct key should be set to a boolean (true or false) to indicate whether or not the checkbox with the corresponding value of the struct key should be checked. Note that since the default for the value of checked is false, you do not have to provide anything in the struct other than the values you wish to be checked. - A one-dimensional array of simple values.
- A query. You must indicate the column name using the
checkValueCol
attribute to use to build the list of check values.
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name attribute is used) |
n/a | The path in the bound object that determines the checked values in the checkbox group. |
name | false (use if no path is defined or if a custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
items | true | n/a | The values to use as the values and optionally display labels for the checkboxes. The values in items are used as labels if the labels attribute is not provided |
labels | false (values in items are used as labels if labels is not provided) |
n/a | The labels to use with the checkboxes. If both items and labels are provided they must be the same data type. |
checkValue | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The values of the checkbox inputs that will have their checked attributes set to true
|
checkValueCol | false | n/a | If checkValue is a query, use this attribute to indicate the query column name to use to build the check value list. |
delimiter | false (may be used if items and optionally labels is a list) |
comma | The delimiter used in the list provided as the items (and optionally labels and checkValue ) attributes. Note that if items is used with either labels or checkValue (or both), and these are all lists, they must use the same delimiter. |
labelCol | false | label | If items is a query, the query column to use as the label for the checkboxes. |
valueCol | false | value | If items is a query, the query column to use as the value for the checkboxes. |
labelKey | false | label | If items is an array of structs, the key name to use as the label for the checkboxes. |
valueKey | false | value | If items is an array of structs, the key name to use as the value for the checkboxes. |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
displayOrder | false | Takes a list or array | Used to control the display order when a struct is passed to the items attributes. Indicate a list or array or key names in order to display. Use * to indicate all keys minus any other key that is indicated in the list. |
This tag renders an HTML input
tag with the type of radio
. Continuing with our example, let's show how an user could select his/her favorite season of the year.
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<p><form:radio path="favoriteSeason" value="Winter"/> Winter</p>
<p><form:radio path="favoriteSeason" value="Spring"/> Spring</p>
<p><form:radio path="favoriteSeason" value="Summer"/> Summer</p>
<p><form:radio path="favoriteSeason" value="Autumn"/> Autumn</p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Which produces HTML output like this:
<form method="post" encType="multipart/form-data" action="index.cfm?event=processUser">
<p><input id="favoriteSeason_Winter" value="Winter" type="radio" name="favoriteSeason"/> Winter</p>
<p><input id="favoriteSeason_Spring" value="Spring" type="radio" name="favoriteSeason"/> Spring</p>
<p><input id="favoriteSeason_Summer" value="Summer" type="radio" name="favoriteSeason"/> Summer</p>
<p><input id="favoriteSeason_Autumn" value="Autumn" type="radio" name="favoriteSeason"/> Autumn</p>
<p><input type="submit" value="Save Changes" /></p>
</form>
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element |
value | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The value to use. |
checked | false | n/a | Explicitly checks the checkbox (boolean) |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
size | false | attribute is not set if not defined (takes numeric) | Sets the size of the form element. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
The radioGroup
tag renders multiple HTML input
tags with the type of radio
and corresponding formatting / display information. Compared with the single radio
tag above, the radioGroup
tag allows for simpler syntax in the generation of multiple radio
inputs.
For example, the radio
sample code from above in which we use the seasons of the year:
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<p><form:radio path="favoriteSeason" value="Winter"/> Winter</p>
<p><form:radio path="favoriteSeason" value="Spring"/> Spring</p>
<p><form:radio path="favoriteSeason" value="Summer"/> Summer</p>
<p><form:radio path="favoriteSeason" value="Autumn"/> Autumn</p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Using a list for the data, the example would be written as follows using the radioGroup
tag:
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="Winter,Spring,Summer,Autumn">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
As you can glean from this example, the radioGroup
tag loops over a collection and outputs a group of radio inputs. Let's look at each attribute of the radioGroup
tag and how the output works.
The path
attribute functions as with all the form tags. Since the form is bound to user
, the attribute favoriteSeason
of user
will determine which radio input is checked. Since no name
attribute is provided, favoriteSeason
will also be the name of each radio input. The name
and path
attribute may both be provided if you want the name of the radio inputs to be different than the name of the CFC attribute to which the selected value is bound.
Formatting Template
Note the special syntax (formatting template) outputting the radio button, label tag, and label text. Rather than the radioGroup
tag pre-determining the formatting of the output, the use of ${output}
style syntax allows you to control the HTML output generated by the radioGroup
tag. This functions as follows:
-
${output.radio}
is the radio input tag itself, which includes the name and value of the radio input. -
${output.id}
is the HTML ID for the radio input. This is generated automatically by theradioGroup
tag and follows the formatnameOfRadioGroup_HTMLSafeVersionOfValue
. -
${output.label}
is the label to display for the radio input.
Two separate attributes, items
and labels
, are used to indicate the value and display label for each radio input. The items
and labels
attributes may be one of the following data types:
You may specify the list delimiter by using the delimiter
attribute of the radioGroup
tag (comma is used as a default).
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="Winter,Spring,Summer,Autumn">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
In this example, both the radio value and the label are the same. If we wanted to change that, we could use the labels
attribute which matches by list position with the items
attribute:
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="1,2,3,4" labels="Winter,Spring,Summer,Autumn">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
This would produce:
<form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<p><form:radio path="favoriteSeason" value="1"/> Winter</p>
<p><form:radio path="favoriteSeason" value="2"/> Spring</p>
<p><form:radio path="favoriteSeason" value="3"/> Summer</p>
<p><form:radio path="favoriteSeason" value="4"/> Autumn</p>
<p><input type="submit" value="Save Changes" /></p>
<form>
If a struct is provided the struct key is used as the value for the radio input, with the struct value being used as the label for the radio input. Note that if a struct is provided as the items
attribute the labels
attribute is redundant and therefore is ignored if provided. You can control the sorting of the struct (since structs are unordered datatypes) via the displayOrder
attribute.
<cfset variables.seasons = StructNew() />
<cfset variables.seasons["1"] = "Winter" />
<cfset variables.seasons["2"] = "Spring" />
<cfset variables.seasons["3"] = "Summer" />
<cfset variables.seasons["4"] = "Fall" />
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="#variables.seasons#">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
This would put the following using the keys (alpha-numeric ASC are the sort order):
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<p><form:radio path="favoriteSeason" value="1"/> Winter</p>
<p><form:radio path="favoriteSeason" value="2"/> Spring</p>
<p><form:radio path="favoriteSeason" value="3"/> Summer</p>
<p><form:radio path="favoriteSeason" value="4"/> Autumn</p>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
If we wanted to sort the struct by seasons in reverse, we could defined a sort order using displayOrder="4,3,2,1"
. This attributes takes a list or array of struct key names. See the tag attribute table for more information on using this attribute.
One-dimensional arrays with simple values (e.g. strings) as the array elements. This will use the array element value for both the radio button value and label.
<cfset variables.seasons = ArrayNew(1) />
<cfset ArrayAppend(variables.seasons, "Winter") />
<cfset ArrayAppend(variables.seasons, "Spring") />
<cfset ArrayAppend(variables.seasons, "Summer") />
<cfset ArrayAppend(variables.seasons, "Fall") />
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="#variables.seasons#">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
The one-dimensional array of structs allows you control the order with each struct having the keys named label
(default or configurable via labelKey
attribute) and value
(default or configurable via the valueKey
attribute) in each struct.
<cfset variables.seasons = ArrayNew(1) />
<cfset ArrayAppend(variables.seasons, [value:1, label:'Winter']) />
<cfset ArrayAppend(variables.seasons, [value:2, label:'Spring']) />
<cfset ArrayAppend(variables.seasons, [value:3, label:'Summer']) />
<cfset ArrayAppend(variables.seasons, [value:4, label:'Fall']) />
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="#variables.seasons#">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
If a query is provided for items
and contains query columns of label
and value
, those will be used as the label and value for each radio input. If the query does not contain columns named label
and value
, the labelCol
and valueCol
attributes of the radioGroup
tag must be provided. As with the struct example outlined above, if a query object is used as the items
attribute, the labels
attribute is redundant and therefore is ignored if provided.
<!--- This query has columns 'id' and 'name' where the the 'name' is the name
of the season and the 'id' is the unique database row id. --->
<cfset variables.seasons = "QUERY HERE" />
<form:form actionEvent="processUser" bind="user">
<!--- firstName, lastName, favoriteColors, etc. --->
<h4>Your Favorite Season of the Year</h4>
<form:radioGroup path="favoriteSeason" items="#variables.seasons#" valueCol="id" labelCol="name">
<p>${output.radio} <label for="${output.id}">${output.label}</label></p>
</form:radioGroup>
<p><input type="submit" value="Save Changes" /></p>
</form:form>
Note that if both the items
and labels
attributes are provided they must be of the same data type.
The items
attribute is required, and is used to indicate the value used for each member of the radio group. Items can of course be dynamic (e.g. items="#myVar#"
), and if a labels
attribute is not provided the item values are used as the radio input labels as well.
The labels
attribute, which is omitted in the example above, may be provided when a list or one-dimensional array containing simple values is used as the items
attribute. To reiterate what was stated above, if items
and labels
are both provided, they must be of the same data type. Review the bullet list of data types above for cases in which labels
is ignored.
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name attribute is used) |
n/a | The path in the bound object that determines the checked value in the radio group. |
name | false (use if no path is defined or if a custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
items | true | n/a | The values to use as the values and optionally display labels for the radio inputs. The values in items are used as labels if the labels attribute is not provided |
labels | false (values in items are used as labels if labels is not provided) |
n/a | The labels to use with the radio inputs. If both items and labels are provided they must be the same data type. |
checkValue | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The value of the radio input that will have its checked attribute set to true
|
delimiter | false (may be used if items and optionally labels is a list) |
comma | The delimiter used in the list provided as the items (and optionally labels ) attributes. Note that if both items and labels are lists they must use the same delimiter. |
labelCol | false | label | If items is a query, the query column to use as the label for the radio inputs. |
valueCol | false | value | If items is a query, the query column to use as the value for the radio inputs. |
labelKey | false | label | If items is an array of structs, the key name to use as the label for the radio inputs. |
valueKey | false | value | If items is an array of structs, the key name to use as the value for the raido inputs. |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
displayOrder | false | Takes a list or array | Used to control the display order when a struct is passed to the items attributes. Indicate a list or array or key names in order to display. Use * to indicate all keys minus any other key that is indicated in the list. |
This tag renders an HTML input
tag with the type of password
. By the default, the value is not used to pre-populate the form. If you need to pre-populate the value, use the showPassword
attribute set to true
.
<form:password path="password" />
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
value | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The value to use. |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
readonly | false | false (takes boolean) | Set to true to make the form element read only. |
maxlength | false | attribute is not set if not defined (takes numeric) | Sets the maximum input length of the form element. |
size | false | attribute is not set if not defined (takes numeric) | Sets the size of the form element. |
showPassword | false | false | By default, the password value is not shown. If you want to pre-populate the password value, set the showPassword to true. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag renders an HTML input
tag with the type of file
. Due to security restrictions with file
inputs the value attribute cannot be used to set the value of the input. Path binding may be used, however, and will populate the name
and id
attributes.
<form:file path="filename" />
When the file
tag is used in a form, the enctype
of the form is automatically set to multipart/form-data (1.9+)
.
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object that will be used as the input's name and id attributes |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
readonly | false | false (takes boolean) | Set to true to make the form element read only. |
maxlength | false | attribute is not set if not defined (takes numeric) | Sets the maximum input length of the form element. |
size | false | attribute is not set if not defined (takes numeric) | Sets the size of the form element. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
In order to more easily facilitate file uploads, in addition to the file
form tag, a new fileUpload()
function has been added to Mach-II. This function is available in any CFC that extends a Mach-II component. The uploadFile()
function takes all the attributes of the CFFILE
tag, and actually is a convenient wrapper around CFFILE
that allows for better integration of file uploads into Mach-II.
The syntax is as follows:
uploadFile("form field", "destination directory", "name conflict action", "accept", "mode", "attributes")
Only the form field and destination directory are required. All optional attributes default to the same values as the CFFILE
tag itself.
The uploadFile()
function returns a struct containing the results of the CFFILE
tag's execution. This is the exact same struct that is set to the result
attribute when using CFFILE
directly.
Let's look at an example of using both the file
tag and the uploadFile()
function. You might have a form as follows:
<form:form actionEvent="uploadFile">
<form:file name="theFile" /><br />
<form:button value="Upload" />
</form:form>
Assuming the uploadFile
event notifies a listener and calls the method processFileUpload
, the listener method might look like this:
<cffunction name="processFileUpload" access="public" output="false" returntype="void">
<cfargument name="event" type="MachII.framework.Event" required="true" />
<cfset var uploadResults = uploadFile("theFile", ExpandPath("/"), "overwrite", "application/msword") />
</cffunction>
This would upload the file contained in the form field theFile
(note that you do not call arguments.event.getArg("theFile")
but refer to the form field name directly) and return the struct that is generated by the CFFILE
tag. In this case the name conflict action is set to overwrite
, and the accept
attribute has been set to only accept Microsoft Word files as the uploaded file.
As of Mach-II Integrity (1.9.0), the accept
attribute accepts a list of mixed file extensions (which must start with a dot) and/or MIME types:
<cfset var uploadResults = uploadFile("theFile", ExpandPath("/"),
"overwrite", ".jpg,.gif,.pdf,application/msword") />
Keep in mind that the uploadFile
function simply provides a convenience wrapper to the CFFILE
tag and does not provide any additional security enhancements to the CFFILE
tag. It is still the responsibility of the individual developer to protect their systems from script attacks via CFFILE
as described in articles such as this, and to handle the deletion and removal of invalid or unacceptable files once they are uploaded to the server via the uploadFile
function.
This tag renders an HTML select
tag. This tag supports rendering option
tags by passing data in via an items
attribute. You can also nesting option
or options
tags within the select
tag. The details of these additional tags are discussed further down in this documentation document.
Let's continue with our example, let's say we have a struct of holidays where the key name will be used as the option value and key value will be used as the option label.
<cfset variables.seasons = {
easter="Easter",
valentines="Valentine's Day",
independenceDay="Fourth of July"
} />
<form:select path="favoriteHoliday" items="#variables.seasons#">
<form:option value="-" label="Choose a holiday" />
</form:select>
This produces the following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_easter" value="easter">Easter</option>
<option id="favoriteHoliday_independenceday" value="independenceday">Fourth of July</option>
<option id="favoriteHoliday_valentines" value="valentines">Valentine's Day</option>
</select>
As you can see, we passed the select
tag a struct of options. Using a struct can cause the order of the options in a random order so they will be sorted alphanumerically.
You can also pass it an array or list. If you use an array or list, the each array/list element will be used for the option value and label. The options will be generated in the order they are defined in the array or list. See the options
tag for more ideas on what you can do with the items
attribute. The item
attribute is a shortcut for a nested options
tag so see the options
tag for complete documentation on attributes and configuration options/examples.
We recommend that if you use a "please select an option" value in the drop down that you use -
(dash) as a value by default.
The following data types are supported as either the path
value or the checkValue
attribute, which indicates the option(s) in the group to be selected:
- A list. You may use a delimiter other than a comma (the default) by providing a
delimiter
attribute to theselect
tag, but note that only onedelimiter
attribute is supported so if you are also supplyingitems
orvalues
as a list and using a deilmiter other than a comma, the delimiter must match between thecheckValue
attribute and other lists being used as tag attributes. - A struct. In the struct used for the
checkValue
attribute, the key is the value to match against the item list, and the value of the struct key should be set to a boolean (true or false) to indicate whether or not the checkbox with the corresponding value of the struct key should be checked. Note that since the default for the value of checked is false, you do not have to provide anything in the struct other than the values you wish to be checked. You can control the sorting of the struct (since structs are unordered datatypes) via thedisplayOrder
attribute. - A one-dimensional array of simple values.
- A query. You must indicate the column name using the
checkValueCol
attribute to use to build the list of check values.
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the checkValue is automatic if path attribute is defined). |
checkValue | false (use when name is defined |
zero-length string | The value to check each option against for auto-binding. Only use with name attribute and not valid with path attribute. |
checkValueCol | false | ||
multiple | false | false (takes boolean) | Set to true to allow multiple selections. |
readonly | false | false (takes boolean) | Set to true to make the form element read only. |
size | false | attribute is not set if not defined (takes numeric) | Sets the size of the form element. |
items | false | n/a | Takes a struct, array or list of options to generate (if struct, they will be sorted alphanumerically). |
labelCol | false | label |
The name of the query column to use when using a query datatype for the options items. Defaults to label as the query column unless specified. |
valueCol | false | value |
The name of the query column to use when using a query datatype for the options items. Defaults to value as the query column unless specified. |
labelKey | false | label | If items is an array of structs, the key name to use as the label for the options items. |
valueKey | false | value | If items is an array of structs, the key name to use as the value for the options items. |
delimiter | false |
, (comma) |
The delimiter to use if using a list in the items attribute. |
displayOrder | false | Takes a list or array | Used to control the display order when a struct is passed to the items attributes. Indicate a list or array or key names in order to display. Use * to indicate all keys minus any other key that is indicated in the list. |
optgroup | true | n/a | The label to apply for the optgroup around a group of options when using the items attributes. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag renders an HTML option
tag. Continuing with our example using favorite holidy, we could define each holiday separately.
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:option value="easter" label="Easter" />
<form:option value="independenceday" label="Fourth of July" />
<form:option value="valentines" label="Valentines's Day" />
</form:select>
This produces the following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_easter" value="easter">Easter</option>
<option id="favoriteHoliday_independenceday" value="independenceday">Fourth of July</option>
<option id="favoriteHoliday_valentines" value="valentines">Valentine's Day</option>
</select>
The label
attribute is optional so you could just define a value for each select. By default if no
labelis defined, the data provided in the
value` attribute is used as the option label.
Since the data in the value
attribute is used in the auto-generated id
attribute, any spaces in that data will be removed when making the id. So if the value was fourth of July
the id would be favoriteHoliday_fourthofJuly
.
Name | Required | Default | Description |
---|---|---|---|
value | true | n/a | Provides the value of the option. |
label | false | uses the data provided in the value attribute |
Sets the label to be show for the value. |
disabled | false | false (takes boolean) | Set to true to disable the form element. |
selected | false | n/a | Explicitly selects the option (boolean) otherwise the data binding will select the correct option for this select. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag renders multiple HTML option
tags and takes lists, arrays, queries and structs. This tag must be nested inside select
tag in order to work.
Let's continue with our example, let's say we have a struct of holidays where the key name will be used as the option value and key value will be used as the option label. Looping over structs does not always produce the same output order. By default, the options
tag performs a StructSort
text ascending before looping over the struct. You can control the sorting of the struct (since structs are unordered datatypes) via the displayOrder
attribute.
<cfset variables.holidays = {
easter="Easter",
valentines="Valentine's Day",
independenceDay="Fourth of July"
} />
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="#variables.holidays#" />
</form:select>
This produces the following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_easter" value="easter">Easter</option>
<option id="favoriteHoliday_independenceday" value="independenceday">Fourth of July</option>
<option id="favoriteHoliday_valentines" value="valentines">Valentine's Day</option>
</select>
Let's say we wanted Valentine's Day be the first holiday displayed, we could make use of the displayOrder
attribute. displayOrder
expects a list of key names and/or an *
. The *
is used to indicate all keys except the any other key names in the list. For example, to get Valentine's Day to be displayed first we would do this:
<cfset variables.holidays = {
easter="Easter",
valentines="Valentine's Day",
independenceDay="Fourth of July"
} />
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="#variables.holidays#" displayOrder="valentines,*" />
</form:select>
This produces the following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_valentines" value="valentines">Valentine's Day</option>
<option id="favoriteHoliday_easter" value="easter">Easter</option>
<option id="favoriteHoliday_independenceday" value="independenceday">Fourth of July</option>
</select>
For example, to get Easter to be displayed last we would do this:
<cfset variables.holidays = {
easter="Easter",
valentines="Valentine's Day",
independenceDay="Fourth of July"
} />
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="#variables.holidays#" displayOrder="*,easter" />
</form:select>
This produces the following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_valentines" value="valentines">Valentine's Day</option>
<option id="favoriteHoliday_easter" value="easter">Easter</option>
<option id="favoriteHoliday_independenceday" value="independenceday">Fourth of July</option>
</select>
Using lists is easy for options as well.
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="Easter,Valentines's Day,Independence Day" />
</form:select>
This produces this following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_Easter" value="easter">Easter</option>
<option id="favoriteHoliday_Valentines_" value="valentines">Valentine's Day</option>
<option id="favoriteHoliday_Independenceday" value="independenceday">Independence Day</option>
</select>
Using arrays is simple too! This example shows an array of simple values.
<cfset variables.holidays = ["Easter","Valentine's Day", "Independence Day" ] />
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="#variables.holidays#" />
</form:select>
This produces this following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_Easter" value="easter">Easter</option>
<option id="favoriteHoliday_Valentines_Day" value="valentines">Valentine's Day</option>
<option id="favoriteHoliday_Independenceday" value="independenceday">Independence Day</option>
</select>
We also support an array of structs. By default the label key name is label
or it can be configured via the labelKey
attribute. By default the value key name for the struct is value
or it can be configured via the valueKey
attribute.
<cfset variables.holidays = ArrayNew(1) />
<cfset temp = StructNew() />
<cfset temp.label = "Easter Sunday" />
<cfset temp.value = "Easter" />
<cfset ArrayAppend(variables.holidays, temp) />
<cfset temp = StructNew() />
<cfset temp.label = "Valentine's Day" />
<cfset temp.value = "Valentines" />
<cfset ArrayAppend(variables.holidays, temp) />
<cfset temp = StructNew() />
<cfset temp.label = "Independence Day" />
<cfset temp.value = "July4th" />
<cfset ArrayAppend(variables.holidays, temp) />
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="#variables.holidays#" />
</form:select>
This produces this following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_Easter" value="easter">Easter</option>
<option id="favoriteHoliday_Valentines" value="valentines">Valentine's Day</option>
<option id="favoriteHoliday_July4th" value="independenceday">Independence Day</option>
</select>
Got a query? It's easy as pie! Pretend that variables.holidays
has two columns called id
and season_name
. As you can see, we are indicating the column names we need for the option value and the label by using the valueCol
and labelcol
respectively.
<form:select path="favoriteHoliday">
<form:option value="-" label="Choose a holiday" />
<form:options items="#variables.holidays#" labelCol="id" valueCol="id" />
</form:select>
This produces this following output:
<select id="favoriteHoliday" name="favoriteHoliday">
<option id="favoriteHoliday_-" value="-">Choose a holiday</option>
<option id="favoriteHoliday_Easter" value="easter">Easter</option>
<option id="favoriteHoliday_Valentines_" value="valentines">Valentine's Day</option>
<option id="favoriteHoliday_Independenceday" value="independenceday">Independence Day</option>
</select>
Name | Required | Default | Description |
---|---|---|---|
items | true | n/a | Takes a struct, array, query or list of options to generate (if struct, they will be sorted alphanumerically). |
delimiter | false |
, (comma) |
The delimiter to use if using a list in the items attribute and not using the default , list delimiter. |
labelCol | false | label |
The name of the query column to use when using a query datatype for the options items. Defaults to label as the query column unless specified. |
valueCol | false | value |
The name of the query column to use when using a query datatype for the options items. Defaults to value as the query column unless specified. |
labelKey | false | label | If items is an array of structs, the key name to use as the label for the options items. |
valueKey | false | value | If items is an array of structs, the key name to use as the value for the options items. |
displayOrder | false | Takes a list or array | Used to control the display order when a struct is passed to the items attributes. Indicate a list or array or key names in order to display. Use * to indicate all keys minus any other key that is indicated in the list. |
optgroup | true | n/a | The label to apply for the optgroup around this group of options. |
This tag renders an HTML optgroup
tag and is used to group together related options in a select list. This tag is used in conjunction of the select
and option
/ options
tags. Each user agent (browser) renders opt groups different
<cfset variables.germanCars = StructNew() />
<cfset variables.germanCars.bmw = "BMW" />
<cfset variables.germanCars.vw = "Volkswagon" />
<cfset variables.germanCars.audi = "Audi" />
<cfset variables.americanCars = StructNew() />
<cfset variables.americanCars.ford = "Ford" />
<cfset variables.americanCars.gm = "General Motors" />
<form:select path="favoriteCars">
<form:optgroup label="German Companies">
<form:options items="#variables.germanCars#"/>
</form:optgroup>
<form:optgroup label="American Companies">
<form:options items="#variables.AmericanCars#"/>
</form:optgroup>
</form:select>
You could use the optgroup
attribute of either the select
tag or options
tag as well. This example would produce the same output as the example above:
<form:select path="favoriteCars">
<form:options items="#variables.germanCars#" optgroup="German Cars"/>
<form:options items="#variables.AmericanCars#" optgroup="American Cars"/>
</form:select>
Both of the examples above produces this same output:
<select id="favoriteCars" name="favoriteCars">
<optgroup label="German Companies">
<option id="favoriteCars_audi" value="audi">Audi</option>
<option id="favoriteCars_bmw" value="bmw">BMW</option>
<option id="favoriteCars_vw" value="vw">Volkswagon</option>
</optgroup>
<optgroup label="American Companies">
<option id="favoriteCars_ford" value="ford">Ford</option>
<option id="favoriteCars_gm" value="gm">General Motors</option>
</optgroup>
</select>
Name | Required | Default | Description |
---|---|---|---|
label | true | n/a | The label to apply for the optgroup. |
This tag renders an HTML textarea
.
<form:textarea path="notes" rows="3" cols="20" />
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
value | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The value to use. |
rows | false | n/a | Sets the rows value of the textarea . |
cols | false | n/a | Sets the cols value of the textarea . |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag renders a HTML input
tag with the type of hidden
.
<form:hidden path="orderId" />
This produces:
<input type="hidden" name="orderId" id="orderId" value="5679981" />
Name | Required | Default | Description |
---|---|---|---|
path | false (use if no name and value attribute is used) |
n/a | The path in the bound object to get the value |
name | false (use if no path is defined or custom element name is required) |
value from path
|
The name of the form element (the value is automatic if not defined and a path attribute is defined). |
value | false (use if no path is defined or a custom value to override the value provided by path is required) |
value from path
|
The value to use. |
All standard attributes, event attributes (onClick, etc.) and non-standard attributes (x
namespace only) are supported.
This tag was added in after the release of Mach-II 1.8 Beta 1. Please the BER or a newer Beta / RC / Stable if available.
This tag does not generate any HTML output, but is an important tag for the form tag library as is enables multiple bind contexts in a single form. Sometimes your form is not modeled around a single bean, so you choose not to bind to a bean in the form
tag because there are multiple non-hierarchical bind points (i.e. one bean is not inside another bean via composition). Some code is worth a thousand more words describing this:
<form:form actionEvent="processSomethingCool">
<form:bind target="user">
<!--- form tags for user fields --->
</form:bind>
<form:bind target="company">
<!--- form tags for company fields --->
</form:bind>
</from:form>
As you can see, we are switching the bind context in the middle of form. Also, the bind
tag switches the bind context back the original context if it is available. Take this sample for instance:
<form:form actionEvent="processSomethingCool" bind="user">
<!--- form tags for user fields --->
<form:bind target="company">
<!--- form tags for company fields --->
</form:bind>
<!--- Additional form tags for user fields --->
</from:form>
What is going here if we step through the above code:
- The
form
tag sets the bind context to theUser
bean and some user related form fields are processed. - The
bind
tag sets the bind context to theCompany
bean and saves the previous bind context for later which in this case is theUser
bean. Some company related form fields are processed. - At the end of the
bind
tag, the original bind context (i.e.User
bean) is set as the new bind context. - Additional user related form fields are processed.
Currently, the bind
attribute of the form tag allows for three different ways to provide a bind for the form.
- Simple dot path shortcut -- ex.
target="user"
is equivalent shortcut to the M2 EL syntax oftarget="${event.user}"
- M2 EL syntax - ex.
target="${event.user}"
ortarget="${event.user.address}"
- Pass in a bean directly using CFML -- ex.
target="#variables.someBean#"
- If you do not specify the
target
attribute, thebind
tag will bind to the Mach-II Event object directly.
Name | Required | Default | Description |
---|---|---|---|
target | false | Mach-II Event object | Provides a bind path as a M2 EL expression or simple dot path shortcut syntax or passes in a bean via CFML. See above for available options. |
How do you used inline styles (i.e. class="someStyle"
) so that we could style one specific form control in a specific way if needed?
All tags current already support all standard attributes (id
, class
, style
, dir
and lang
) and all tags except for form
, radiogroup
, checkboxgroup
, option
and the options
tag support standard event attributes (such as tabIndex
, accessKey
, onFocus
, etc). All tags support all attributes as defined by the W3C.
How would you utilize this when reusing the same form for create account and update account? when creating an account, there is no account variable in the event, so I get the error:
"A bind named 'account' is not available the current event object."
Actually this question does not have anything to do with the form tag library specifically. Really what this gets at is how best to handle adds and edits with the same form. Let's say I have an event called showPersonForm
. In my event handler, I call the getPerson
method on my PersonListener
. If there's a personID
in my event, then I'll get a populated Person
object, otherwise I'll get an empty one. Then regardless of what is occurring -- an add or an update, you can then use the binding because there's a bean there.
Ok, if a Person
'has an' Address
and some of the form fields includes Address
properties (i.e. person.address.streetAddress1
) should my empty Person
instantiate the associated empty Address
object as well?
By default if your Person
bean 'has an' Address
, then the default value for the address
attribute in a Person
should be an empty Address
bean. It is quite common for beans to use composition (i.e. beans within beans).
How do you define non-W3C attributes in a tag?
While not part of the standard, sometimes it is necessary to add an attribute to tag for Javascript (i.e. the Lightwindow library for Prototype uses the class
attribute for configuration parameters) or for browser specific attributes (i.e autocomplete="off"
to indicate turning off auto-complete for forms -- which is partially supported by browsers). This can easily be done by using the x
namespace support. See the section on specifying attributes using a namespace for more information. However it's simple as prefixing the attributes with the x:
namespace:
<form:form id="assessmentForm" actionEvent="router" x:autocomplete="off">
Unless you provide an id
attribute, most all form library custom tags (except for form
and hidden
) will assign a id
to each form element and auto-generate a value based off the name
value (and value
if radio or option form elements). Since the id
value cannot contain certain characters (punctuation characters), the framework will change all spaces to _
(dash) and remove all punctuation (using the RegEx expression). We do clean up control characters such as line feeds or tabs.
Examples:
"Dirty" Id | Cleaned Id |
---|---|
Valentine's Day |
Valentines_Day |
C.J. Cregg's Birthday |
CJ_Creggs_Birthday |
C. Farrell & Sons |
C_Farrell__Sons |
Mach-II 1.8 using the following UDF to create cleaned versions for id
:
<cffunction name="createCleanId" access="public" returntype="string" output="false"
hint="
Creates a cleaned version to be used as an 'id'.
Changes spaces to '_' and removes most punctuation (that conforms to RegEx '[[:punct:]]')." >
<cfargument name="dirtyId" type="string" required="true" />
<cfset var cleanedId = arguments.dirtyId />
<cfset cleanedId = REReplaceNoCase(cleanedId, "[[:punct:]]", "", "all") />
<cfset cleanedId = ReplaceNoCase(cleanedId, " ", "_", "all") />
<cfreturn cleanedId />
</cffunction>
We support all tag attributes as defined by the specifications set forth by the W3C. All tags support the list in the standard attributes. Most tags (other than form
and option
) support event attributes. All tags will indicate if they support the event attributes. Non-standard HTML attributes are supported using the x
namespace. URL parameters are supported with the p
namespace (form
tag only) and query string parameters for URL Routes are supported with the q
namespace (form
tag tag only).
All standard attributes are optional and not required.
Attribute Name | Description |
---|---|
id | The value of id is computed off of the name of the element (combined with value for checkbox and radio - favoriteSeason_winter ) if not defined. |
class | |
style | |
dir | |
lang | |
title | |
accesskey | |
tabindex |
Custom attributes are tag attributes that are non-standard HTML attributes for the specific tag. For example you may need to set a tag that is web browser specific, but is not part of the normal W3C approved attributes for the tag.
As we stated above, some Mach-II developers would prefer to specify URL parameters when building URLs by defining name / value pairs instead of passing in a list or struct to the actionParameter
attribute. Now, you're problems are solved using attribute namespaces. Using attribute namespaces leaves the door open for future enhancements to the tag and provides an easy a way around having namespace conflicts (i.e. two keys with the same name, but indicate two separate data fragments).
For example (using the same example from above), if we want to use name / value pairs to indicate the userId
we would namespace the userId
key like so:
<form:form actionEvent="processUser" bind="user" p:userId="#event.getArg('userId')">
This would ouput code in this fashion (note that the URL string may vary depending on you eventParameter
and SES settings):
<form method="post" encType="multipart/form-data" action="index.cfm?event=processUser&userId=46573">
We strip off the namespace prefix (p:
) from the attribute key name and use that as the URL parameter key name when building the URL. The same process applies to the other namespaces we support in the form
tag such as the x
and q
namespaces. Any name / value pairs specified as namespaced attributes will overwrite any key conflicts from the p
, q
or x
attributes.
Sometimes a developer needs to use a non-standard attribute within an HTML tag. This may be either for defining some javascript functionality, or utilizing an attribute that is just not yet W3C compliant. In this case the developer should make use of the x namespace. A common example of this would be for stopping auto-complete in input fields. While not W3C compliant some browsers support the attribute autocomplete
. This being a non-standard attribute would have to be prefixed by the x namespace as indicated below.
<form:input path="firstName" x:autocomplete="false" />
this would output the following html code:
<input type="text" name="firstName" id="firstName" value="John" autocomplete="false" />
Available Namespaces
Namespace | Description |
---|---|
p | Used to prefix name / value pairs used for the URL parameters when building URLs (form tag only). |
q | Used to prefix name / value pairs used for query string parameters when building routes (valid only when using the route attribute) (form tag only). |
x | Uses to prefix name / value pairs for non-standard HTML attributes to be inserted into final output of the form tag. For example, you might use a javascript framework look for a non-standard attribute of a tag in order to perform some functionality on it. |
Attribute Name |
---|
tabIndex |
accessKey |
onFocus |
onBlur |
onSelect |
onChange |
onDblClick |
onMouseDown |
onMouseUp |
onMouseOver |
onMouseMove |
onMouseOut |
onKeyPress |
onKeyDown |
onKeyUp |
The M2SFP for this feature were filed under multiple tickets (numbers from former trac-wiki)
- #211 "task: Implement Form Tag Library (closed: completed)")
- #242 "task: Add "radioGroup" form tag lib (closed: completed)")
- #323 "task: Add "checkboxGroup" form tag lib (closed: completed)") and
- #354 "task: Add "bind" tag to form tag library (closed: fixed)").