Book Image

Instant Building Multi-Page Forms with Yii How-to

By : Uday Sawant
Book Image

Instant Building Multi-Page Forms with Yii How-to

By: Uday Sawant

Overview of this book

Yii is a high-performance PHP framework for rapid web application development. It is well-designed, well-supported, easy to learn, and easy to maintain. Forms are the basic method used to collect information on the Internet, and in cases like user registration and payment process, there's a lot of data to be presented and the lists can get lengthy. Instant Building Multi-Page Forms with Yii is a simple and descriptive how-to that provides step-by-step recipes to help you in converting your lengthy forms into short, interactive forms. It will guide you through the inbuilt features of Yii framework to help you with this complex job. The book starts with the basics of Yii and will guide you through creating simple forms before then converting your simple forms into multi-page forms. It will use the capabilities of Yii to ease the tasks required to do this. Yii eases your work by providing options like database connectivity. We will also take a look at the automated code generation capabilities of Yii in generating forms and necessary CRUD operations, as well as looking at how to divide a single long form into multiple views with same controller/action, and then add form validations and AJAX support to the forms. We will also cover the upload process and how to customise Yii's looks.
Table of Contents (7 chapters)

Creating basic forms (Simple)


Now we will see the creation and working of basic forms in Yii. We will use the Gii tool to automatically generate CRUD operations and a form.

Getting ready

We will use the table user created in the Using the Gii tool recipe. Make sure you have enabled Gii under config/main.php.

How to do it...

  1. Generate a new model for the table User.

  2. Generate CRUD operations with the Gii tool as specified in the Using the Gii tool recipe.

Tip

As we need to create a simple form, we don't need additional functionality such as admin, index, and update. Feel free to uncheck them when generating CRUD.

How it works...

Yii creates some new files and folders, as follows:

  • protected/models/User.php: This is a model class file. It deals with database-related tasks such as fetching and storing data, updating, and deleting. The User class is extended from the base class CActiveRecord.

  • protected/controllers/UserController.php: This is a controller class extended from the base class Controller. This class holds all the code for fetching data using models, data manipulation according to requirements, and sending data to the respective views.

  • protected/views/user: This folder holds views for all CRUD operations; names starting with _ are partial views that are used in multiple places. The remaining files are views for their respective action names in UserController.php.

Let's take a look at the generated controller file. Change access rules to enable any user to access our form as follows:

return array(
  //allow all users to perform 'index' and 'view' actions
  array('allow',  
    'actions'=>array('index','view', 'create'),
    'users'=>array('*'),
  ),

All we need to do is add actionCreate() to the actions that all users can access.

Now move to actionCreate(). This is the action when we access the form with the URL ?r=user/create. At the first line of actionCreate, we instantiate the User model. As the POST variables are not set, the if block is skipped and the form is rendered with the view file create, with model passed to it as a parameter.

public function actionCreate()
{
  $model=new User;
  if(isset($_POST['User']))
  {
    $model->attributes=$_POST['User'];
    if($model->save())
      $this->redirect(array('view','id'=>$model->id));
  }
  $this->render('create',array('model'=>$model));
}

In the view of create.php, we simply render the partial view with the following lines:

<?php echo $this->renderPartial('_form', array(
  'model'=>$model
)); ?>

This uses the file _form.php, which contains all the form elements and passes to it the model that we received from actionCreate. As we need the same form elements in actionCreate and actionUpdate, Yii has created a single file, _form.php, that contains all the form elements. This file is used by both the actions to render the form.

In _form.php, we start with creating an instance of the CActiveForm widget.

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'user-form',
	'enableAjaxValidation'=>false,
)); ?>

The HTML code in the following screenshot is created by this widget:

Next we create a space to render error details, if any, with following line:

<?php echo $form->errorSummary($model); ?>

This adds a DIV element to the page if there are any errors in the form fields.

Next we render all necessary input elements as follows:

<div class="row">
  <?php echo $form->labelEx($model,'last_name'); ?>
  <?php echo $form->textField($model,'last_name',array(
    'size'=>50,
    'maxlength'=>50,
  )); ?>
  <?php echo $form->error($model,'last_name'); ?>
</div>

The HTML code generated can be seen in the following screenshot:

The $form->labelEx() method renders the label. It takes the parameter name from the model's attributeLabels function. If no label is set for this attribute, the attribute name is used as the label.

The $form->textField() method renders the actual form field. We use textField for input with the type set to text; dropDownList to select boxes, textArea to render text areas, hiddenField to render hidden fields respectively.

Note

Look at the name of the input field. It has the format User[last_name]; this enables us to get all related form fields in a single User array, which can be directly assigned to the models' attributes with a single line of code, $model->attributes = $_POST['User'], thereby reducing the number of lines of code.

The $form->error() method adds error messages in a separate div element if there is any error with the data in this field.

Finally, we have added a submit button with the echo CHtml::submitButton('Create'). It creates an input element with type set to submit and is attached to the parent form by default. We can end the form widget with $this->endWidget();.

When the user clicks on the create button, the form data is submitted to the same actionCreate function as POST data.

Now as the $_POST['User'] field is set, the code enters the if block. We assign all attributes marked as safe in the User variable of type POST to model with $model->attributes = $_POST['User']. This is called Mass Assignment.

Then on the next line, we save the model with $model->save(). The method save() internally validates the model to check if the user has entered the valid data. Here, the rules specified in the method rules under the User model are used to validate the form data.

public function rules()
{
  return array(
    array(
      'first_name, last_name, gender, dob, address_1,
      city, state, country, phone_number_1, email_1, 
      created', 'required'
    ),
    array(
      'first_name, last_name, city, state, country, 
       phone_number_1, phone_number_2',
       'length', 'max'=>50
    ),
    array('gender', 'length', 'max'=>6),
    array(
      'address_1, address_2, email_1, email_2', 
      'length', 'max'=>255
    ),
    array('modified, dob', 'safe'),
    array(
      'id, first_name, last_name, gender, dob, address_1, 
      address_2, city, state, country, phone_number_1, 
      phone_number_2, email_1, email_2, created, 
      modified', 'safe', 'on'=>'search'
    ),
  );
}

In the first array, we specify all the required fields; in the next three arrays, we set the maximum length of data for each field. In the fourth array, additionally, we mark the attributes dob and modified as safe. We also make several attributes as safe when the scenario is set to search.

If the validation is successful, the form data is persisted to the database and the page is redirected to the action view, which displays all the captured data.

If the validation fails, the same model is passed to the view but now with the respective validation errors set in it. The line $form->errorSummary($model) renders the summary of all errors in the form and the line $form->error() adds the error line below the respective fields.

There's more...

We have seen the automated creation of forms and CRUD operations with the Gii tool. If you want to write a custom code to process the form and you simply want to generate the form with all fields for the specified table, you can use the form generator tool provided by Gii.

Enter the model's class and view name and click on the Preview button. You will see the same form generated by the Gii tool under the views folder. Click on the Generate button to generate the actual file.

For more information on safe attributes, visit http://www.yiiframework.com/doc/guide/1.1/en/form.model#securing-attribute-assignments.

For more information on validation rules, visit http://www.yiiframework.com/doc/guide/1.1/en/form.model#declaring-validation-rules.