Seems you have to debug through the method renderFormElements().
An element should only be rendered if it has a ‘name’ means it is an attribute of the model.
The ‘<hr>’ element is type of CFormStringElement and will not be rendered to the output and ‘required’ will not be checked.
protected function renderFormElements()
{
$output = '';
$elements = $this->getElements();
foreach ($elements as $element)
{
if (isset($element->name)) //element is an attribute of the model
{
$elemName = $element->name;
...
}
}
else //CFormStringElement... Bugfix in the next release
$output .= $element->render();
But there is a bug, because <hr/> will not be rendered, so I have to add the ‘else’ part.
I made the above post almost a year ago, and it is now fixed unfortunately, I think this preceeded to break checkboxes.
2628
In the attached image, you can see that yii has a hidden element and the checkbox both named Items[otherOpt][]
What this causes, is that the checkboxes get knocked off so if you check the first box, item 2 actually gets checked since the hidden field is 0 and the checkbox is 1.
2629
In update view, this is not a problem because the id is set so they don’t extend each other, but if you create more items with JS they don’t have the index set so it is a problem.
I think the only way to fix this would be to have JS include ids in the array.
Also, for some reason, the new items added by JS are now checked. I’m not sure what has caused this.
I’m happy to help with trying to code fixes, but I’m not exactly sure where to start. I feel like building in the array indexes will require quite a few code changes. Maybe it is just that the hidden fields for checkboxes need to be processed differently by the addon?
Thanks for adding the true/false to the ADD and Remove items, that helps alot since I am pre-populating the form and not allowing for additional records.
The issue I am seeing now is that I have one main record(1st model), and 28 sub records(2nd model) on the one form. It’s not saving the sub records above the 23rd record. I can edit the first 23 records, no problem, but any values I change on the 24th or above record doesn’t save the change. i don’t know if that number is consistent or not.
The question is, is there a limit to the number of records that you can edit on the 2nd model sub form?
edit
Also, is there a way to have paging on the 2nd model?
After I turned on the warnings, firebug output the following:
Use of getAttributeNode() is deprecated. Use getAttribute() instead.
Use of getAttributeNodeNS() is deprecated. Use getAttributeNS() instead.
No, the console window is empty. It’s strange, the first 20 or so records I will save the update, the ones past that will not.
Here’s some sample code from the controller:
public function actionUpdate($id)
{
Yii::import('ext.multimodelform.MultiModelForm');
$model=$this->loadModel($id); //The Performance Review model
$perfreviewsub = new PerfReviewSub;
$validatedPerfreviewsub = array(); //ensure an empty array
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model,$perfreviewsub);
if(isset($_POST['PerfReview']))
{
$model->attributes=$_POST['PerfReview'];
//the value for the foreign key 'performancereviewid'
$masterValues = array ('performancereviewid'=>$model->performancereviewid);
if(//Save the parent model after saving child sub records
MultiModelForm::save($perfreviewsub,$validatedPerfreviewsub,$deletePerfreviewsub,$masterValues) &&
$model->save()
)
$this->redirect(array('update','id'=>$model->performancereviewid));
}
$this->render('update',array(
'model'=>$model,
//submit the sub and validatedItems to the widget in the edit form
'perfreviewsub'=>$perfreviewsub,
'$validatedPerfreviewsub' => $validatedPerfreviewsub,
));
}
And here’s the code from the _form
$perfreviewsubFormConfig = array(
'elements'=>array(
'standardname'=>array(
'id'=>'standardid',
'label'=>'Standard',
'type'=>'textarea',
'rows'=>'4',
'cols'=>'65',
'disabled'=>'disabled',
'resize'=>'none'
),
'elementname'=>array(
'label'=>'Element',
'type'=>'textarea',
'rows'=>'4',
'cols'=>'65',
'disabled'=>'disabled',
),
'ratingid'=>array(
'type'=>'radiolist',
'items'=>PerfReview_Admin::model()->getRatingOptions(),
//'prompt'=>'Please Select Rating:',
),
));
$this->widget('ext.multimodelform.MultiModelForm',array(
'id' => 'id_perfreviewsub2', //the unique widget id
'tableView' => true,
'formConfig' => $perfreviewsubFormConfig, //the form configuration array
'model' => $perfreviewsub, //instance of the form model
//if submitted not empty from the controller,
//the form will be rendered with validation errors
'validatedItems' => $validatedPerfReviewSub,
//array of perfreviewsub instances loaded from db
'data' => $perfreviewsub->findAll('(performancereviewid=:performancereviewid) order by standardid, elementid', array(':performancereviewid'=>$model->performancereviewid)),
));
There are only 3 columns on the 2nd model (sub records), and only the ratingid gets updated. The first two columns are pre-populated and are disabled.
Here is the code from the form file which should be enough to emulate it since all you should need to do is add a checkbox field to the form and it should start messing up.
<?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
$itemFormConfig = array(
'elements'=>array(
'item'=>array(
'type'=>'text',
'maxlength'=>50,
),
'bringing'=>array(
'type'=>'text',
'maxlength'=>32,
),
'otherOpt'=>array(
'type'=>'checkbox',
),
'other'=>array(
'type'=>'text',
'maxlength'=>50,
),
'order'=>array(
'type'=>'text',
'maxlength'=>3,
'size'=>2
),
)
);
$this->widget('ext.multimodelform.MultiModelForm',array(
'id' => 'id_items', //the unique widget id
'formConfig' => $itemFormConfig, //the form configuration array
'model' => $item, //instance of the form model
//if submitted not empty from the controller,
//the form will be rendered with validation errors
'validatedItems' => $validItems,
'tableView' => true,
//array of member instances loaded from db
'data' => $item->findAll(array(
'condition' => 'menu_id=:menuId',
'params' => array(':menuId'=>$model->id),
'order' => '`order` asc'
)),
));
?>
If not, I have also zipped my whole application and attached it. (Don’t worry, passwords were removed first.)
Ok, I did a print_r() in the Save function of the MultiModelForm.php like so:
//if sortable, assign the sortAttribute
if (!empty($sortAttribute))
{
$sortIndex++;
$item->$sortAttribute = $sortIndex;
}
print_r($item);
if (!$item->save())
return false;
There are 38 records total and the record id’s I have on the form of the 2nd model are 1677-1714.
I reviewed the output from print_r() and I see that it updates records 1677-1695 and 1695 is the last record output from the print_r() function. It does not print 1696-1714 as if it’s not looping through all the records when it saves.
I hope this makes sense and hope you can help. thanks!
Not to sound condescending, but whether or not I use the cloning feature of the model is irrelevant to the issue at hand. I like the ease of your extension, but just don’t need that particular feature on this particular form as the data is pre-populated. I will check the POST data to see if there is a limitation. Thanks for the tip!
EDIT You nailed it. unbeknownst to me, Suhosin was installed in the server. I changed the suhosin.post.max_vars = 2048 and suhosin.request.max_vars = 2048 in the suhosin.ini file and it worked! Thanks again for the extension and the tip!
Sorry, working in too many frameworks. I’ve been working in Django which creates the database from the code. I forgot Yii creates code from the database.