How to create an active form with CRUD related models?

Hi:

Let’s say I have a model “Client”, and a Client can have many Contacts. So we have 2 models, related.

I’m in the update method of the controller, when I can modify data:

$model = Client::findOne($id);
(this model already have relations, so I can access $model->contacts to get all the contacts of the client)

Now, we are in the view … I put some client fields …

<?php
echo $form->field($model, 'company')->textInput();
echo $form->field($model, 'address')->textInput();
echo $form->field($model, 'email')->textInput();
...
?>

And now I want to put all the contacts:

foreach ($model->contacts as $contact) {
 echo $form->field($model, 'contacts.name')->textInput();
 echo $form->field($model, 'contacts.email')->textInput();
 ...
}

This is what it’s not working for me … I don’t know how to create the ActiveFields for those related fields, and also how can I put a block of blank fields, so a user can create a new contact … then in the controller, how can I handle the old ones modifications and the new one ?

Importante note: it’s not creating a view from 2 separate models (as suggested here: https://yii2-framework.readthedocs.io/en/latest/guide/input-multiple-models/).

I’m referring to create one unique view with one unique ActiveForm (not a Gridview) of the main model and as many “blocks” of inputs with the related model records, in order to modify and create a new one (or even delete one).

A way to explain :wink:

FORM

input with model.company
input with model.email

Contacts
{loop}
input with model.contacts.name input with model.contacts.email …
input with model.contacts.name input with model.contacts.email …
line with blank inputs so user can create a new one
{/loop}

/FORM

This is a very good question.

A single form for a main model and its multiple related models … we want to implement this kind of form quite frequently.

What I want to suggest is yii2-dynamicform widget extensions. The original source is written by Wanderson Bragança (wbraganca / yii2-dynamicform). And there are many forks out there. I’m personally using kidzen / yii2-dynamicform. Take a look at them and choose what you like.

And I’m also very curious about how people are solving this challenge.

I made it this way:

Controller (view/update method)
$model = $this->findModel($id);
(as I said, this model has already the relations)

View
echo $form->field($model, ‘name’)->textInput();
echo $form->field($model, ‘lastname’)->textInput();

// and for other relations (not in Gridview as I wanted):
foreach ($model->relation as $k => $r) {
echo $form->field($r, ‘[’.$k.’]attribute1’)->textInput();
echo $form->field($r, ‘[’.$k.’]attribute2’)->textInput();

}

Does it work as expected? I’m afraid not, because you may not be able to add/remove related models, while you could update existing ones.

Please take a look at the documentation of yii2-dynamicform, and you’ll know what it can do for you and what you have to do to use it.

Yes, I can … it’s a simple loop through the ID’s I receive … if new, new record, if exists update, if I don’t find it, delete.
It’s working perfectly !

I’ve taken a look at the one you used … personally, it’s doing the same I did … but it does do things I really don’t like, for example, to delete all subrecords and then create the ones coming …

1 Like

That’s nice!
How do you increase/decrease the number of records in the view? Using some javascript? Or preparing fixed number of empty fields?
Does it work with AJAX?
I’m very curious. Could you share your code in the controller and the view for us?

I think the controller code is a sample. It doesn’t belong to the extension. You could do it as you like in the controller.