Carsten Brandt
10 years ago
4 changed files with 152 additions and 113 deletions
@ -1,6 +1,35 @@ |
|||||||
Complex Forms with Multiple Models |
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. |
> Note: This section is under development. |
||||||
> |
> |
||||||
> It has no content yet. |
> It has no content yet. |
||||||
|
|
||||||
|
TBD |
||||||
|
|
||||||
|
Dependend models |
||||||
|
---------------- |
||||||
|
|
||||||
|
|
||||||
|
> Note: This section is under development. |
||||||
|
> |
||||||
|
> It has no content yet. |
||||||
|
|
||||||
|
TBD |
||||||
|
@ -0,0 +1,112 @@ |
|||||||
|
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 |
Loading…
Reference in new issue