multimodelform

Handling of multiple records and models in a form
49 followers

This extension allows to work with multiple records and different models in a edit form. It handles clientside cloning and removing input elements/fieldsets and serverside batchInsert/Update/Delete.

Creating forms with this functionality is a 'tricky' workaround in views and controllers. This widget should do the main part of the work for you. It can be useful for order/registration forms ...

See:

'multimodelform' could be an updated version of my extension jqrelcopy, but because of the different approach jqrelcopy will stay as lightweight extension for other needs. If you don't have to work with models take a look at jqrelcopy.

Note

Not every form input element is supported.

You can use the a few basic CFormInputElement (text, textarea, dropdownlist, ...) and some widgets (CJuiDatePicker, see below) but at the moment

  • checkbox: you have to use a checkboxlist instead (see below and the demo.3.2)
  • Autocomplete ...

are not supported.

Features

  • Clientside Clone/Remove form elements / fieldsets with the jQuery plugin http://www.andresvidal.com/labs/relcopy.html
  • Simple handling of the submitted form data in the controllers create/update action
  • Simultanous editing multiple records and models (master/detail...)
  • Supports validation and error summary for each model/record
  • Autogenerating input form elements with the 'form builder' functionality of Yii

New since v2.0

  • tableView (= gridView)
  • Support for cloning widget form elements: CJuiDatePicker, extension datetimepicker

Imporant note when upgrading to v2.1

  • MultiModelForm::validate and MultiModelForm::save have now the same parameterlist, so you have to add 'deletedItems' as third parameter (see Usage Validate/Save)
MultiModelForm::save($model,$validatedItems,$deleteItems,$masterValues)

Requirements

  • Yii 1.1.6+

Usage

  • Extract the files under .../protected/extensions

  • Master/Detail example:

Assume you have two models 'group' (id, title) and 'member' (id, groupid, firstname,lastname,membersince). The id attribute is the autoincrement primary key.

  • Generate the models 'Group' and 'Member' with gii. For testing the error summary set the members firstname/lastname as required in the rules.

  • Generate the 'GroupController' and the group/views with gii. You don't need to create a 'MemberController' and the member views for this example.

  • Change the default actionUpdate of the GroupController to

public function actionUpdate($id)
{
    Yii::import('ext.multimodelform.MultiModelForm');
 
    $model=$this->loadModel($id); //the Group model
 
    $member = new Member;
    $validatedMembers = array(); //ensure an empty array
 
    if(isset($_POST['Group']))
    {
        $model->attributes=$_POST['Group'];
 
        //the value for the foreign key 'groupid'
        $masterValues = array ('groupid'=>$model->id);
 
        if( //Save the master model after saving valid members
            MultiModelForm::save($member,$validatedMembers,$deleteMembers,$masterValues) &&
            $model->save()
           )
                $this->redirect(array('view','id'=>$model->id));
    }
 
    $this->render('update',array(
        'model'=>$model,
        //submit the member and validatedItems to the widget in the edit form
        'member'=>$member,
        'validatedMembers' => $validatedMembers,
    ));
}
  • Change the code of actionCreate like this
public function actionCreate()
{
    Yii::import('ext.multimodelform.MultiModelForm');
 
    $model = new Group;
 
    $member = new Member;
    $validatedMembers = array();  //ensure an empty array
 
    if(isset($_POST['Group']))
    {
        $model->attributes=$_POST['Group'];
 
        if( //validate detail before saving the master
            MultiModelForm::validate($member,$validatedMembers,$deleteItems) &&
            $model->save()
           )
           {
             //the value for the foreign key 'groupid'
             $masterValues = array ('groupid'=>$model->id);
             if (MultiModelForm::save($member,$validatedMembers,$deleteMembers,$masterValues))
                $this->redirect(array('view','id'=>$model->id));
            }
    }
 
    $this->render('create',array(
        'model'=>$model,
        //submit the member and validatedItems to the widget in the edit form
        'member'=>$member,
        'validatedMembers' => $validatedMembers,
    ));
}
  • Change the renderPartial in views/group/create.php and update.php to transfer the parameters $member and $validatedMembers to the _form.php
echo $this->renderPartial('_form', array('model'=>$model,
                          'member'=>$member,'validatedMembers'=>$validatedMembers));
  • Change the generated code of the GroupController's form view (views/group/_form.php).
