Commit 0e848427 by Carsten Brandt

adjust form guide structure

fixes #7042
parent 55196dc8
......@@ -90,7 +90,8 @@ Getting Data from Users
* [Creating Forms](input-forms.md)
* [Validating Input](input-validation.md)
* [Uploading Files](input-file-upload.md)
* **TBD** [Getting Data for Multiple Models](input-multiple-models.md)
* [Collecting tabular input](input-tabular-input.md)
* [Getting Data for Multiple Models](input-multiple-models.md)
Displaying Data
......
Working with Forms
==================
Creating Forms
==============
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.
A form, that is displayed on the client side, will in most cases have a corresponding model which is used
A form, that is displayed on the client side, will in most cases have a corresponding [model](structure-models.md) which is used
to validate its input on the server side (Check the [Validating Input](input-validation.md) section for more details on validation).
When creating model-based forms, the first step is to define the model itself. The model can be either based upon
an [Active Record](db-active-record.md) class, representing some data from the database, or a generic Model class
......@@ -108,114 +108,11 @@ class like it is done in the above example with [[yii\helpers\Html::submitButton
> }
> ```
The next section [Validating Input](input-validation.md) handles the validation of the submitted form data on the server
side as well as ajax- and client side validation.
Handling multiple models with a single form
-------------------------------------------
To read about more complex usage of forms, you may want to check out the following sections:
> Note: This section is under development.
Sometimes you need to handle multiple models of the same kind in a single form. For example, multiple settings where
each setting is stored as a name-value pair and is represented by a `Setting` [active record](db-active-record.md) model.
This kind of form is also often referred to as "tabular input".
In contrast to this, handling different models of different kind, is handled in the section
[Complex Forms with Multiple Models](input-multiple-models).
The following shows how to implement tabular input with Yii.
There are three different situations to cover, which have to be handled slightly different:
- Updating a fixed set of records from the database
- Creating a dynamic set of new records
- Updating, creating and deleting of records on one page
In contrast to the single model forms explained before, we are working with an array of models now.
This array is passed to the view to display the input fields for each model in a table like style and we
will use helper methods of [[yii\base\Model]] that allow loading and validating multiple models at once:
- [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] load post data into an array of models.
- [[yii\base\Model::validateMultiple()|Model::validateMultiple()]] validates an array of models.
### Updating a fixed set of records
Let's start with the controller action:
```php
<?php
namespace app\controllers;
use Yii;
use yii\base\Model;
use yii\web\Controller;
use app\models\Setting;
class SettingsController extends Controller
{
// ...
public function actionUpdate()
{
$settings = Setting::find()->indexBy('id')->all();
if (Model::loadMultiple($settings, Yii::$app->request->post()) && Model::validateMultiple($settings)) {
foreach ($settings as $setting) {
$setting->save(false);
}
return $this->redirect('index');
}
return $this->render('update', ['settings' => $settings]);
}
}
```
In the code above we're using [[yii\db\ActiveQuery::indexBy()|indexBy()]] when retrieving models from the database to populate an array indexed by models primary keys.
These will be later used to identify form fields. [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] fills multiple
models with the form data coming from POST
and [[yii\base\Model::validateMultiple()|Model::validateMultiple()]] validates all models at once.
As we have validated our models before, using `validateMultiple()`, we're now passing `false` as
a parameter to [[yii\db\ActiveRecord::save()|save()]] to not run validation twice.
Now the form that's in `update` view:
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin();
foreach ($settings as $index => $setting) {
echo $form->field($setting, "[$index]value")->label($setting->name);
}
ActiveForm::end();
```
Here for each setting we are rendering name and an input with a value. It is important to add a proper index
to input name since that is how [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] determines which model to fill with which values.
### Creating a dynamic set of new records
Creating new records is similar to updating except the part where we instantiate the models:
```php
public function actionCreate()
{
$count = count(Yii::$app->request->post('Setting', []));
$settings = [new Setting()];
for($i = 1; $i < $count; $i++) {
$settings[] = new Setting();
}
// ...
}
```
Here we create an initial `$settings` array containing one model by default and adding more models for each line of input
we may have received.
In the view you can use javascript to add new input lines dynamically.
### Combining Update, Create and Delete on one page
TBD
- [Collecting tabular input](input-tabular-input.md) for collecting data for multiple models of the same kind.
- [Complex Forms with Multiple Models](input-multiple-models.md) for handling multiple different models in the same form.
- [Uploading Files](input-file-upload) on how to use forms for uploading files.
Complex Forms with Multiple Models
==================================
In complex user interfaces it can happen that a user has to fill in data in one form that
has to be saved in different tables in the database. The concept of Yii forms allows you to
build these forms with nearly no more complexity compared to single model forms.
Same as with one model you follow the following schema for validation on the server side:
1. instantiate model classes
2. populate the models attributes with input data
3. validate all models
4. If validation passes for all models, save them
5. If validation fails or no data has been submitted, display the form by passing all model instances to the view
In the following we show an example for using multiple models in a form... TBD
Multiple models example
---------------
> Note: This section is under development.
>
> It has no content yet.
TBD
Dependend models
----------------
> Note: This section is under development.
>
> It has no content yet.
TBD
Collecting tabular input
========================
Sometimes you need to handle multiple models of the same kind in a single form. For example, multiple settings, where
each setting is stored as a name-value pair and is represented by a `Setting` [active record](db-active-record.md) model.
This kind of form is also often referred to as "tabular input".
In contrast to this, handling different models of different kind, is handled in the section
[Complex Forms with Multiple Models](input-multiple-models.md).
The following shows how to implement tabular input with Yii.
There are three different situations to cover, which have to be handled slightly different:
- Updating a fixed set of records from the database
- Creating a dynamic set of new records
- Updating, creating and deleting of records on one page
In contrast to the single model forms explained before, we are working with an array of models now.
This array is passed to the view to display the input fields for each model in a table like style and we
will use helper methods of [[yii\base\Model]] that allow loading and validating multiple models at once:
- [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] load post data into an array of models.
- [[yii\base\Model::validateMultiple()|Model::validateMultiple()]] validates an array of models.
### Updating a fixed set of records
Let's start with the controller action:
```php
<?php
namespace app\controllers;
use Yii;
use yii\base\Model;
use yii\web\Controller;
use app\models\Setting;
class SettingsController extends Controller
{
// ...
public function actionUpdate()
{
$settings = Setting::find()->indexBy('id')->all();
if (Model::loadMultiple($settings, Yii::$app->request->post()) && Model::validateMultiple($settings)) {
foreach ($settings as $setting) {
$setting->save(false);
}
return $this->redirect('index');
}
return $this->render('update', ['settings' => $settings]);
}
}
```
In the code above we're using [[yii\db\ActiveQuery::indexBy()|indexBy()]] when retrieving models from the database to populate an array indexed by models primary keys.
These will be later used to identify form fields. [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] fills multiple
models with the form data coming from POST
and [[yii\base\Model::validateMultiple()|Model::validateMultiple()]] validates all models at once.
As we have validated our models before, using `validateMultiple()`, we're now passing `false` as
a parameter to [[yii\db\ActiveRecord::save()|save()]] to not run validation twice.
Now the form that's in `update` view:
```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin();
foreach ($settings as $index => $setting) {
echo $form->field($setting, "[$index]value")->label($setting->name);
}
ActiveForm::end();
```
Here for each setting we are rendering name and an input with a value. It is important to add a proper index
to input name since that is how [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] determines which model to fill with which values.
### Creating a dynamic set of new records
Creating new records is similar to updating, except the part, where we instantiate the models:
```php
public function actionCreate()
{
$count = count(Yii::$app->request->post('Setting', []));
$settings = [new Setting()];
for($i = 1; $i < $count; $i++) {
$settings[] = new Setting();
}
// ...
}
```
Here we create an initial `$settings` array containing one model by default so that always at least one text field will be
visible in the view. Additionally we add more models for each line of input we may have received.
In the view you can use javascript to add new input lines dynamically.
### Combining Update, Create and Delete on one page
> Note: This section is under development.
>
> It has no content yet.
TBD
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment