When creating HTML forms, we often find that we are writing many view codes that are repetitive and difficult to reuse in different projects. For example, for each input box, we need to associate it with a text label and display possible validation errors. To improve the reusability of these codes, we can use the Form builder features available from version 1.1.0.
1. Basic Concepts
Yii Form Builder uses the CForm object to represent what is required to describe an HTML form, including which data models are associated with this form, what input boxes are in the form, and how the entire form is rendered. Developers primarily need to create and configure this CForm object, and then invoke its rendering method to display the form.
The form's input box parameters are organized into a hierarchical structure based on the form elements. At the top level of the structure is the CForm object. The members of this object fall into two main categories: Cform::buttons and cform::elements. The former contains the button elements (such as the Submit button, reset button), which contains the input elements, static text, and sub-forms. The child form is also a CForm object, except that it exists in the cform::elements of another form. A child form can have its own data model, Cform::buttons, and cform::elements collections.
When a user submits a form, the data that is filled in the entire form structure is submitted, including the data that is filled in the subform. CForm provides a convenient way to automatically assign input data to the corresponding data attributes and perform data validation.
2. Create a simple form
Below, we show how to use the form Builder to create a login form.
First, we write the login action code:
Public Function Actionlogin () { $model = new LoginForm; $form = new CForm (' Application.views.site.loginForm ', $model); if ($form->submitted (' login ') && $form->validate ()) $this->redirect (Array (' Site/index ')); else $this->render (' login ', array (' form ' = = $form));}
In the above code, we application.views.site.loginForm
created the CForm object using the parameters specified by the path alias (which will be briefly explained). CForm objects and LoginForm
models (described in creating model) are associated.
As shown in the code, if the form is submitted and all the inputs have been verified without errors, we will move to the user's browser to the site/index
page. Otherwise, we render the view with this form login
.
A path alias application.views.site.loginForm
actually refers to a PHP file protected/views/site/loginForm.php
. This file should return a PHP array that represents the configuration required by CForm, as follows:
Return Array ( ' title ' = ' Please provide your login credential ', ' elements ' =>array ( ' username ' = Array ( ' type ' = ' = ' text ', ' maxlength ' =>32, ), ' Password ' =>array ( ' type ' = ' = ') Password ', ' maxlength ' =>32, ), ' RememberMe ' =>array ( ' type ' = ' checkbox ', ) ), ' buttons ' =>array ( ' login ' =>array (' type ' = ' submit ', ' label ' = ' login ', ), ),);
A configuration is an associative array of key-value pairs that is used to initialize the corresponding properties of the CForm. The most important properties to configure, as described previously, are cform::elements and cform::buttons. Each of them is an array that specifies a list of form elements. In the next section we will give more details on how to configure the form elements.
Finally, we write a login
view that can be succinctly shown below,
tip: The code above is echo $form;
equivalent echo $form->render();
. This is because CForm executes the __toString
magic method, which invokes render()
and returns its result as a string representing this form object.
3. Specifying form elements
Using the Form builder, most of our work is done by writing the view script code to the specified form element. In this section, we describe how to specify the Cform::elements property. We are not going to tell Cform::buttons because its configuration and cform::elements configuration are almost identical.
The Cform::elements property accepts an array as its value. Each array element specifies a separate form element, which can be an input box, a static text string, or a sub-form.
Specifying input elements
An INPUT element consists mainly of a label, an input box, a hint text, and an error display. It must be associated with a model property. The specification of an INPUT element is represented as a cforminputelement instance. The following code in the cform::elements array specifies a separate INPUT element:
' Username ' =>array ( ' type ' = ' = ' text ', ' maxlength ' =>32,),
It shows that the model property is named, the type of the username
input box is text
, and its maxlength
property is 32.
Any Cforminputelement writable property can be configured as above. For example, we can specify the hint option to display a cue message, or we can specify the items option if the input box is a list box, a drop-down list, a multiple-selection list, or a radio button listing. If the name of the option is not a cforminputelement attribute, it will be considered a property of the corresponding HTML input element, for example, because the above is maxlength
not a cforminputelement property, it is rendered as an HTML text input box maxlength
property.
The type option requires special attention. It specifies the type of the input box. For example, text
a type means that a normal text input box will be rendered, and password
the type means that a password input box will be rendered. Cforminputelement identifies the following built-in types:
Text
Hidden
Password
TextArea
File
Radio
CheckBox
ListBox
DropDownList
CheckBoxList
Radiolist
In the built-in types above, we want to say a little more about the use of these "list" types, including dropdownlist
, checkboxlist
and radiolist
. These types need to set the Items property of the corresponding INPUT element. You can do this:
' Gender ' =>array ( ' type ' = ' dropdownlist ', ' items ' =>user::model ()->getgenderoptions (), ' Prompt ' = = ' Please select: ', ',... class User extends cactiverecord{public function getgenderoptions () { return Array ( 0 = ' Male ', 1 = ' Female ', );} }
The above code will generate a drop-down list selector, prompting the text to be "Please select:". Options include "Male" and "Female", which are User
returned by methods in the Model class getGenderOptions
.
In addition to these built-in types, the type option can be a path alias for a widget class name or widget class. The Widget class must be extended from Cinputwidget or Cjuiinputwidget. When the input element is rendered, an instance of the specified widget class is created and rendered. The widget is configured using the specification as given for the input element.
Specify static text
In many cases, a form contains some decorative HTML code. For example, a horizontal line is used to separate different parts of a form, and an image appears in a specific location to enhance the visual appearance of the form. We can specify these HTML code as static text in the Cform::elements collection. To do this, we just specify a static text string as an array element in the cform::elements proper position. For example
Return Array ( ' elements ' =>array (... ') Password ' =>array ( ' type ' = ' password ', ' maxlength ' =>32, ' ), '
Above, we password
insert a horizontal line between the input box and the other rememberMe
.
Static text is best used when the text content and their location are irregular. If each INPUT element in the form needs to be similarly decorated, we should customize the form rendering method, which is briefly described in this section.
Specify child forms
A child form is used to separate a long form into several logical parts. For example, we can separate the user registration form into two parts: login information and archive information. Each sub-form and a data model have no association. For example, in a user registration form, if we store user login information and profile information into two separate data tables (represented as two data models), then each sub-form needs to be associated with a corresponding data model. If we store all the information in a single data table, none of the sub-forms have a data model because they share the same model as the root form.
A sub-form is also represented as a Cform object. To specify a sub-form, we should configure the Cform::elements property to be an form
element of type:
Return Array ( ' elements ' =>array (... ') User ' =>array ( ' type ' = ' form ', ' title ' = ' Login credential ', ' elements ' =>array ( ' Username ' =>array ( ' type ' = ' text ', ), ' Password ' =>array ( ' type ' = ' password ', ), ' email ' =>array ( ' type ' = ' + ' text ',),), ' profile ' =>array ( ' Type ' = ' = ' form ', ...), ...),...) ;
Similar to configuring a root form, we primarily need to specify the Cform::elements property for a single child form. If a sub-form needs to be associated with a data model, we can also configure its Cform::model property.
Sometimes we want to use a class to represent a form without using the default CForm class. For example, this section will briefly show that we can extend cform to customize the form rendering logic. By specifying the type of INPUT element form
, a child form is automatically represented as an object whose class is the same as its parent form. If we specify that the type of the input element is similar to XyzForm
(an Form
ending string), then the child form will be represented as an XyzForm
object.
4. Accessing form elements
Accessing form elements is as simple as accessing array elements. The Cform::elements property returns an Cformelementcollection object that extends from CMap and allows its elements to be accessed in a manner similar to an ordinary array. For example, to access the elements in the login form username
, we can use the following code:
$username = $form->elements[' username ');
To access the elements in the user registration form email
, use the
$email = $form->elements[' user ']->elements[' email ';
Because CForm performs array access for its Cform::elements property, the above code can be simplified to:
$username = $form [' username ']; $email = $form [' user '] [' email '];
5. Create a nested form
We have described the sub-forms. We call a form with a child form as a nested form. In this section, we use the user registration form as an example to show how to create a nested form that associates multiple data models. We assume that the user's authentication information is stored as a User
model, and the user's profile information is stored as a Profile
model.
We first create the register
action as follows:
Public Function Actionregister () { $form = new CForm (' Application.views.user.registerForm '); $form [' user ']->model = new user; $form [' profile ']->model = new profile; if ($form->submitted (' register ') && $form->validate ()) { $user = $form [' User ']->model; $profile = $form [' Profile ']->model; if ($user->save (false)) { $profile->userid = $user->id; $profile->save (false); $this->redirect (Array (' Site/index ')); } } $this->render (' register ', Array (' form ' = = $form));}
On top of that, we application.views.user.registerForm
created the form by using the specified configuration. After the form is submitted and successfully validated, we try to save the user and Profile model. We model
retrieve the user and Profile model by accessing the properties of the corresponding child form object. Because input validation is complete, we call $user->save(false)
to skip validation. This is also done for the Profile model.
Next, we write the form configuration file protected/views/user/registerForm.php
:
return array (' Elements ' =>array (' user ' =>array (' type ' = ' ' form ', ' title ' = ' = ' Logi n Information ', ' Elements ' =>array (' username ' =>array (' type ' = ' "text ') ,), ' Password ' =>array (' type ' = ' password ',), ' Email ' =>array (' type ' = ' ' text ',)), ' Profil E ' =>array (' type ' = ' form ', ' title ' = ' profile information ', ' Elements ' =>array ( ' FirstName ' =>array (' type ' = ' = ' text ',), ' LastName ' =& Gt;array (' type ' = ' = ' text ',),),), ' Buttons ' =>array ( ' Register ' =>array (' type ' = ' submit ', ' label ' = ' register ',),);
On top of that, when you specify each child form, we also specify its Cform::title property. The default form rendering logic encapsulates each child form into a single field-set, using this property as its caption.
Finally, we write the register
view script:
6. Custom form Display
The primary benefit of using Form Builder is the separation of the logic (the form configuration is stored in a separate file) and the presentation (Cform::render method). In this way, we can implement custom form displays by overriding Cform::render or by providing a partial view to render the form. Both methods maintain the integrity of the form configuration and can be easily reused.
When overriding Cform::render, you primarily need to traverse cform::elements and Cform::buttons and invoke the Cformelement::render method of each form element. For example
Class MyForm extends cform{public function render () { $output = $this->renderbegin (); foreach ($this->getelements () as $element) $output. = $element->render (); $output. = $this->renderend (); return $output; }}
Maybe we also need to write a view script _form
to render a view:
<?phpecho $form->renderbegin (); foreach ($form->getelements () as $element) echo $element->render (); echo $form->renderend ();
To use this view script, we need to call:
<p class= "Form" > $this->renderpartial (' _form ', Array (' form ' = = $form));</p>
If a generic form rendering does not apply to a particular form (for example, the form needs an irregular decoration for a particular element), we can do so in the view script:
Some complex UI elements here<?php echo $form [' username '];? >some complex UI elements here<?php echo $form [' PASSW Ord '];? >some complex UI elements here
In the final approach, the form builder does not look good because we still need to write a lot of form code. However, it is still beneficial that the form is specified using a separate configuration file, which helps developers focus more on the logical part.
The above is the official Yii Framework Guide Series 21--Use forms: Use the content of the form builder (CForm), and more about topic.alibabacloud.com (www.php.cn)!