<div class="form wide">
 
<?php $form=$this->beginWidget('CActiveForm', array(
        'id'=>'group-form',
        'enableAjaxValidation'=>false,
)); ?>
 
<p class="note">Fields with <span class="required">*</span> are required.</p>
 
<?php
    //show errorsummary at the top for all models
    //build an array of all models to check
    echo $form->errorSummary(array_merge(array($model),$validatedMembers));
?>
 
<div class="row">
    <?php echo $form->labelEx($model,'title'); ?>
    <?php echo $form->textField($model,'title'); ?>
    <?php echo $form->error($model,'title'); ?>
</div>
 
<?php
 
// see http://www.yiiframework.com/doc/guide/1.1/en/form.table
// Note: Can be a route to a config file too,
//       or create a method 'getMultiModelForm()' in the member model
 
$memberFormConfig = array(
      'elements'=>array(
        'firstname'=>array(
            'type'=>'text',
            'maxlength'=>40,
        ),
        'lastname'=>array(
            'type'=>'text',
            'maxlength'=>40,
        ),
        'membersince'=>array(
            'type'=>'dropdownlist',
            //it is important to add an empty item because of new records
            'items'=>array(''=>'-',2009=>2009,2010=>2010,2011=>2011,),
        ),
    ));
 
$this->widget('ext.multimodelform.MultiModelForm',array(
        'id' => 'id_member', //the unique widget id
        'formConfig' => $memberFormConfig, //the form configuration array
        'model' => $member, //instance of the form model
 
        //if submitted not empty from the controller,
        //the form will be rendered with validation errors
        'validatedItems' => $validatedMembers,
 
        //array of member instances loaded from db
        'data' => $member->findAll('groupid=:groupId', array(':groupId'=>$model->id)),
    ));
?>
 
<div class="row buttons">
    <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
 
<?php $this->endWidget(); ?>
 
</div><!-- form -->

Usage Validate/Save

The behavior has changed in v2.1. In older versions 'save' always exceuted 'validate' internally. 'validate' means to recreate all items from the form data. So there was no chance to alter the attributes of the models in $validatedItems between calling 'validate' and 'save'.

No you can do something like this.

//validate formdata and populate $validatedItems/$deleteItems
if (MultiModelForm::validate($model,$validatedItems,$deleteItems,$masterValues)) 
{
 
 //... alter the model attributes of $validatedItems if you need ... 
 
 //will not execute internally validate again, because $validatedItems/$deleteItems are not empty
 MultiModelForm::save($model,$validatedItems,$deleteItems,$masterValues);
}

But you can still use 'save' without extra validate before. Validation will be internally done when $validatedItems/$deleteItems are empty.

$validatedItems=array();
 
if(isset($_POST['FORMDATA']) && MultiModelForm::save($model,$validatedItems,$deleteItems,$masterValues)) 
{
  //... validation and saving is ok ...
  //redirect ...
}
 
//No POST data or validation error on save 
$this->render ...

Usage tableView

Set the property 'tableView'=>true.

$this->widget('ext.multimodelform.MultiModelForm',array(
       ...
        'tableView' => true,
     //'tableFootCells' => array('footerCol1','footerCol2'...), //optional table footer
       ...
    ));

Usage widget form elements

Yii allows type='AWidget' as form element. So in your form config array you can use:

