Lets consider a senario such that certain controls to be displayed based on selection of dropdown in which it may contain calender controls (such as CJUIDateTimePicker) or a ajax calls which in turns calls another view. To achieve the above situation
In my case , While entering land details the user selects "whether regularization applied?" column to Yes/NO selection.
If Yes then we have to accept the "date of application" and again We need to know whether "Depreciation Claimed or not by the applicant" and , If yes then we have to accept the reasons and date from the user.
For this, I have main model "land" which consists fields "reg_applied varchar(1) , app_dt date, dclaimed varchar(1) , reasons varchar(300) and finally dcdate date."
First we have _createform.php (app_folder\protected\views\land\_createform.php):
<?php echo $form->dropDownList($model,'reg_applied',array('N'=>'NO','Y'=>'YES'),
array('prompt'=>'Select',
'ajax'=>array( 'type'=>'POST',
'url'=>CController::createUrl('Land/areg',array('id'=>$model->id)),
'update'=>'#areg',
))); ?>
<?php echo $form->error($model,'reg_applied'); ?>
<div id="areg">
</div>
In above dropdown we defined a ajax call to the action 'areg' . and updates the div content which is having id as 'areg'.
Now we have to define the action 'areg' in our LandController.php (app_folder\protected\controller\LandController.php)
public function actionAreg($id){
if(($id==null)or($id=='')or(empty($id)))
$model=new Land;
else
$model=$this->loadModel($id);
$stat=$_POST['Land']['reg_applied'];
$output=$this->renderPartial('_areg',array('model'=>$model,'stat'=>$stat),true,true);
echo $output;
}
Now we have to define our partial form i.e., nothing but "_areg.php" in our views folder (app_folder\protected\views\land\_areg.php)
<?php if(strtoupper($stat)=='Y'){ /* This is defined in controller and we are passing as argument in the render partial method */ ?>
<table>
<tr>
<td><b> If Yes (applied) - </b></td>
<td><b>Date of application </b></td>
<td>
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker',array(
'model'=>$model,
'attribute'=>'app_dt',
'value'=>date('Y-m-d',strtotime($model->app_dt)),
'language'=>'',
'options'=>array(
'showAnim'=>'slide', //'slide','fold','slideDown','fadeIn','blind','bounce','clip','drop'
// 'showAnim'=>'slideDown',
'showHour'=>false,
'showMinute'=>false,
'showTime'=>false,
'changeMonth'=>true,
'changeYear'=>true,
'dateFormat'=>'yy-mm-dd',
'timeFormat'=>'',
'showButtonPanel'=>true,
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
?>
</td>
<td><b>Depreciation Claimed</b></td>
<td>
<?php echo CHtml::dropDownList('Land[dclaimed]',"$model->dclaimed",
array('N'=>'NO','Y'=>'YES'),
array('ajax'=>array(
'type'=>'POST',
'url'=>CController::createUrl('Land/dclaim',array('id'=>$model->id)),
'update'=>'#dclaim',
))
);?>
</td>
</tr>
<tr>
<td colspan='5'>
</td>
<div id="dclaim">
</div>
</tr>
</table>
Here in the above partial form we are calling another ajax call for the dropdown dclaimed. Remember We have to know whether "Depreciation Claimed or not by the applicant" and , If claimed then we have to accept the reasons and date from the user.To acheive this we are calling ajax call and we have to handle the code that if claimed ie., $model->dclaimed =='Y' then we have to display the fields reasons and date
Again move to controller (our LandController.php) and define the action dclaim (app_folder\protected\controller\LandController.php)
public function actionDclaim($id){
if(($id==null)or($id=='')or(empty($id)))
$model=new Land;
else
$model=$this->loadModel($id);
$stat=$_POST['Land']['dclaimed'];
$output=$this->renderPartial('_dclaim',array('model'=>$model,'stat'=>$stat),true,true);
echo $output;
}
and here we are rendering partial view dclaim , remember the view elements which are showing are shown in the position where our div dclaim defined. So we have to customize the positions of controls according to our requirement
Now define partial view (app_folder\protected\views\land\_dclaim.php)
<?php if(strtoupper($stat)=='Y'){ ?>
<table>
<tr>
<td rowspan="2"><b> If Yes </b></td>
<td colspan="1"><b>Details</b></td>
<td colspan="3">
<?php echo CHtml::textArea('Land[reasons]', "$model->details",array('rows'=>4,'cols'=>40,'style'=>'width:270px;height:80px;')); ?>
</td>
</tr><tr>
<td><b>Date of Execution </b></td>
<td>
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker',array(
'model'=>$model,
'attribute'=>'dcdate',
'value'=>date('Y-m-d',strtotime($model->dcdate)),
'language'=>'',
'options'=>array(
'showAnim'=>'slide', //'slide','fold','slideDown','fadeIn','blind','bounce','clip','drop'
// 'showAnim'=>'slideDown',
'showHour'=>false,
'showMinute'=>false,
'showTime'=>false,
'changeMonth'=>true,
'changeYear'=>true,
'dateFormat'=>'yy-mm-dd',
'timeFormat'=>'',
'showButtonPanel'=>true,
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
?>
</td>
</tr>
</table>
<?php } ?>
and finally don't forget to define access rules for the above two actions ie.,
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view','areg','dclaim'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('admin','create','update'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
Now, the requirement fulfilled up to entry level. We need to treat update screen differently, i.e., in create action simply we defined the controls to be displayed based on selection. But in update screen the selection was done already we have to show them directly on loading the screen in addition to the above actions defined. i.e., if the user selected "regularized" column as yes and given application date.
So in update form (app_folder\protected\views\land\_updateform.php), note we have same as _createform but the div 'areg' is defined here.
<?php echo $form->dropDownList($model,'reg_applied',array('N'=>'NO','Y'=>'YES'),
array('prompt'=>'Select',
'ajax'=>array(
'type'=>'POST',
'url'=>CController::createUrl('Land/areg',array('id'=>$model->id)),
'update'=>'#areg',
)));
?>
<?php echo $form->error($model,'reg_applied'); ?>
<div
id="areg">
<?php $stat=$model->reg_applied; ?>
<?php if(strtoupper($stat)=='Y'){ ?>
<table>
<tr>
<td rowspan="4"><b> If Yes (applied) - </b></td>
<td><b>Date of application </b></td>
<td>
<?php
$this->widget('zii.widgets.jui.CJuiDatePicker',array(
'model'=>$model,
'attribute'=>'app_dt',
'value'=>date('Y-m-d',strtotime($model->app_dt)),
'language'=>'en-AU',
'options'=>array(
'showAnim'=>'slide', //'slide','fold','slideDown','fadeIn','blind','bounce','clip','drop'
// 'showAnim'=>'slideDown',
'showHour'=>false,
'showMinute'=>false,
'showTime'=>false,
'changeMonth'=>true,
'changeYear'=>true,
'dateFormat'=>'yy-mm-dd',
'timeFormat'=>'',
'showButtonPanel'=>true,
),
'htmlOptions'=>array(
'style'=>'height:20px;'
),
));
?>
</td>
<td><b>Depreciation Claimed</b></td>
<td>
<?php echo $form->dropDownList($model,'dclaimed',
array('N'=>'NO','Y'=>'YES'),
array('ajax'=>array(
'type'=>'POST',
'url'=>CController::createUrl('Land/dclaim',array('id'=>$model->id)),
'update'=>'#dclaim',
))
);?>
</td>
</table>
<?php } // End of condition ?>
</div>
I have shown a example, similarly we have to do for "Depreciation Claimed" condition also. Otherwise the controls shown in ajax action only, but if in create action user have already given the date, etc., so before giving him/her provision to update we need to show them in the screen.
Hope this post is useful