Multimodelform

Hi,

I can insert many values for members using multimodelform extension. Later a need to remove one maybe more, but when i remove this items in client side from members using update action, that items exist still in database, they were updated to empty values.

Master-> Clientetarjeta

Members-> ClienteNumerotelefono

form ajaxvalidation is enabled;




	public function actionCreate() {

                

		$model = new Cliente;

                $clientepreguntasecreta = new ClientePreguntaSecreta;

                $clientetarjeta = new ClienteTarjeta;

                $clientenumerotelefono = new ClienteNumerotelefono;

                $validatedMembers = array();


               

		$this->performAjaxValidation(array($model,$clientepreguntasecreta,$clientetarjeta), 'cliente-form');


		if (isset($_POST['Cliente'],$_POST['ClientePreguntaSecreta'],$_POST['ClienteTarjeta'],$_POST['ClienteNumerotelefono'])) {

			$model->setAttributes($_POST['Cliente']);

                        $clientepreguntasecreta->setAttributes($_POST['ClientePreguntaSecreta']);

                        $clientetarjeta->setAttributes($_POST['ClienteTarjeta']);

                        $clientenumerotelefono->setAttributes($_POST['ClienteNumerotelefono']);


                        $valid = $model->validate();

                        $valid = $clientepreguntasecreta->validate();

                        $valid = $clientetarjeta->validate() && $valid;

                       

                        

                        $detailOK = MultiModelForm::validate($clientenumerotelefono,$validatedMembers,$deleteItems);

                       


			if ($valid && $detailOK) {

                                if ($model->save(false))

                                {

                                    $clientepreguntasecreta->idcliente = $model->idcliente;

                                    $clientepreguntasecreta->save(false);

                                    $clientetarjeta->idcliente = $model->idcliente;

                                    $clientetarjeta->idusuario = 1;                             

                                     

                                        if (empty($validatedMembers)){

                                           

                                            $clientetarjeta->save(false);

                                          

                                            $this->redirect(array('view','id'=>$model->idcliente));

                                        }

                                        else{

                                        if ($detailOK && $clientetarjeta->save(false)){

                                            $masterValues = array ('idcliente_tarjeta'=>$clientetarjeta->idcliente_tarjeta);

                                            

                			    if (MultiModelForm::save($clientenumerotelefono,$validatedMembers,$deleteItems,$masterValues)){

                                                $this->redirect(array('view','id'=>$model->idcliente));

                                            }

                                        }

                                        }

                                        

                                }

		

			}

		}


		$this->render('create', array( 'model' => $model,'clientepreguntasecreta'=>$clientepreguntasecreta,

                    'clientetarjeta'=>$clientetarjeta,'clientenumerotelefono'=>$clientenumerotelefono,

                    'validatedMembers' => $validatedMembers));

	}






