Click to share! ⬇️

Yii Active Form Tutorial

In the last example we created a controller and a yii view to dynamically generate stock charts. That worked out pretty well, and it works like a charm. For this installment, we’re going to take a look at ActiveForm in Yii so we can build a form to present to the user. This form will collect user input, place it into a model, validate it, then hand off to the view that displays stock charts. This way, we can pass data with Post requests instead of Get Requests, and the user will be able to submit a form to generate various stock charts. Let’s do this.

Create The Model

First off we’ll create a model to hold the data the user submits. This will be called a StockForm model which extends the Model class.

models/StockForm.php source


<?php

namespace appmodels;

use yiibaseModel;

class StockForm extends Model
{
    public $ticker;
    public $timeframe;

    public function rules()
    {
        return [
            [['ticker', 'timeframe'], 'required']
        ];
    }
}

This may be a bit of a change from the norm of what you are used to. Just because we created a Model, does not mean we will interact with the Database. In fact in this tutorial so far, we don’t even have a database present. When you need to use Models in this way that do not associate with a database, you use the Model class. When we start working with databases we’ll use the ActiveRecord class. Note that we have a public $ticker and $timeframe, the two pieces of information we need to render a stock chart. There is also a method named rules() which is used to define validation processes. All we do in this one is say that both the ticker and timeframe are required.

Lights Camera Site Controller Action

We have a StockForm Model that will represent the data submitted via the form, but we do not yet have an action to handle the request. This is what out method will look like, we simply put it at the end of all of the other methods in the Site Controller.

SiteController.php source


    public function actionGetchart()
    {
        $model = new StockForm;

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
			
		  if($model->timeframe == 'weekly') {
			  $model->timeframe = '0&p=w';
		  } elseif ($model->timeframe == 'monthly') {
			  $model->timeframe = '0&p=m';
		  } else {
			  $model->timeframe = '1&p=d';
		  }
            return $this->render('chart', ['ticker' => $model->ticker, 'timeframe' => $model->timeframe ]);
			
        } else {
            // either the page is initially displayed or there is some validation error
            return $this->render('chartform', ['model' => $model]);
        }
    }

In this method, we first create an instance of the StockForm Model. Now, you need to make sure that you add this class to your namespaces at the top of the file. If you don’t, Yii will not know how to find the class and will throw an error. Note the addition of the namespace at the top of the SiteController.php here.

<?php

namespace appcontrollers;

use Yii;
use yiifiltersAccessControl;
use yiiwebController;
use yiifiltersVerbFilter;
use appmodelsLoginForm;
use appmodelsContactForm;
use appmodelsStockForm;

Namespaces are the new norm, no matter what framework we’re using – so be sure to brush up on them! The action we created here, actionGetchart, is simply a modified version of the method we created in the last episode. The difference however is that the first time around, we constructed things to use GET variables passed via the query string of the URL. This iteration is different in that we will use a Form, A Model, and POST data to provide to the stock chart. In fact, we will use the same exact view named chart to display the chart in this new controller method. So let’s see, we have a model, a controller, and a view. What are we missing? Oh that’s right, we still need a form to actually accept the input data from the user. Let’s create it now and learn about the power of the Yii Active Form!

chartform.php source


<?php
use yiihelpersHtml;
use yiiwidgetsActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'ticker') ?>

    <?= $form->field($model, 'timeframe') ?>

    <div class="form-group">
        <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>

Let’s look at this a little bit. First off we pull in the Html helper and ActiveForm widget via namespaces. Then we are free to open a form by using ActiveForm::begin() which assigns an instance of the object to $form. We can then build up fields in the form by calling the field method, $form->field(), of the ActiveForm instance. We pass it the $model and the name of the field we want to collect data on. So behind the scenes ‘ticker’ and ‘timeframe’ will become keys in the POST super global array. Then, thanks to the built in Bootstrap framework in yii, we can create a submit button via the Html helper class. The first parameter passed is the text on the button, and the second parameter is an array with attributes to set. In this case we give this button a class of btn btn-primary. Finally, we call ActiveForm::end() to close the form. The best way to see what this does for us in terms of HTML generation is to load up the page, and view the source. Here is what we get when the form is loaded.

http://localhost/yii/basic/web/index.php?r=site/getchart source


<form method="post" action="/yii/basic/web/index.php?r=site/getchart" id="w0">
  <input type="hidden" value="T1l4blNDQS0bICtZZikFVXdqDgxmCx5ENREZATEwDFgnETs3O3J1HQ==" name="_csrf">
  <div class="form-group field-stockform-ticker required">
    <label for="stockform-ticker" class="control-label">Ticker</label>
    <input type="text" name="StockForm[ticker]" class="form-control" id="stockform-ticker">
    <div class="help-block"></div>
  </div>
  <div class="form-group field-stockform-timeframe required">
    <label for="stockform-timeframe" class="control-label">Timeframe</label>
    <input type="text" name="StockForm[timeframe]" class="form-control" id="stockform-timeframe">
    <div class="help-block"></div>
  </div>
  <div class="form-group">
    <button class="btn btn-primary" type="submit">Submit</button>
  </div>
</form>

Now, get ready for some incredible power and awesomeness. When you load this page that generates the form, try to place your cursor in the first field and then move your cursor to the second field without entering any data. Notice that you are prompted right off the back that this field can not be blank! How is Yii doing this?! Well it turns out, only does the Yii ActiveForm do server side validation for you, it also generates client side validation JavaScript at the same time! This is awesome stuff friends!

http://localhost/yii/basic/web/index.php?r=site/getchart browser view

Yii Active Form Validation

So now that we have seen how cool it is to have client side validation built right in, let’s test out the full solution. We’ll check for the daily stock chart of Twitter.
Yii Active Form Submit

When we click on Submit, we get the chart we specified.
Yii Active Form Submission Complete

Conclusion

In this episode, we saw how powerful the Yii Active Form Widget is. By creating a new form with this widget, we found that not only is server side validation handled for you, but client side is taken care of as well. What a fantastic touch by the developers of Yii. We also used a model to handle user input, even in the absence of any database connectivity.

Click to share! ⬇️