array( 
   'elements'=>array(
         ....
          'lastname'=>array(
            'type'=>'text',
            'maxlength'=>40,
            ),
 
            'dayofbirth'=>array(              
                'type'=>'zii.widgets.jui.CJuiDatePicker',
                'language'=>'de',
                'options'=>array(
                    'showAnim'=>'fold',
                ),
           ...                      
        )
    )

This however needs a javascript workaround on cloning the date element. We have to assign the CJuiDatePicker functionality to the cloned new element.

Since v2.0 there are the properties jsBeforeClone,jsAfterClone,jsBeforeNewId,jsAfterNewId available where javascript code can be implemented. Use 'this' as the current jQuery object.

For CJuiDatePicker and the extension extension datetimepicker there are predefined functions available, so it's easy to make cloning date fields work.

You have to assign the property 'jsAfterNewId' to the prepared code.

Assume your form definition elements are defined in the array $formConfig. 'afterNewIdDatePicker' reads the options from the specified element and adds the 'datepicker':

$this->widget('ext.multimodelform.MultiModelForm',array(
       ...
         // 'jsBeforeNewId' => "alert(this.attr('id'));", 
        'jsAfterNewId' => MultiModelForm::afterNewIdDatePicker($formConfig['elements']['dayofbirth']),
       ...
    ));

Now cloning of the field 'dayofbirth' should work.

Support for 'datetimepicker' is analog (afterNewIdDateTimePicker).

For other widgets you have to find out the correct javascript code on cloning. Please let me know if you have found a javascript code for other widgets.

Note: I couldn't get Autocomplete working. Maybe one of you has an idea (see afterNewIdAutoComplete in MultiModelForm.php).

Sortable fieldsets (since v3.0)

Set the property 'sortAttribute' to your db-field for sorting (should be an integer) if you want to order the items by drag/drop manually. Uses jQuery UI sortable, but works only when 'tableView' is false. See the demo.

$this->widget('ext.multimodelform.MultiModelForm',array(
       ...
        'sortAttribute' => 'position', //if assigned: sortable fieldsets is enabled
       ...
    ));

Property showAddItemOnError (since v3.0)

Regarding to requests and workarounds in the forum topic:

A user should not be able to add/clone items, when in error mode (model rules not passed successfully). Now you can set the property $showAddItemOnError to false to enable this behavior. See the demo.

Properties allowAddItem and allowRemoveItem (since v3.1)

For example, if you only want to allow an admin user to add new items or remove items, you can use these properties to display the addlink and the removelinks

$this->widget('ext.multimodelform.MultiModelForm',array(
       ...
       'allowAddItem' => Yii::app()->user->isAdmin(),
       'allowRemoveItem' => Yii::app()->user->hasRole('admin'),
       ...
    ));

Checkboxes

Unfortunatly the basic checkbox is not supported, because it's not so easy to handle (see the comments in the forum).

But if you need checkboxes, you can use the checkboxlist - see the demo.3.2 If you only need a single checkbox you can set the item-data to an array with one item.

In the view / formConfig:

$memberFormConfig = array(
          'elements'=>array(
 
             ...
            'flags'=>array(
              'type'=>'checkboxlist',
              'items'=>array('1'=>'Founder','2'=>'Developer','3'=>'Marketing'), //One single checkbox: array('1'=>'Founder')
              ),
        ));

In the model you have to convert array <-> string on saving/loading - see the Member model in the demo

/*
     * Convert the flags array to string
     */
    public function beforeSave()
    {
        if(parent::beforeSave())
        {
            if(!empty($this->flags) && is_array($this->flags))
                $this->flags = implode(',',$this->flags);
 
            return true;
        }
 
        return false;
    }
 
   /*
    * Convert the flags string to array
    */
   public function afterFind()
   {
       $this->flags = empty($this->flags) ? array() : explode(',',$this->flags);
   }

Notes

  • Take a look at MultiModelForm.php for more options of the widget.

  • The widget never will render a form begin/end tag. So you have always to add $this->beginWidget('CActiveForm',...) ... $this->endWidget in the view.

  • The implementation of the class MultiModelEmbeddedForm needs review in upcoming Yii releases. In 1.1.6+ the only output of CActiveForm.init() and CActiveForm.run() is the form begin and end tag.

  • The extension should work for non activerecord models too: instances of CModel, CFormModel...

  • You can add more widgets for rendering other models in the form view. Take care to assign a unique widget id when adding more multimodelform widgets.

  • Use Yii::app()->controller->action->id or $model->scenario to generate different forms for your needs (readonly fields on update ...)

Ressources

Changelog

  • v3.3
    • Correct support for the options['limit'] property from relcopy.js. See property limitText.
  • v3.2
    • New property 'hideCopyTemplate' (default:true), means that the empty copyTemplate is not visible
    • New demo with CheckBoxList
  • v3.1
    • New: Added properties $allowAddItem and $allowRemoveItem
    • Bugfix: hidden fields in the Tableheader no more displayed
    • Bugfix: Strings as elements formconfig (htmlttags,CFormStringElement) have not been rendered
  • v3.0

    • New: Added sortable feature for fieldsets (not in table view)
    • New: Property $showAddItemOnError=true; Show 'Add item' link and empty item in errormode
    • New: Demo with sortable fieldsets
    • Bugfixes: visible/hidden fields
  • v2.2.1 Bugfix: Array elements need extra 'allEmpty' check 

  • v2.2
    • Support for array elements (checkboxlist, radiolist) in form config These elements didn't work on creating only on update
  • v2.1.1
    • Bugfix - Labels of hidden elements have been rendered
  • v2.1
    • Bugfix - tableView: Hidden input have been rendered into a cell
    • Changed parameters and handling of MultiModelForm::save
  • v2.0.1 Bugfix: Tableheader displayed hidden fields too. Better internal handling of labels, now supports required '*'
  • v2.0 Added 'tableView' and support for cloning date/time widgets
  • v1.0.2 Bugfix: Detailrecord was created twice on creating master
  • v1.0.1 Bugfix 'Undefined Index','Undefined variable' when error_reporting(E_ALL) is set

Total 20 comments

#7301 report it
fr0d0z at 2012/03/12 01:28pm
Wouldn't it be simpler / cleaner

to add this to your config file:

// autoloading model and component classes
'import'=>array(
    'application.models.*',
    'application.components.*',
......
    'ext.multimodelform.MultiModelForm',

instead of using:

Yii::import('ext.multimodelform.MultiModelForm');

in your controller? Yii will handle the autoloading as needed, so using the actual import line seems redundant / leads to messier controllers ...

#7095 report it
th3r00st3r at 2012/02/23 12:10pm
Thanks for the forum topic link.

Didn't know there was one..

#7094 report it
joblo at 2012/02/23 11:52am
formbuilder

This is an issue of how to create forms with the formbuilder. Please post it in the forum, or in the multimodelform topic

In this case, I would first work with the form builder to generate a form you like and afterwards integrate this detailform in the multimodelform.

#7093 report it
th3r00st3r at 2012/02/23 11:36am
Formatting Radio Buttons..

I have radio button in the widget, but I would like them displayed horizontally. I tried 'display'=>'inline', but it didn't work:

'ratingid'=>array(
            'type'=>'radiolist',
            'items'=>PerfReview::model()->getRatingOptions(),
            //'prompt'=>'Please Select Rating:',
            'display'=>'inline' **//This doesn't work**
        ),

Any Suggestions?

#6559 report it
jmariani at 2012/01/18 02:44pm
Fieldset

Hi.

This extension really rocks. I have a question. How to embed the detail into a fieldset?

Regards!

#6505 report it
yii at 2012/01/15 02:41pm
Customizing form

Hi Joe, danke für die super Externsion. Gibt es eine Anleitung wie man die das Aussehen / die Form der Extension anpassen kann? Ich würde gerne meine eigene Tabelle verwenden und komme mit der Datei nicht klar. Wünschenswert wäre auch das jede Klasse eine eigene Datei hätte und es eine Datei für die Ausgabe der Extension gäbe. Ich benutze die Version 3.0 thx!

#6054 report it
joblo at 2011/12/08 08:36am
issues
#6034 report it
LiuXuan at 2011/12/07 04:57am
IDENTITY_INSERT issue when adding new member

Thank you for the nice extension. I met two issues when using this, I have master class 'Team' like the 'Group' in demo and 'User' like the 'Member' describe in demo. issue 1: my backend database is sqlserver, where the User table has id column which is auto increment identity,

with the extension, I can update user within a team,but when add a new user, the error occurs as: CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: [Microsoft][SQL Server Native Client 10.0][SQL Server]Cannot insert explicit value for identity column in table 'user' when IDENTITY_INSERT is set to OFF.. The SQL statement executed was: INSERT INTO [dbo].[user] ([username], [email], [password], [phone], [mobile], [id], [team_id]) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6)

issue 2: How can I only show some attributes (e.g, only reuired column) in detail form instead of currently, it shows all columns of Users table

Looking forward to helping on this

#4275 report it
joblo at 2011/06/21 01:54pm
Great

It would be nice if you upload the full file into the forum topic (see resource) so that I can integrate the fileupload feature in the next release. Maybe you can add a simple full example too.

#4268 report it
dinhtrung at 2011/06/21 09:32am
File Upload Support

I have extend the MultimodelForm to support File upload using CUploadedFile.

diff -r 5d49e1ab920f protected/extensions/multimodelform/MultiModelForm.php
--- a/protected/extensions/multimodelform/MultiModelForm.php    Tue Jun 21 11:20:50 2011 +0700
+++ b/protected/extensions/multimodelform/MultiModelForm.php    Tue Jun 21 20:24:17 2011 +0700
@@ -346,8 +346,9 @@
     */
 
    public function initItems(&$validatedItems,&$deleteItems, $masterValues = array(),$formData = null)
 
    {
 
-       if (!isset($formData))
 
+       if (!isset($formData)){
 
            $formData = $_POST;
 
+       }
 
 
 
        $result = true;
 
        $newItems = array();
 
@@ -371,8 +372,9 @@
                $model->attributes = $attributes;
 
 
 
                foreach ($this->fileAttributes as $attribute) {
 
-                   $model->attribute = CUploadedFile::getInstances($this->model, "[n__][$idx]" . $attribute);
 
-                   if (count($model->attribute) == 1) $model->attribute = $model->attribute[0];
 
+                   $files = CUploadedFile::getInstances($this->model, "[n__][$idx]" . $attribute);
 
+                   if (! empty($files)) $model->attribute = $files;
 
+                   if (count($files) == 1) $model->attribute = $files[0];
 
                }
 
 
 
 
 
@@ -406,8 +408,9 @@
                $model->attributes = $attributes;
 
 
 
                foreach ($this->fileAttributes as $attribute) {
 
-                   $model->attribute = CUploadedFile::getInstances($this->model, "[u__][$idx]" . $attribute);
 
-                   if (count($model->attribute) == 1) $model->attribute = $model->attribute[0];
 
+                   $files = CUploadedFile::getInstances($this->model, "[u__][$idx]" . $attribute);
 
+                   if (! empty($files)) $model->attribute = $files;
 
+                   if (count($files) == 1) $model->attribute = $files[0];
 
                }
 
 
 
                if (!empty($masterValues))
 
@@ -448,10 +451,6 @@
 
 
        // use the first item as reference
 
        $refAttribute = key($formData[$modelClass]);
 
-       $uploadFiles = array();
 
-       foreach ($this->fileAttributes as $attribute) {
 
-           $uploadFiles[$attribute] = CUploadedFile::getInstances($this->model, $attribute);
 
-       }
 
        $refArray = array_shift($formData[$modelClass]);
 
 
 
 
 
@@ -478,8 +477,10 @@
 
 
            foreach ($formData[$modelClass] as $attrKey => $values){
 
                $model->$attrKey = $values[$idx];
 
-               if (! empty($uploadFiles[$attrKey][$idx])) {
 
-                   $model->$attrKey = $uploadFiles[$attrKey][$idx];
 
+               if (in_array($attrKey, $this->fileAttributes)){
 
+                   $files = CUploadedFile::getInstances($model, $attrKey);
 
+                   if (! is_null($files)) $model->$attrKey = $files;
 
+                   if (count($files) == 1) $model->$attrKey = $files[0];
 
                }
 
            }

Let's use a model to store our file.

/**
* @property CUploadedFile name : Use as the input file.
* @property string title : File title
* @property string path : File directory
* @property string description : File description
*/
class FileManager extends CActiveRecord {
   ...
   protected function beforeValidate(){
      if ($this->name instanceof CUploadedFile){
          $this->name->saveAs($this->path . DIRECTORY_SEPARATOR . $this->name->name);
      }
      return parent::beforeValidate();
   }
}

And in your view, use the CForm element like this.

'elements'  =>  array(
        'name'  =>  array(
            'type'  =>  'file',
        ),
        'path' => array(
            'type'  => 'text',
                        'size'  => 50,
            'length' => 255,
        ),
        'title' => array(
            'type'  => 'text',
                        'size'  => 20,
            'length' => 80,
        ),
        'description' => array(
            'type'  => 'text',
                        'size'  => 50,
            'length' => 255,
        ),
    )
#4147 report it
dinhtrung at 2011/06/09 04:23am
The new version really rocks

With validate and save separated, I can modify the validated items with correct data. I'll try with fileField, and report back asap. Thanks again. This extension really awesome.

#4119 report it
joblo at 2011/06/07 09:14pm
Update 2.1

feby_lho:

Now you should be able to alter the data between 'validate' and 'save'. See usage validate/save above.

dinhtrung/feby_lho: Sorry, I don't have the time yet to investigate the javascript stuff for cloning autocomplete (I have tried a few hours without a result) or filefields.

You have to play around with jsAfterNewId ... to hook into the js-code on cloning. Take a look at the code of MultiModelForm::afterNewIdDatePicker that returns the necessary js-code. Maybe it can be easy done with filefields, not easy with autocomplete :-(

#4087 report it
feby_lho at 2011/06/05 04:00am
validatedItems

Still can't get it right at line 335, since you reset the array to null, and get error if I uncomment this line I think this validatedItems don't have to be as parameter in your function, am I correct? you set the attributes from the form anyway,

foreach ($formData[$modelClass]['n__'] as $idx => $attributes)
{ ... $model->attributes = $attributes; ....}

and you change the data type of validatedItems from array to modelclass in validate(), any solutions to set value like my comment #3925 below from controller? I'm stuck.

thanks

#4084 report it
dinhtrung at 2011/06/04 12:49pm
Greate Extension. How about file upload?

I've tried your extension and it works great for post data and all. But how can I get multimodelform to work with file field? I can only render the view with file field, but could not make my model understand to process the upload file correctly. Any suggestion?

#3939 report it
feby_lho at 2011/05/23 06:21am
great

it'll be great idea and I'm looking forward for the autocomplete feature too

#3926 report it
joblo at 2011/05/22 11:51am
$validatedItem is only out parameter

What you want to do cannot work, because your $validatedDetail is an out parameter.

Take a look at line 335 - method initItems: I have added a line to reset the $validatedItems as a bugfix v1.0.2, because detailrecords where created twice if I call 'MultiModelForm::validate' and 'MultiModelForm::save' in the usage comment above on 'actionCreate'.

So you can comment this line an see what happens.

Maybe I find another workaround like adding onBeforeSave ... to alter attribute values before saving.

#3925 report it
feby_lho at 2011/05/22 03:50am
passing parameter

hi, I have some problems,

//...some code like example
if ($validDetail && empty($validatedDetail))
            {
                Yii::app()->user->setFlash('error','No detail submitted.');
                $validDetail = false;
            }
            foreach($validatedDetail as $item)
            {
                $temp = ItemCardStock::model()->getLastData($item->item_id);
                if (!$temp)
                {
                    Yii::app()->user->setFlash('error','Invalid request.');
                    $validDetail = false;
                }
            }
            if($validDetail && $model->save())
            {
                $masterValues = array ('usage_id'=>$model->usage_id);
                foreach($validatedDetail as $item)
                {
                                       // ...some code
                                     $item->subtotal = $stock->subprice;
                                      // subtotal is in detail, it's value not from user input, I set the value just like that
                                 }
                                 foreach($validatedDetail as $item)
                    print_r($item->attributes);
                                  //test print_r the value of subtotal and each has a value
                                 if(MultiModelForm::save($detail,$validatedDetail,$masterValues))       $this->redirect(array('view','id'=>$model->usage_id));
                                  // somewhat every subtotal became NULL and 
                          }

and get error

CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'subtotal' cannot be null. The SQL statement executed was: INSERT INTO item_usage_detail (item_id, quantity, detail_id, usage_id, subtotal) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4)

what I'm missing here? thanks

#3885 report it
joblo at 2011/05/17 05:55pm
fixed

The issue of showing hidden fields in the table header is fixed in v2.0.1.

And also fixed: Now the '*' will be added to the label of required attributes.

#3884 report it
feby_lho at 2011/05/17 03:15pm
table view

one more question :D, I tried tableView and like example above, my purchase_detail has some columns that I don't want to show/don't need user input, but tableView seems to show all the columns, its' showed only as table header and don't have input area like others that I set in formConfig, how can I remove this?

thanks again

#3883 report it
joblo at 2011/05/17 02:06pm
Should be easy

When you call MultiModelForm::validate the 'validatedMembers' will be populated with all detailmodels submitted by the form. Some of this models can have errors (checked by the rules). So additionally you can check if validatedMembers is an empty array.

$detailOK = MultiModelForm::validate($member,$validatedMembers,$deleteItems);
  if ($detailOK && empty($validatedMembers))
    {
      Yii::app()->user->setFlash('error','No detail submitted');
       $detailOK = false;
    }
 
  if( $detailOK && $model->save()) //save the master
  {
        //save the details and redirect
  }
...
 
$this->render('create', ...)

You have to display the users flash messages in the view too.

Leave a comment

Please to leave your comment.

Create extension