Commit 55196dc8 by Carsten Brandt

update guide about tabular input forms

issue #7040
parent 7dd3eea6
...@@ -115,14 +115,28 @@ Handling multiple models with a single form ...@@ -115,14 +115,28 @@ Handling multiple models with a single form
> Note: This section is under development. > 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 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 name-value and is represented by `Setting` model. This kind of form is also often each setting is stored as a name-value pair and is represented by a `Setting` [active record](db-active-record.md) model.
referred to as "tabular input". In contrast to this, handling different models of different kind, is handled in the section 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). [Complex Forms with Multiple Models](input-multiple-models).
The following shows how to implement tabular input with Yii. The following shows how to implement tabular input with Yii.
Let's start with controller action: 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
<?php <?php
...@@ -146,7 +160,6 @@ class SettingsController extends Controller ...@@ -146,7 +160,6 @@ class SettingsController extends Controller
foreach ($settings as $setting) { foreach ($settings as $setting) {
$setting->save(false); $setting->save(false);
} }
return $this->redirect('index'); return $this->redirect('index');
} }
...@@ -155,10 +168,12 @@ class SettingsController extends Controller ...@@ -155,10 +168,12 @@ class SettingsController extends Controller
} }
``` ```
In the code above we're using `indexBy` when retrieving models from the database to populate an array indexed by model ids. 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. `loadMultiple` fills multiple models with the form data coming from POST These will be later used to identify form fields. [[yii\base\Model::loadMultiple()|Model::loadMultiple()]] fills multiple
and `validateMultiple` validates all models at once. In order to skip validation when saving we're passing `false` as models with the form data coming from POST
a parameter to `save`. 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: Now the form that's in `update` view:
...@@ -170,11 +185,37 @@ use yii\widgets\ActiveForm; ...@@ -170,11 +185,37 @@ use yii\widgets\ActiveForm;
$form = ActiveForm::begin(); $form = ActiveForm::begin();
foreach ($settings as $index => $setting) { foreach ($settings as $index => $setting) {
echo Html::encode($setting->name) . ': ' . $form->field($setting, "[$index]value"); echo $form->field($setting, "[$index]value")->label($setting->name);
} }
ActiveForm::end(); ActiveForm::end();
``` ```
Here for each setting we are rendering name and an input with a value. It is important to add a proper index 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 `loadMultiple` determines which model to fill with which values. 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
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