Master Detail Form Example

I want to share about how to create master detail form with Yii. I’ve implement for Capella ERP Indonesia.

GenjournalController.php




<?php


class GenjournalController 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';


	public function filters()

  {

    return array(

      'rights',

    );

  }


	/**

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

	{

	  $journaldetail=new Journaldetail('search');

	  $journaldetail->unsetAttributes();  // clear any default values

	  if(isset($_GET['Journaldetail']))

		$journaldetail->attributes=$_GET['Journaldetail'];


		$account=new Account('search');

	  $account->unsetAttributes();  // clear any default values

	  if(isset($_GET['Account']))

		$account->attributes=$_GET['Account'];


		$model=new Genjournal;

		$model->referenceno='Reference No';

		$model->journalnote='Journal Note';

		$model->recordstatus=0;

		if (Yii::app()->request->isAjaxRequest)

        {

			if ($model->save()) {

			  Yii::app()->session['genjournalid'] = $model->genjournalid;

			  echo CJSON::encode(array(

				  'status'=>'failure',

				  'genjournalid'=>Yii::app()->session['genjournalid'],

				  'divcreate'=>$this->renderPartial('_form', array('model'=>$model,

					'journaldetail'=>$journaldetail,

				  'account'=>$account), true)

				  ));

			  Yii::app()->end();

			}

        }

        else

		{

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

			'model'=>$model,

				  'journaldetail'=>$journaldetail,

				  'account'=>$account

		));

		}

	}


	public function actionCreatedetail()

	{

	  $account=new Account('search');

	  $account->unsetAttributes();  // clear any default values

	  if(isset($_GET['Account']))

		$account->attributes=$_GET['Account'];


		$journaldetail=new Journaldetail;

		$journaldetail->genjournalid=Yii::app()->session['genjournalid'];


		if (Yii::app()->request->isAjaxRequest)

        {

            echo CJSON::encode(array(

                'status'=>'failure',

				'genjournalid'=>$journaldetail->genjournalid,

                'divcreate'=>$this->renderPartial('_formdetail',

				  array('model'=>$journaldetail,'account'=>$account), true)

				));

            Yii::app()->end();

        }

        else

		{

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

			'model'=>$journaldetail,'account'=>$account

		));

		}

	}


	/**

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

	{

	  $journaldetail=new Journaldetail('search');

	  $journaldetail->unsetAttributes();  // clear any default values

	  if(isset($_GET['Journaldetail']))

		$journaldetail->attributes=$_GET['Journaldetail'];


		$account=new Account('search');

	  $account->unsetAttributes();  // clear any default values

	  if(isset($_GET['Account']))

		$account->attributes=$_GET['Account'];


		$id=$_POST['id'];

	  $model=$this->loadModel($id[0]);

	  Yii::app()->session['genjournalid']=$model->genjournalid;


		// Uncomment the following line if AJAX validation is needed


		if (Yii::app()->request->isAjaxRequest)

        {

            echo CJSON::encode(array(

                'status'=>'failure',

				'genjournalid'=>$model->genjournalid,

				'referenceno'=>$model->referenceno,

				'journaldate'=>$model->journaldate,

				'journalnote'=>$model->journalnote,

				'recordstatus'=>$model->recordstatus,

                'div'=>$this->renderPartial('_form', array('model'=>$model,

				  'journaldetail'=>$journaldetail,

				'account'=>$account), true)

				));

            Yii::app()->end();

        }

        else

		{

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

			'model'=>$model,

				  'journaldetail'=>$journaldetail,

				  'account'=>$account

		));

		}

	}


	public function actionUpdatedetail()

	{

	  	  $account=new Account('search');

	  $account->unsetAttributes();  // clear any default values

	  if(isset($_GET['Account']))

		$account->attributes=$_GET['Account'];


		$id=$_POST['id'];

	  $journaldetail=$this->loadModeldetail($id[0]);


		// Uncomment the following line if AJAX validation is needed


		if (Yii::app()->request->isAjaxRequest)

        {

            echo CJSON::encode(array(

                'status'=>'failure',

				'journaldetailid'=>$journaldetail->journaldetailid,

				'genjournalid'=>Yii::app()->session['genjournalid'],

				'accountid'=>$journaldetail->accountid,

				'accountcode'=>$journaldetail->account->accountcode,

				'accountname'=>$journaldetail->account->accountname,

				'debit'=>$journaldetail->debit,

				'credit'=>$journaldetail->credit,

                'div'=>$this->renderPartial('_formdetail',

				  array('model'=>$journaldetail,'account'=>$account), true)

				));

            Yii::app()->end();

        }

        else

		{

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

			'model'=>$journaldetail,

				  'account'=>$account

		));

		}

	}


	public function actionWrite()

	{

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

	  {

		$dataku->attributes=$_POST['Genjournal'];

		if ((int)$dataku->attributes['genjournalid'] > 0)

		{

		  $model=$this->loadModel($dataku->attributes['genjournalid']);

		  $model->referenceno = $dataku->attributes['referenceno'];

		  $model->journaldate = $dataku->attributes['journaldate'];

		  $model->journalnote = $dataku->attributes['journalnote'];

		  $model->recordstatus = $dataku->attributes['recordstatus'];

		}

		else

		{

		  $model = new Genjournal();

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

		  $model->genjournalid=Yii::app()->session['genjournalid'];

		}

		try

		{

		  if($model->save())

		  {

			if (Yii::app()->request->isAjaxRequest)

			  {

				echo CJSON::encode(array(

				  'status'=>'success',

				  'div'=>"Data saved"

				));

			  }

			  else

			  {

				Yii::app()->user->setflash($id, array('title' => 'Success', 'content' => 'Data Saved') );

				$this->redirect(array('index'));

			  }

		  }

		}

		catch (Exception $e)

		{

		  $errormessage=$model->getErrors();

		  if ($errormessage == '')

		  {

			$errormessage=$e->getMessage();

		  }

		  if (Yii::app()->request->isAjaxRequest)

		  {

			  echo CJSON::encode(array(

				'status'=>'failure',

                'div'=>$errormessage

              ));

          }

		}

	  }

	}


	public function actionWritedetail()

	{

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

	  {

		$dataku->attributes=$_POST['Journaldetail'];

		if ((int)$dataku->attributes['journaldetailid'] > 0)

		{

		  $model=Journaldetail::model()->findbyPK($dataku->attributes['journaldetailid']);

		  $model->genjournalid = Yii::app()->session['genjournalid'];

		  $model->accountid = $dataku->attributes['accountid'];

		  $model->debit = $dataku->attributes['debit'];

		  $model->credit = $dataku->attributes['credit'];

		}

		else

		{

		  $model = new Journaldetail();

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

		  $model->genjournalid=Yii::app()->session['genjournalid'];

		}

		try

		{

		  if($model->save())

		  {

			if (Yii::app()->request->isAjaxRequest)

			  {

				echo CJSON::encode(array(

				  'status'=>'success',

				  'div'=>"Data saved"

				));

			  }

			  else

			  {

				Yii::app()->user->setflash($id, array('title' => 'Success', 'content' => 'Data Saved') );

				$this->redirect(array('index'));

			  }

		  }

		}

		catch (Exception $e)

		{

		  $errormessage=$model->getErrors();

		  if (count($errormessage) == 0)

		  {

			$errormessage=$e->getMessage();

		  }

		  var_dump($errormessage);

		  if (Yii::app()->request->isAjaxRequest)

		  {

			  echo CJSON::encode(array(

				'status'=>'failure',

                'div'=>$errormessage

              ));

          }

		}

	  }

	}


	/**

	 * 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=$_POST['id'];

		foreach($id as $ids)

		{

		  $model=$this->loadModel($ids);

		  $model->recordstatus=0;

		  $model->save();

		}

		echo CJSON::encode(array(

                'status'=>'success',

                'div'=>'Data deleted'

				));

        Yii::app()->end();

	}


	/**

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

	{

		$id=$_POST['id'];

		foreach($id as $ids)

		{

		  $model=Journaldetail::model()->findbyPK($ids);

		  $model->delete();

		}

		echo CJSON::encode(array(

                'status'=>'success',

                'div'=>'Data deleted'

				));

        Yii::app()->end();

	}


	/**

	 * Lists all models.

	 */

	public function actionIndex()

	{

	  $account=new Account('search');

	  $account->unsetAttributes();  // clear any default values

	  if(isset($_GET['Account']))

		$account->attributes=$_GET['Account'];

	  $journaldetail=new Journaldetail('search');

	  $journaldetail->unsetAttributes();  // clear any default values

	  if(isset($_GET['Journaldetail']))

		$journaldetail->attributes=$_GET['Journaldetail'];

		$model=new Genjournal('search');

		$model->unsetAttributes();  // clear any default values

		if(isset($_GET['Genjournal']))

			$model->attributes=$_GET['Genjournal'];

		if (isset($_GET['pageSize']))

		{

		  Yii::app()->user->setState('pageSize',(int)$_GET['pageSize']);

		  unset($_GET['pageSize']);  // would interfere with pager and repetitive page size change

		}


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

			'model'=>$model,

			'journaldetail'=>$journaldetail,

			'account'=>$account

		));

	}


	public function actionIndexdetail()

	{

	  $account=new Account('search');

	  $account->unsetAttributes();  // clear any default values

	  if(isset($_GET['Account']))

		$account->attributes=$_GET['Account'];

	  $journaldetail=new Journaldetail('search');

	  $journaldetail->unsetAttributes();  // clear any default values

	  if(isset($_GET['Journaldetail']))

		$journaldetail->attributes=$_GET['Journaldetail'];

	  $this->renderPartial('indexdetail',

		array('journaldetail'=>$journaldetail,'account'=>$account));

	  Yii::app()->end();

	}


	public function actionDownload()

  {

    Yii::import('application.extensions.fpdf.*');

    require_once("pdf.php");

    $pdf = new PDF();

    $pdf->title='Absence Schedule List';

    $pdf->AddPage('L');

    $pdf->setFont('Arial','B',12);


    // definisi font

    $pdf->setFont('Arial','B',<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />;


    // menuliskan tabel

    $header = array('No','ID','Schedule Name','Absence In','Absence Out', 'Status', 'Wage Name', 'Currency', 'Insentif');

    $model=new Absschedule('searchwstatus');

    $dataprovider=$model->searchwstatus();

    $dataprovider->pagination=false;

    $data = $dataprovider->getData();

    $cols = $dataprovider->getKeys();

    $dataku=array(count($data));

    //var_dump($dataku);

    $w= array(20,25,30,30,30,30,30,30,30);

    $pdf->SetTableHeader();

    //Header

    for($i=0;$i<count($header);$i++)

        $pdf->Cell($w[$i],7,$header[$i],1,0,'C',true);

    $pdf->Ln();

    $pdf->SetTableData();

    //Data

    $fill=false;

    foreach($data as $n=>$datas)

    {

        $pdf->Cell($w[0],6,$n,'LR',0,'C',$fill);

        $pdf->Cell($w[1],6,$datas['absscheduleid'],'LR',0,'C',$fill);

        $pdf->Cell($w[2],6,$datas['absschedulename'],'LR',0,'C',$fill);

        $pdf->Cell($w[3],6,$datas['absin'],'LR',0,'C',$fill);

        $pdf->Cell($w[4],6,$datas['absout'],'LR',0,'C',$fill);

        $pdf->Cell($w[5],6,Absstatus::model()->findByPk($datas['absstatusid'])->shortstat,'LR',0,'C',$fill);

        $pdf->Cell($w[6],6,Wagetype::model()->findByPk($datas['wagetypeid'])->wagename,'LR',0,'C',$fill);

        $pdf->Cell($w[7],6,Currency::model()->findByPk($datas['currencyid'])->currencyname,'LR',0,'C',$fill);

        $pdf->Cell($w[8],6,number_format($datas['insentif']),'LR',0,'C',$fill);

        $pdf->Ln();

        $fill=!$fill;

    }

    $pdf->Cell(array_sum($w),0,'','T');




    // me-render ke browser

    $pdf->Output();

  }


	/**

	 * 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=Genjournal::model()->findByPk((int)$id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


	public function loadModeldetail($id)

	{

		$model=Journaldetail::model()->findByPk((int)$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']==='genjournal-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

		if(isset($_POST['ajax']) && $_POST['ajax']==='journaldetail-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

}






<?php

$this->breadcrumbs=array(

	'Genjournals',

);

$pageSize=Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']);

?>

<script type="text/javascript">

// here is the magic

function adddata()

{

    <?php echo CHtml::ajax(array(

			'url'=>array('genjournal/create'),

            'data'=> "js:$(this).serialize()",

            'type'=>'post',

            'dataType'=>'json',

            'success'=>"function(data)

            {

				document.getElementById('messagediv').innerHTML = '';

                if (data.status == 'failure')

                {

                    $('#createdialog div.divcreate').html(data.div);

					$('#yt0').val('Create');

					$('#Genjournal_genjournalid').val(data.genjournalid);

					$('#Genjournal_referenceno').val('');

					$('#Genjournal_journaldate').val('');

					$('#Genjournal_journalnote').val('');

                          // Here is the trick: on submit-> once again this function!

                    $('#createdialog div.divcreate form').submit(adddata);

                }

                else

                {

                    $('#createdialog div.divcreate').html(data.div);

                    setTimeout(\"$('#createdialog').dialog('close') \",3000);

                }

            } ",

            ))?>;

    return false;

}

</script>

<script type="text/javascript">

function editdata()

{

    <?php

	echo CHtml::ajax(array(

			'url'=>array('genjournal/update'),

            'data'=> array('id'=>'js:$.fn.yiiGridView.getSelection("genjournal-grid")'),

            'type'=>'post',

            'dataType'=>'json',

            'success'=>"function(data)

            {

document.getElementById('messagediv').innerHTML = '';

                if (data.status == 'failure')

                {

                    $('#createdialog div.divcreate').html(data.div);

					$('#yt0').val('Save');

					$('#Genjournal_genjournalid').val(data.genjournalid);

					$('#Genjournal_referenceno').val(data.referenceno);

					$('#Genjournal_journaldate').val(data.journaldate);

					$('#Genjournal_journalnote').val(data.journalnote);

					if (data.recordstatus == '1')

					{

					  $('#recordstatus').checked='checked';

					}

                          // Here is the trick: on submit-> once again this function!

                    $('#createdialog div.divcreate form').submit(editdata);

                }

                else

                {

                    $('#createdialog div.divcreate').html(data.div);

                    setTimeout(\"$('#createdialog').dialog('close') \",3000);

                }

            } ",

            ))?>;

    return false;

}

</script>

<script type="text/javascript">

function deletedata()

{

    <?php

	echo CHtml::ajax(array(

			'url'=>array('genjournal/delete'),

            'data'=> array('id'=>'js:$.fn.yiiGridView.getSelection("genjournal-grid")'),

            'type'=>'post',

            'dataType'=>'json',

            'success'=>"function(data)

            {


            } ",

            ))?>;

	$.fn.yiiGridView.update('genjournal-grid');

	$.fn.yiiGridView.update('journaldetail-grid');

    return false;

}

</script>

<script type="text/javascript">

function refreshdata()

{

    $.fn.yiiGridView.update('genjournal-grid');

	$.fn.yiiGridView.update('journaldetail-grid');

    return false;

}

</script>

<?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog

    'id'=>'createdialog',

    'options'=>array(

        'title'=>'Form Dialog',

        'autoOpen'=>false,

        'modal'=>true,

        'width'=>900,

        'height'=>600,

    ),

));?>

<div id="divcreate"></div>

<?php echo $this->renderPartial('_form', array('model'=>$model,

				  'journaldetail'=>$journaldetail,

				'account'=>$account)); ?>

<?php $this->endWidget();?>


<?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog

    'id'=>'helpdialog',

    'options'=>array(

        'title'=>'Help',

        'autoOpen'=>false,

        'modal'=>true,

        'width'=>550,

        'height'=>470,

    ),

));?>

<?php echo $this->renderPartial('_help'); ?>

<?php $this->endWidget();?>

<h1>General Journal</h1>

<?php

$imgcreate=CHtml::image(Yii::app()->request->baseUrl.'/images/create.png');

echo CHtml::link($imgcreate,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{adddata(); $('#createdialog').dialog('open');}",

));

$imgedit=CHtml::image(Yii::app()->request->baseUrl.'/images/edit.png');

echo CHtml::link($imgedit,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata(); $('#createdialog').dialog('open');}",

));

$imgup=CHtml::image(Yii::app()->request->baseUrl.'/images/up.png');

echo CHtml::link($imgup,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata(); $('#createdialog').dialog('open');}",

));

$imgdown=CHtml::image(Yii::app()->request->baseUrl.'/images/down.png');

echo CHtml::link($imgdown,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata(); $('#createdialog').dialog('open');}",

));

$imgprint=CHtml::image(Yii::app()->request->baseUrl.'/images/print.png');

echo CHtml::link($imgprint,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata(); $('#createdialog').dialog('open');}",

));

$imgrefresh=CHtml::image(Yii::app()->request->baseUrl.'/images/refresh.png');

echo CHtml::link($imgrefresh,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{refreshdata()}",

));

$imgdelete=CHtml::image(Yii::app()->request->baseUrl.'/images/delete.png');

echo CHtml::link($imgdelete,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{deletedata()}",

));

$imghelp=CHtml::image(Yii::app()->request->baseUrl.'/images/help.png');

echo CHtml::link($imghelp,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"$('#helpdialog').dialog('open');",

));

?>

<?php

$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'genjournal-grid',

	'dataProvider'=>$model->Search(),

	'filter'=>$model,

  'selectableRows'=>2,

	'template'=>'{pager}<br>{items}{pager}',

	'pagerCssClass'=>Yii::app()->request->baseUrl.'/css/pager.css',

	'pager'=>array(

	  'class'=>'CLinkPager',

	  'header'=>' Record/page '.CHtml::textField($pageSize,'',array('size'=>'5',

        // change 'user-grid' to the actual id of your grid!!

        'onchange'=>"$.fn.yiiGridView.update('genjournal-grid',{ data:{pageSize: $(this).val() }})",

	  ))

	),

	'columns'=>array(

    array(

      'class'=>'CCheckBoxColumn',

      'id'=>'ids',

    ),

	array('name'=>'genjournalid', 'header'=>'ID','value'=>'$data->genjournalid','htmlOptions'=>array('width'=>'1%')),

		'referenceno',

		'journaldate',

		'journalnote',

    array(

      'class'=>'CCheckBoxColumn',

      'name'=>'recordstatus',

      'selectableRows'=>'0',

      'header'=>'Record Status',

      'checked'=>'$data->recordstatus'

    ),

  ),

));


$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'journaldetail-grid',

	'dataProvider'=>Journaldetail::model()->Searchbygenjournalid($_GET['id']),

	'filter'=>Journaldetail::model(),

  'selectableRows'=>0,

	'template'=>'{pager}<br>{items}{pager}',

	'pagerCssClass'=>Yii::app()->request->baseUrl.'/css/pager.css',

	'pager'=>array(

	  'class'=>'CLinkPager',

	  'header'=>' Record/page '.CHtml::textField($pageSize,'',array('size'=>'5',

        // change 'user-grid' to the actual id of your grid!!

        'onchange'=>"$.fn.yiiGridView.update('journaldetail-grid',{ data:{pageSize: $(this).val() }})",

	  ))

	),

	'columns'=>array(

    array(

      'class'=>'CCheckBoxColumn',

      'id'=>'ids1',

    ),

	array('name'=>'journaldetailid', 'header'=>'ID','value'=>'$data->journaldetailid','htmlOptions'=>array('width'=>'1%')),

	array('name'=>'accountid', 'header'=>'Account Code','value'=>'$data->account->accountcode','htmlOptions'=>array('width'=>'1%')),

	'debit',

	'credit',

  ),

)); 

?>

<div id="message"></div>






<div class="form">

<?php 

$journaldetail->genjournalid= $model->genjournalid;

$form=$this->beginWidget('CActiveForm', array(

	'id'=>'genjournal-form',

	'enableAjaxValidation'=>false,

	'htmlOptions'=>array('enctype'=>'multipart/form-data')

)); ?>

<?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog

    'id'=>'helpmodifdialog',

    'options'=>array(

        'title'=>'Help Dialog',

        'autoOpen'=>false,

        'modal'=>true,

        'width'=>500,

        'height'=>400,

    ),

));?>

<?php echo $this->renderPartial('_helpmodif'); ?>

<?php $this->endWidget();?>

<?php

$imghelp=CHtml::image(Yii::app()->request->baseUrl.'/images/help.png');

echo CHtml::link($imghelp,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"$('#helpmodifdialog').dialog('open');",

));  ?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>

		<?php echo $form->labelEx($model,'genjournalid'); ?>

<?php echo $form->textField($model,'genjournalid'); ?>

	<table>

	  <tr>

		<td>

		  <div class="row">

		<?php echo $form->labelEx($model,'referenceno'); ?>

		<?php echo $form->textField($model,'referenceno',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'referenceno'); ?>

	</div>

		</td>

		<td>

		  <div class="row">

		<?php echo $form->labelEx($model,'journaldate'); ?>

		<?php echo $form->textField($model,'journaldate'); ?> format: yyyy-mm-dd

		<?php echo $form->error($model,'journaldate'); ?>

	</div>

		</td>

	  </tr>

	  <tr>

		<td>

		  <div class="row">

		<?php echo $form->labelEx($model,'journalnote'); ?>

		<?php echo $form->textArea($model,'journalnote',array('rows'=>6, 'cols'=>50)); ?>

		<?php echo $form->error($model,'journalnote'); ?>

	</div>

		</td>

		<td>

		  <div class="row">

		<?php echo $form->labelEx($model,'recordstatus'); ?>

		<?php echo $form->checkBox($model,'recordstatus'); ?>

		<?php echo $form->error($model,'recordstatus'); ?>

	</div>

		</td>

	  </tr>

	</table>

		<div class="row buttons">

		<?php echo CHtml::ajaxSubmitButton('',

		array('genjournal/write'),

	  array('update'=>'#messagediv',

	  'success'=>'js:function(data) {

$.fn.yiiGridView.update("genjournal-grid");

$.fn.yiiGridView.update("journaldetail-grid");

                                $("#createdialog").dialog("close");

                                }')); ?>

	</div>


<?php $this->endWidget(); ?>

	<div id="messagediv"></div>

	<?php

	$this->widget('zii.widgets.jui.CJuiTabs', array(

	'tabs' => array(

		'Journal Detail' => array('content' => $this->renderPartial('indexdetail',

			array('journaldetail'=>$journaldetail,

			'account'=>$account),true)),

	),

	// additional javascript options for the tabs plugin

	'options' => array(

		'collapsible' => true,

	),

));?>

</div><!-- form -->



indexdetail.php




<?php

$this->breadcrumbs=array(

	'Genjournals',

);

$pageSize=Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']);

?>

<script type="text/javascript">

// here is the magic

function adddata1()

{

    <?php echo CHtml::ajax(array(

			'url'=>array('genjournal/createdetail'),

            'data'=> "js:$(this).serialize()",

            'type'=>'post',

            'dataType'=>'json',

            'success'=>"function(data)

            {

				document.getElementById('messagediv1').innerHTML = '';

                if (data.status == 'failure')

                {

                    $('#createdialog1 div.divcreate1').html(data.div);

					$('#yt2').val('Create');

					$('#Journaldetail_journaldetailid').val('');

					$('#Journaldetail_genjournalid').val(data.genjournalid);

					$('#Journaldetail_accountid').val('');

					$('#account_name').val('');

					$('#Journaldetail_debit').val('');

					$('#Journaldetail_credit').val('');

                          // Here is the trick: on submit-> once again this function!

                    $('#createdialog1 div.divcreate1 form').submit(adddata1);

                }

                else

                {

                    $('#createdialog1 div.divcreate1').html(data.div);

                    setTimeout(\"$('#createdialog1').dialog('close') \",3000);

                }

            } ",

            ))?>;

    return false;

}

</script>

<script type="text/javascript">

function editdata1()

{

    <?php

	echo CHtml::ajax(array(

			'url'=>array('genjournal/updatedetail'),

            'data'=> array('id'=>'js:$.fn.yiiGridView.getSelection("indexjournaldetail-grid")'),

            'type'=>'post',

            'dataType'=>'json',

            'success'=>"function(data)

            {

document.getElementById('messagediv1').innerHTML = '';

                if (data.status == 'failure')

                {

                    $('#createdialog1 div.divcreate1').html(data.div);

					$('#yt2').val('Save');

					$('#Journaldetail_journaldetailid').val(data.journaldetailid);

					$('#Journaldetail_genjournalid').val(data.genjournalid);

					$('#Journaldetail_accountid').val(data.accountid);

					$('#account_name').val(data.accountname);

					$('#Journaldetail_debit').val(data.debit);

					$('#Journaldetail_credit').val(data.credit);

					if (data.recordstatus == '1')

					{

					  $('#recordstatus').checked='checked';

					}

                          // Here is the trick: on submit-> once again this function!

                    $('#createdialog1 div.divcreate1 form').submit(editdata1);

                }

                else

                {

                    $('#createdialog1 div.divcreate1').html(data.div);

                    setTimeout(\"$('#createdialog1').dialog('close') \",3000);

                }

            } ",

            ))?>;

    return false;

}

</script>

<script type="text/javascript">

function deletedata1()

{

    <?php

	echo CHtml::ajax(array(

			'url'=>array('genjournal/deletedetail'),

            'data'=> array('id'=>'js:$.fn.yiiGridView.getSelection("indexjournaldetail-grid")'),

            'type'=>'post',

            'dataType'=>'json',

            'success'=>"function(data)

            {


            } ",

            ))?>;

	$.fn.yiiGridView.update('indexjournaldetail-grid');

    return false;

}

</script>

<script type="text/javascript">

function refreshdata1()

{

    $.fn.yiiGridView.update('indexjournaldetail-grid');

    return false;

}

</script>

<?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog

    'id'=>'createdialog1',

    'options'=>array(

        'title'=>'Form Dialog',

        'autoOpen'=>false,

        'modal'=>true,

        'width'=>'auto',

        'height'=>'auto',

    ),

));?>

<div id="divcreate1"></div>

<?php echo $this->renderPartial('_formdetail', array('model'=>$journaldetail,

				  'account'=>$account)); ?>

<?php $this->endWidget();?>


<?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog

    'id'=>'helpdialog1',

    'options'=>array(

        'title'=>'Help',

        'autoOpen'=>false,

        'modal'=>true,

        'width'=>550,

        'height'=>470,

    ),

));?>

<?php echo $this->renderPartial('_helpdetail'); ?>

<?php $this->endWidget();?>

<?php

$img1create=CHtml::image(Yii::app()->request->baseUrl.'/images/create.png');

echo CHtml::link($img1create,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{adddata1(); $('#createdialog1').dialog('open');}",

));

$img1edit=CHtml::image(Yii::app()->request->baseUrl.'/images/edit.png');

echo CHtml::link($img1edit,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata1(); $('#createdialog1').dialog('open');}",

));

$img1up=CHtml::image(Yii::app()->request->baseUrl.'/images/up.png');

echo CHtml::link($img1up,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata1(); $('#createdialog1').dialog('open');}",

));

$img1down=CHtml::image(Yii::app()->request->baseUrl.'/images/down.png');

echo CHtml::link($img1down,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata1(); $('#createdialog1').dialog('open');}",

));

$img1print=CHtml::image(Yii::app()->request->baseUrl.'/images/print.png');

echo CHtml::link($img1print,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{editdata1(); $('#createdialog1').dialog('open');}",

));

$img1refresh=CHtml::image(Yii::app()->request->baseUrl.'/images/refresh.png');

echo CHtml::link($img1refresh,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{refreshdata1()}",

));

$img1delete=CHtml::image(Yii::app()->request->baseUrl.'/images/delete.png');

echo CHtml::link($img1delete,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"{deletedata1()}",

));

$img1help=CHtml::image(Yii::app()->request->baseUrl.'/images/help.png');

echo CHtml::link($img1help,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"$('#helpdialog1').dialog('open');",

));

?>

<?php

$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'indexjournaldetail-grid',

	'dataProvider'=>Journaldetail::model()->Searchbygenjournalid($journaldetail->genjournalid),

	'filter'=>Journaldetail::model(),

  'selectableRows'=>1,

	'template'=>'{pager}<br>{items}{pager}',

	'pagerCssClass'=>Yii::app()->request->baseUrl.'/css/pager.css',

	'pager'=>array(

	  'class'=>'CLinkPager',

	  'header'=>' Record/page '.CHtml::textField($pageSize,'',array('size'=>'5',

        // change 'user-grid' to the actual id of your grid!!

        'onchange'=>"$.fn.yiiGridView.update('indexjournaldetail-grid',{ data:{pageSize: $(this).val() }})",

	  ))

	),

	'columns'=>array(

    array(

      'class'=>'CCheckBoxColumn',

      'id'=>'ids',

    ),

	array('name'=>'journaldetailid', 'header'=>'ID','value'=>'$data->journaldetailid','htmlOptions'=>array('width'=>'1%')),

	array('name'=>'genjournalid', 'header'=>'Journal ID','value'=>'$data->genjournalid','htmlOptions'=>array('width'=>'1%')),

	array('name'=>'accountid', 'header'=>'Account Code','value'=>'$data->account->accountcode','htmlOptions'=>array('width'=>'1%')),

	'debit',

	'credit',

  ),

));


?>

<div id="message1"></div>



_formdetail.php




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'journaldetail-form',

	'enableAjaxValidation'=>false,

	'htmlOptions'=>array('enctype'=>'multipart/form-data')

)); ?>

<?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array( // the dialog

    'id'=>'helpmodifdialog1',

    'options'=>array(

        'title'=>'Help Dialog',

        'autoOpen'=>false,

        'modal'=>true,

        'width'=>'auto',

        'height'=>'auto',

    ),

));?>

<?php echo $this->renderPartial('_helpmodif'); ?>

<?php $this->endWidget();?>

<?php

$imghelp1=CHtml::image(Yii::app()->request->baseUrl.'/images/help.png');

echo CHtml::link($imghelp1,'#',array(

   'style'=>'cursor: pointer; text-decoration: underline;',

   'onclick'=>"$('#helpmodifdialog1').dialog('open');",

));  ?>

<?php echo $form->hiddenField($model,'journaldetailid'); ?>

<?php echo $form->hiddenField($model,'genjournalid'); ?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>


    <div class="row">

		<?php echo $form->labelEx($model,'accountid'); ?>

<?php echo $form->hiddenField($model,'accountid'); ?>

	  <input type="text" name="account_name" id="account_name" title="Account name" readonly value="<?php echo Account::model()->findByPk($model->accountid)->accountname ?>">

    <?php

      $this->beginWidget('zii.widgets.jui.CJuiDialog',

       array(   'id'=>'account_dialog',

                // additional javascript options for the dialog plugin

                'options'=>array(

                                'title'=>Yii::t('app','Account'),

                                'width'=>'auto',

                                'autoOpen'=>false,

                                'modal'=>true,

                                ),

                        ));


    $this->widget('zii.widgets.grid.CGridView', array(

      'id'=>'account-grid',

      'dataProvider'=>$account->Searchwstatus(),

      'filter'=>$account,

      'template'=>'{summary}{pager}<br>{items}{pager}{summary}',

      'columns'=>array(

        array(

          'header'=>'',

          'type'=>'raw',

        /* Here is The Button that will send the Data to The MAIN FORM */

          'value'=>'CHtml::Button("+",

          array("name" => "send_absschedule",

          "id" => "send_absschedule",

          "onClick" => "$(\"#account_dialog\").dialog(\"close\"); $(\"#account_name\").val(\"$data->accountname\"); $(\"#Journaldetail_accountid\").val(\"$data->accountid\");

		  "))',

          ),

        'accountid',

        'accountcode',

        'accountname',

        array(

          'class'=>'CCheckBoxColumn',

          'name'=>'recordstatus',

          'selectableRows'=>'0',

          'header'=>'Record Status',

          'checked'=>'$data->recordstatus'

        ),

        ),

    ));


    $this->endWidget('zii.widgets.jui.CJuiDialog');

    echo CHtml::Button('...',

                          array('onclick'=>'$("#account_dialog").dialog("open"); return false;',

                       ))?>		

		<?php echo $form->error($model,'accountid'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'debit'); ?>

		<?php echo $form->textField($model,'debit'); ?>

		<?php echo $form->error($model,'debit'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'credit'); ?>

		<?php echo $form->textField($model,'credit'); ?>

		<?php echo $form->error($model,'credit'); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::ajaxButton('',

		array('genjournal/writedetail'),

	  array('update'=>'#messagediv1','type'=>'POST',

	  'success'=>'js:function(data) {

$.fn.yiiGridView.update("indexjournaldetail-grid");

                                $("#createdialog1").dialog("close");

                                }')); ?>

	</div>


<?php $this->endWidget(); ?>

	<div id="messagediv1"></div>

</div><!-- form -->



  1. there are a lot of code duplications you need to make new functions to re-sieve only that part and make avoid code duplication ex:



$journaldetail=new Journaldetail('search');

$journaldetail->unsetAttributes();  // clear any default values

if(isset($_GET['Journaldetail']))

    $journaldetail->attributes=$_GET['Journaldetail'];






$account=new Account('search');

$account->unsetAttributes();  // clear any default values

if(isset($_GET['Account']))

    $account->attributes=$_GET['Account'];



  1. create and update always are similar except in create you need make new model and in update you need to load model. suggestion make only one function.

thank you for your feedback, I’ll optimize that code

it nice tutorial…!

vefy good and usefull

Yes you can do that. My example code show that you can create/edit in single form

hello siskalandre,

I’m a newbie in yii and now i’m trying to create a master detail form like the example you’ve given.

I’ve already followed your codes, but I’m facing a problem with create function.

It doesn’t work. The data doesn’t stored at all in the database. When I click the ‘Save’ button, nothing happenend, even the dialog didn’t closed.

while the update function could work perfectly. I’ve tried to input data manually from the database and then use the update function in the system, and it works!

So, is there any problem with the actionWrite?

I wonder that maybe there were some changes that you’ve made to the codes given in this forum. Or it’s just me who don’t understand perfectly ;D

Anyway, I’ve also compared between the codes that you’ve given and the actual form in the prisma data abadi website, I think there’re so many changes that you’ve made, right?

And it makes me quiet confused to learn it, since i’m still newbie ofcourse :lol:

It will be very grateful if you can give me some advices… :rolleyes:

Thanks a lot

Please use english here, as this is the general section… For your language use the International Yii section…

I’m sorry Sir,

I didn’t realize it…

I’ve changed my post

thanks

Very good sample, I think.

siskalandre can you upload the database schema ? or the schema for tables you are using in the master detail sample?

Thanks

lmir

Sorry for bad english

hi, can this be moved to a wiki page, so other could bookmark it ??

Best regards

siskalandre, it will be best if You give us whole project with db. For us, refuge from "winform land" it is sometime hard to understand some simple thinks in web application. But if You give us real exsample it will be easier. And while not wiki for mater_child form, dreaming???

Best regards.

Hello, i’m new in Yii.

I have followed your examples (maybe the exact word is copy and paste your code) from top to bottom, but the checkbox column in the master section every time i click doesnt refresh the detail at all and if i see using firebug, there is no ajax process like your examples in capellaerp.com/index.php?r=genjournal/index. Is there any code that i missed. Please help…

Sorry for my bad english.

Thank u

Hello… I’m a newbie in yii…

I have copied and pasted all of your example, an I got following error :

Filter "rights" is invalid. Controller "GenjournalController" does not have the filter method "filterrights".

Please give me any advice about it…

Thanks before.

Hi siskalandre,

I’m new to Yii & I’m from Indonesia too, I want to learn that master detail in your solution. But I really confuse read your sample and it cannot run after I copy paste. Can I get complete source for simple master-detail relationship?

And what is the username and password for the demo prismadataabadi. com/ capella/ ?

Thank you

Thank you for sharing and I’m understand what this is. even without any database schema.

but it will be very helpful for beginner to understand if you post a picture of the end result, not just code.

Wow, thanks a lot, thats what I need :)