[EXTENSION] multimodelform/jqrelcopy Solutions for clientside cloning
#21
Posted 12 August 2011 - 12:21 PM
Thanks a lot. Sorry for not making clear on my second question. I am aware there is a option to add remove link in the rows which we clone. I am asking things in update mode. In update mode , i want to add a remove option in the rows which i reproduced. How to acheive that ?
#22
Posted 16 August 2011 - 12:03 PM
See ya.
#23
Posted 07 September 2011 - 10:46 PM
this is my form config
$detailFormConfig = array(
'elements'=>array(
'product_id'=>array(
'type'=>'dropdownlist',
'items'=>Product::model()->getProductOptions(),
'prompt'=>'-- Select Product --',
'onchange'=>'
var text = $("select#InvoiceDetail_product_id option:selected").html();
var last = text.lastIndexOf(" ");
var price = text.substring(last,text.length);
$("#InvoiceDetail_price").val(price);
',
),
'quantity'=>array(
'type'=>'text',
),
'price'=>array(
'type'=>'text',
),
'discount'=>array(
'type'=>'text',
'value'=>'0',
),
));That works just for first detail row, and about cloning the form as well as the javascipt code I don't really know how to do that with jsAfterClone etc. Name of the id is generated like copy1,copy2, and so on.. how can I get the specific cloned id like price and discount field
$this->widget('ext.multimodelform.MultiModelForm',array(
'tableView' => true,
'id' => 'id_detail', //the unique widget id
'formConfig' => $detailFormConfig, //the form configuration array
'model' => $detail, //instance of the form model
'jsAfterClone' => '
alert(this.attr(\'class\'));
// what/how to do in here?
// I want to do like above code, set the price and discount value
',
.....
thanks for the help
#24
Posted 08 September 2011 - 02:38 AM
See the code at line 90, when cloning the children.
Here you have to assign the onchange to the cloned elements.
When it's working, you can move the code to 'jsAfterClone' => '....' (=funcAfterNewId)
// Increment Clone Children IDs
$(clone).find('[id]').each(function(){
var newid = $(this).attr('id') + (counter +1);
funcBeforeNewId.call($(this));
$(this).attr('id', newid);
funcAfterNewId.call($(this));
... your testcode here ....
});
#25
Posted 13 September 2011 - 09:23 AM
I am getting an error "Array to String Conversion" on my multimodel form. This is the only form in my app that gives this error. I have another form that uses the same rules() and saves the information with no problem. Can you help me find the problem?
Here's my controller:
<?php
class memberController extends Controller
{
/**
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout='//layouts/column2';
/**
* @return array action filters
*/
public function filters()
{
return array(
'accessControl', // perform access control for CRUD operations
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update','create2'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
/**
* Displays a particular model.
* @param integer $id the ID of the model to be displayed
*/
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id),
));
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionCreate()
{
$model=new member;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['member']))
{
$model->attributes=$_POST['member'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
public function actionCreate2()
{
Yii::import('ext.multimodelform.MultiModelForm');
$model = new member;
$member = new member;
$validatedMembers = array(); //ensure an empty array
if(isset($_POST['member']))
{
$model->attributes=$_POST['member'];
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('create2',array(
'model'=>$model,
//submit the member and validatedItems to the widget in the edit form
'member'=>$member,
'validatedMembers' => $validatedMembers,
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/
public function actionUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['member']))
{
$model->attributes=$_POST['member'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
));
}
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* @param integer $id the ID of the model to be deleted
*/
public function actionDelete($id)
{
if(Yii::app()->request->isPostRequest)
{
// we only allow deletion via POST request
$this->loadModel($id)->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if(!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
else
throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
}
/**
* Lists all models.
*/
public function actionIndex()
{
$criteria = new CDbCriteria();
if(isset($_GET['qs']))
{
$qs = $_GET['qs'];
$criteria->compare('name', $qs, true, 'OR');
}
$dataProvider=new CActiveDataProvider("member", array('criteria'=>$criteria));
$this->render('index',array(
'dataProvider'=>$dataProvider,
'pagination'=>false,
$dataProvider->pagination->pageSize=50000000,
'name'=>'ajax',
));
}
/**
* Manages all models.
*/
public function actionAdmin()
{
$model=new member('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['member']))
$model->attributes=$_GET['member'];
$this->render('admin',array(
'model'=>$model,
));
}
/**
* Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised.
* @param integer the ID of the model to be loaded
*/
public function loadModel($id)
{
$model=member::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* @param CModel the model to be validated
*/
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='service-member-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
}
And here is the form:
<div class="form wide">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'bulk-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?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(
'name'=>array(
'type'=>'text',
'maxlength'=>40,
),
'rankLevel'=>array(
'type'=>'text',
'maxlength'=>40,
),
'Tag'=>array(
'type'=>'text',
'maxlength'=>40,
),
'dept'=>array(
'type'=>'text',
'maxlength'=>40,
),
'dateTag'=>array(
'type'=>'text',
'maxlength'=>40,
),
'date'=>array(
'type'=>'text',
'maxlength'=>40,
),
));
$this->widget('ext.multimodelform.MultiModelForm',array(
'id' => 'id_member', //the unique widget id
'formConfig' => $memberFormConfig, //the form configuration array
'model' => $servicemember, //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' => $servicemember->findAll('branchId=:branchId', array(':branchId'=>$model->id)),
));
?>
<div class="row">
<?php echo $form->labelEx($model,''); ?>
<?php echo $form->hiddenField($model,'ip3',array('value'=>Yii::app()->request->userHostAddress,)); ?>
<?php echo $form->labelEx($model,''); ?>
<?php echo $form->hiddenField($model,'branchId',array('value'=>1,)); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->Here's the stack trace:
Array to string conversion (D:\WAMP\www\yii-1.1.8.r3324\framework\db\CDbCommand.php:256) Stack trace: #0 D:\WAMP\www\yii-1.1.8.r3324\framework\db\schema\CDbCommandBuilder.php(98): CDbCommandBuilder->bindValues() #1 D:\WAMP\www\yii-1.1.8.r3324\framework\db\ar\CActiveRecord.php(1607): CDbCommandBuilder->createFindCommand() #2 D:\WAMP\www\yii-1.1.8.r3324\framework\validators\CUniqueValidator.php(97): member->exists() #3 D:\WAMP\www\yii-1.1.8.r3324\framework\validators\CValidator.php(192): CUniqueValidator->validateAttribute() #4 D:\WAMP\www\yii-1.1.8.r3324\framework\base\CModel.php(152): CUniqueValidator->validate() #5 D:\WAMP\www\yii-1.1.8.r3324\framework\db\ar\CActiveRecord.php(780): member->validate() #6 D:\WAMP\www\yii-1.1.8.r3324\APP\protected\controllers\memberController.php(97): member->save() #7 D:\WAMP\www\yii-1.1.8.r3324\framework\web\actions\CInlineAction.php(50): memberController->actionCreate2() #8 D:\WAMP\www\yii-1.1.8.r3324\framework\web\CController.php(300): CInlineAction->runWithParams() #9 D:\WAMP\www\yii-1.1.8.r3324\framework\web\filters\CFilterChain.php(134): memberController->runAction() #10 D:\WAMP\www\yii-1.1.8.r3324\framework\web\filters\CFilter.php(41): CFilterChain->run() #11 D:\WAMP\www\yii-1.1.8.r3324\framework\web\CController.php(1144): CAccessControlFilter->filter() #12 D:\WAMP\www\yii-1.1.8.r3324\framework\web\filters\CInlineFilter.php(59): memberController->filterAccessControl() #13 D:\WAMP\www\yii-1.1.8.r3324\framework\web\filters\CFilterChain.php(131): CInlineFilter->filter() #14 D:\WAMP\www\yii-1.1.8.r3324\framework\web\CController.php(283): CFilterChain->run() #15 D:\WAMP\www\yii-1.1.8.r3324\framework\web\CController.php(257): memberController->runActionWithFilters() #16 D:\WAMP\www\yii-1.1.8.r3324\framework\web\CWebApplication.php(277): memberController->run() #17 D:\WAMP\www\yii-1.1.8.r3324\framework\web\CWebApplication.php(136): CWebApplication->runController() #18 D:\WAMP\www\yii-1.1.8.r3324\framework\base\CApplication.php(158): CWebApplication->processRequest() #19 D:\WAMP\www\yii-1.1.8.r3324\APP\index.php(25): CWebApplication->run() REQUEST_URI=/yii-1.1.8.r3324/APP/index.php/member/create2
I really hope I can get this fixed as I need tabular input.
As you can probably see in the controller, I copied your sample code from the readme and simply added my model names, etc.
#26
Posted 14 September 2011 - 04:57 PM
See line 97: $model->save()
D:\WAMP\www\yii-1.1.8.r3324\APP\protected\controllers\memberController.php(97): member->save()
There is a problem on validating the $model - see the stack trace: 'member->exists()' (CUniqueValidator).
You should do a var_dump to take a look at the properties of the $model variable.
if(isset($_POST['member']))
{
$model->attributes=$_POST['member'];
var_dump($model); die();
.....
#27
Posted 14 September 2011 - 11:29 PM
Queryton, on 14 September 2011 - 10:24 PM, said:
If you can't answer this question (I know it's my code and my fault if there is something wrong) can you atleast tell me how to pull the "member" table into the main view? (group/index only displays the Group database. How can this be both Group and Member??)
You tell in the instructions to change the actionUpdate and actionCreate, but nothing about actionView or actionIndex.
EDIT: To make it clearer (and not trying to sound mean or demanding) what is the point of adding multiple entries if I cannot index them. How can I do so?
#28
Posted 16 September 2011 - 01:22 AM
It's the same as you would display 'posts' and 'comments'.
#29
Posted 16 September 2011 - 07:53 AM
Joblo, on 16 September 2011 - 01:22 AM, said:
It's the same as you would display 'posts' and 'comments'.
Ok will do. Thanks.
#30
Posted 20 September 2011 - 01:18 PM
#31
Posted 20 September 2011 - 01:34 PM
See:
Tabular Input
How to use a single form to collect data for two or more models?
#32
Posted 21 September 2011 - 03:26 AM
Superb extension. I tried Group-Member example and it works fine for CREATE, UPDATE. How to i get it work for DELETE operation? Right now when i delete it removes only the Group record and not the related Member records.
Thanks
#33
Posted 21 September 2011 - 03:40 AM
Set the definition of the foreign keys: OnDelete -> cascade
#34
Posted 21 September 2011 - 04:43 AM
Joblo, on 21 September 2011 - 03:40 AM, said:
Set the definition of the foreign keys: OnDelete -> cascade
Hi Joblo,
Thanks for your quick response. I tried your solution but still not working.
CREATE TABLE IF NOT EXISTS `member` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`groupid` int(11) NOT NULL,
`firstname` varchar(100) NOT NULL,
`lastname` varchar(100) NOT NULL,
`membersince` int(11) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`groupid`) REFERENCES `group`(`id`) ON DELETE CASCADE
);
#35
Posted 21 September 2011 - 05:21 AM
Maybe sqlite doesn't support this?
It should not be the job of the php-client to delete all members if a group is deleted.
But you can implement the onBeforeDelete/onAfterDelete event of the group model to delete the related members.
#36
Posted 21 September 2011 - 06:31 AM
One more query:
How do i change the layout of the member elements, in _form, from vertical to horizontal? i.e.firstname, lastname, membersince are shown in vertical. I want them all in one row(horizontally).
#37
Posted 21 September 2011 - 06:40 AM
$this->widget('ext.multimodelform.MultiModelForm',array(
...
'tableView' => true,
...
));
#38
Posted 22 September 2011 - 12:17 AM
Joblo, on 21 September 2011 - 06:40 AM, said:
$this->widget('ext.multimodelform.MultiModelForm',array(
...
...
));
I added 'tableView' => true, and i got it the way i want but i also get the unwanted field groupid in the header. How to get rid of it?
Also in update, i get a new formconfig elements without clicking on Add Item. How to resolve this too?
I have gone through your whole post, but could not fix the issues mentioned above. Please help me.
Thanks
#39
Posted 22 September 2011 - 02:06 AM
Try to change the code in line 831 of MultiModelForm.php to:
foreach($this->getElements() as $element)
if ($element->visible && $element->type != 'hidden')
{
....
Maybe $element->visible is not enough.
Clicking on 'AddItem' can only work, if there is an empty row added at the bottom of the other items.
So on updating I have to always add an empty item too, otherwise a user cannot add a new item in update mode.
But the empty row will not be saved.
#40
Posted 22 September 2011 - 02:52 AM
Joblo, on 22 September 2011 - 02:06 AM, said:
Try to change the code in line 831 of MultiModelForm.php to:
foreach($this->getElements() as $element)
if ($element->visible && $element->type != 'hidden')
{
....
Thanks the first issue is resolved
Quote
Clicking on 'AddItem' can only work, if there is an empty row added at the bottom of the other items.
So on updating I have to always add an empty item too, otherwise a user cannot add a new item in update mode.
But the empty row will not be saved.
If i try adding new item and save it throws an Integrity constraint violation error.

Help












