form.md 3.77 KB
Newer Older
1 2 3
Working with forms
==================

4 5 6
The primary way of using forms in Yii is through [[yii\widgets\ActiveForm]]. This approach should be preferred when
the form is based upon  a model. Additionally, there are some useful methods in [[\yii\helpers\Html]] that are typically
used for adding buttons and help text to any form.
7

8 9
When creating model-based forms, the first step is to define the model itself. The model can be either based upon the
Active Record class, or the more generic Model class. For this login example, a generic model will be used:
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

```php
use yii\base\Model;

class LoginForm extends Model
{
	public $username;
	public $password;

	/**
	 * @return array the validation rules.
	 */
	public function rules()
	{
		return [
			// username and password are both required
Qiang Xue committed
26
			[['username', 'password'], 'required'],
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
			// password is validated by validatePassword()
			['password', 'validatePassword'],
		];
	}

	/**
	 * Validates the password.
	 * This method serves as the inline validation for password.
	 */
	public function validatePassword()
	{
		$user = User::findByUsername($this->username);
		if (!$user || !$user->validatePassword($this->password)) {
			$this->addError('password', 'Incorrect username or password.');
		}
	}

	/**
	 * Logs in a user using the provided username and password.
	 * @return boolean whether the user is logged in successfully
	 */
	public function login()
	{
		if ($this->validate()) {
			$user = User::findByUsername($this->username);
			return true;
		} else {
			return false;
		}
	}
}
```

60
The controller will pass an instance of that model to the view, wherein the Active Form widget is used:
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

```php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

<?php $form = ActiveForm::begin([
	'id' => 'login-form',
	'options' => ['class' => 'form-horizontal'],
]) ?>
	<?= $form->field($model, 'username') ?>
	<?= $form->field($model, 'password')->passwordInput() ?>

	<div class="form-group">
		<div class="col-lg-offset-1 col-lg-11">
			<?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
		</div>
	</div>
<?php ActiveForm::end() ?>
```

81 82 83 84
In the above code, `ActiveForm::begin()` not only creates a form instance, but also marks the beginning of the form.
All of the content placed between `ActiveForm::begin()` and `ActiveForm::end()` will be wrapped within the `<form>` tag.
As with any widget, you can specify some options as to how the widget should be configured by passing an array to
the `begin` method. In this case, an extra CSS class and identifying ID are passed to be used in the opening `<form>` tag.
85

86 87 88
In order to create a form element in the form, along with the element's label, and any application JavaScript validation,
the `field` method of the Active Form widget is called. When the invocation of this method is echoed directly, the result
is a regular (text) input. To customize the output, you can chain additional methods to this call:
89 90 91 92 93 94 95 96

```php
<?= $form->field($model, 'password')->passwordInput() ?>

// or

<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
```
Carsten Brandt committed
97 98 99 100 101

This will create all the `<label>`, `<input>` and other tags according to the template defined by the form field.
To add these tags yourself you can use the `Html` helper class. The following is equivalent to the code above:

```php
Алексей committed
102 103 104
<?= Html::activeLabel($model, 'password') ?>
<?= Html::activePasswordInput($model, 'password') ?>
<?= Html::error($model, 'password') ?>
Carsten Brandt committed
105 106 107

or

Алексей committed
108 109 110
<?= Html::activeLabel($model, 'username', ['label' => 'name']) ?>
<?= Html::activeTextInput($model, 'username') ?>
<?= Html::error($model, 'username') ?>
Carsten Brandt committed
111 112
<div class="hint-block">Please enter your name</div>
```
113 114 115 116 117 118 119 120 121

> **Tip**: in order to style required fields with asterisk you can use the following CSS:
>
```css
div.required label:after {
    content: " *";
    color: red;
}
```