public function actionUpdate($id) {


               

        

		$model = $this->loadModel($id, 'Cliente');

                $clientepreguntasecreta = $this->loadModel($id, 'ClientePreguntaSecreta');

                $clientetarjeta = $this->loadModel($id, 'ClienteTarjeta');

                $clientenumerotelefono =  $this->loadModel($clientetarjeta->idcliente_tarjeta, 'ClienteNumerotelefono');

                $validatedMembers = array();


		


                $this->performAjaxValidation(array($model,$clientepreguntasecreta,$clientetarjeta), 'cliente-form');




		if (isset($_POST['Cliente'],$_POST['ClientePreguntaSecreta'],$_POST['ClienteTarjeta'],$_POST['ClienteNumerotelefono'])) {

			$model->setAttributes($_POST['Cliente']);

                        $clientepreguntasecreta->setAttributes($_POST['ClientePreguntaSecreta']);

                        $clientetarjeta->setAttributes($_POST['ClienteTarjeta']);

                        

                        if (!empty ($clientenumerotelefono)){

                            $clientenumerotelefono->setAttributes($_POST['ClienteNumerotelefono']);

                        }


                        $valid = $model->validate();

                        $valid = $clientepreguntasecreta->validate();

                        $valid = $clientetarjeta->validate() && $valid;

                        


                        $detailOK = MultiModelForm::validate($clientenumerotelefono,$validatedMembers,$deleteItems);


			if ($valid && $detailOK) {

                                if ($model->save(false))

                                {

                                    $clientepreguntasecreta->idcliente = $model->idcliente;

                                    $clientepreguntasecreta->save(false);

                                    $clientetarjeta->idcliente = $model->idcliente;

                                    $clientetarjeta->idusuario = 1;


                                   

                                    

                                     if (empty($validatedMembers)){

                                          

                                            $clientetarjeta->save(false);

                                           

                                            $this->redirect(array('view','id'=>$model->idcliente));

                                     }

                                     if ($detailOK){

                                            $clientetarjeta->save(false);

                                            $masterValues = array ('idcliente_tarjeta'=>$clientetarjeta->idcliente_tarjeta);

                                            

                			    if (MultiModelForm::save($clientenumerotelefono,$validatedMembers,$deleteItems,$masterValues)){

                                                $this->redirect(array('view','id'=>$model->idcliente));

                                            }

                                        

                                        }

                           


                                }

                	}

		}



Recently I had similar problems with my multimodelform where I am using 3 models. After trying to figure out why things are not working correctly without success I finally decided to install Xdebug and solved problem within an hour. The problem was in validation and some stupid copy/paste errors which I made.

In your case I see that you are doing assignments from $_POST for more models what is actually not necessary as it is done by multimodelform automatically as it looks through whole $_POST ins several steps. In my attempts to get things working I also did the same things but without success.

I have attached the controller code which is working. As I have already said, I am using 3 models and also Eselect2 dropdown which was also causing a lot of problems before I found the solution how to multiply it. In my case I had also problems with the initialization of hidden fields, which are initialized to predefined values and are not entered by the user. I found that the most elegant solution is to overwrite beforeValidate method in the models with my own. Any other solution caused problems during validation.

Besides the code in the controller take a close look to the validation rules in your models as most likely they are causing validation problems as well.

I have also changed the position of link for adding new records in multimodelform which is now located at the bottom what is much more logically.




/**

 * Creates a new model.

 * If creation is successful, the browser will be redirected to the 'view' page.

 */

public function actionCreate()

{

	

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


	$model = new ObiskiTerena;

			

	//define other two models

	$popisovalec = new ObiskiTerenaPopisovalci;

	$validatedPopisovalci = array();  //ensure an empty array


	$opazovanje = new Opazovanja;

	$validatedOpazovanja = array();  //ensure an empty array

	

	$this->performAjaxValidation($model);

	

	if(isset($_POST['ObiskiTerena']))

	{

		$model->attributes=$_POST['ObiskiTerena'];

			

		// validate each of details before saving the master

		$okPopisovalci = MultiModelForm::validate($popisovalec,$validatedPopisovalci,$deletedPopisovalci);

		$okOpazovanja =  MultiModelForm::validate($opazovanje,$validatedOpazovanja,$deletedOpazovanja);

		

		if( $okOpazovanja && empty($validatedOpazovanja)) {

			Yii::app()->user->setFlash('error','Manjkajo podatki o opazovanjih');

			$okOpazovanja = false;

		}


		if( $okPopisovalci && empty($validatedPopisovalci)) {

			Yii::app()->user->setFlash('error','Manjkajo podatki o popisovalcih');

			$okPopisovalci = false;

		}

		//first save master to get the primary key which will be used as foreign key in other models    

		if ( $okPopisovalci  && $okOpazovanja  &&   $model->save() )

		{

			//the value for the foreign key 'id_obiska'

			$masterValues = array ('id_obiska'=>$model->id_obiska);

			$masterValues2 = array ('id_obiska'=>$model->id_obiska);

			// Save detail one and two and redirect

			if (MultiModelForm::save($popisovalec,$validatedPopisovalci,$deletedPopisovalci,$masterValues) &&

				MultiModelForm::save($opazovanje,$validatedOpazovanja,$deletedOpazovanja,$masterValues2) )

				$this->redirect(array('admin','id'=>$model->id_obiska));

		}

	}


	$this->render('create',array(

			'model'=>$model,

			//submit the models and validatedItems to the widget in the edit form

			'popisovalec'=>$popisovalec,

			'opazovanje'=>$opazovanje,

			'validatedPopisovalci' => $validatedPopisovalci,

			'validatedOpazovanja' => $validatedOpazovanja,

	));


}


/**

 * 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)

{

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


	$model=$this->loadModel($id); //the ObiskiTerena model


	$popisovalec = new ObiskiTerenaPopisovalci;

	$validatedPopisovalci = array(); //ensure an empty array

	

	$opazovanje = new Opazovanja;

	$validatedOpazovanja = array();  //ensure an empty array

	

	if(isset($_POST['ObiskiTerena']))

	{

		

		$model->attributes=$_POST['ObiskiTerena'];

					

		//the values for the foreign keys - in this case they are the same as both tables have same parent table 

		$masterValues = array ('id_obiska'=>$model->id_obiska);

		$masterValues2 = array ('id_obiska'=>$model->id_obiska);

			

		$okPopisovalci = MultiModelForm::validate($popisovalec,$validatedPopisovalci,$deletedPopisovalci);

		$okOpazovanja =  MultiModelForm::validate($opazovanje,$validatedOpazovanja,$deletedOpazovanja);

		

		if ($okPopisovalci && $okOpazovanja ) {

			

			//Save the master model after saving valid members

			$savedPopisovalci = MultiModelForm::save($popisovalec,$validatedPopisovalci,$deletedPopisovalci,$masterValues);

			$savedOpazovanja = MultiModelForm::save($opazovanje,$validatedOpazovanja,$deletedOpazovanja,$masterValues2);

			

			if( $savedPopisovalci && $savedOpazovanja &&

					//now save the ObiskiTerena as last one

					$model->save() ) {

					$this->redirect(array('admin','id'=>$model->id_obiska));

			}

		}

	}


	$this->render('update',array(

			'model'=>$model,

			//submit the models and validatedItems to the widget in the edit form

			'popisovalec'=>$popisovalec,

			'opazovanje'=>$opazovanje,

			'validatedPopisovalci' => $validatedPopisovalci,

			'validatedOpazovanja' => $validatedOpazovanja,

	));

}