[Solved] How To Auto Populate Other Fields With Date Or Return Null Depending On Data Selected From Dropdown Options.

Hi all,

I want to auto populate fields (inspection_date & date_dismantled) with DATE or return NULL depending on status selected from status_id dropdown options.

Here’s my _form:




<div class="row">

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

		<?php $this->widget('zii.widgets.jui.CJuiDatePicker',

                        array(

                            'attribute' => 'date_inspected',

                            'model' => $model,

                            // additional javascript options for the date picker plugin

                            'options' => array(

                                'autoSize' => true,

                                'showAnim' => 'slideDown',

                                'showOn' => 'button',

                                'changeMonth' => true,

                                'changeYear' => true,

                                'dateFormat' => 'yy-mm-dd',

                            ),

                            'htmlOptions' => array(

                                'style' => 'height:20px;',

                            ),

                    ));?>

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

	</div>


	<div class="row">

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

		<?php echo $form->dropDownList($model,'status_id', $model->getStatusOptions(), array('prompt'=>'Select Status')); ?>

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

	</div>


        <div class="row">

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

		<?php $this->widget('zii.widgets.jui.CJuiDatePicker',

                        array(

                            'attribute' => 'inspection_date',

                            'model' => $model,

                            // additional javascript options for the date picker plugin

                            'options' => array(

                                'autoSize' => true,

                                'showAnim' => 'slideDown',

                                'showOn' => 'button',

                                'changeMonth' => true,

                                'changeYear' => true,

                                'dateFormat' => 'yy-mm-dd',

                            ),

                            'htmlOptions' => array(

                                'style' => 'height:20px;',

                            ),

                    ));?>

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

	</div>

        

        <div class="row">

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

		<?php $this->widget('zii.widgets.jui.CJuiDatePicker',

                        array(

                            'attribute' => 'date_dismantled',

                            'model' => $model,

                            // additional javascript options for the date picker plugin

                            'options' => array(

                                'autoSize' => true,

                                'showAnim' => 'slideDown',

                                'showOn' => 'button',

                                'changeMonth' => true,

                                'changeYear' => true,

                                'dateFormat' => 'yy-mm-dd',

                            ),

                            'htmlOptions' => array(

                                'style' => 'height:20px;',

                            ),

                    ));?>

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

	</div>



status_id has 3 options: "Green Tag, Red Tag and Dismantled".

What I wish to happen is when I choose “Green Tag or Red Tag” the inspection_date field will be populated by today’s date +7days and date_dismantled field will remain Null (something like: $model->inspection_date = date(‘Y-m-d’, strtotime(’+7 days ')); $model->date_dismantled = Null;). But when I choose “Dismantled”, inspection_date will return Null and date_dismantled will be populated with today’s date (something like: $model->inspection_date = Null; $model->date_dismantled = date(‘Y-m-d’);).

By the way date_inspected & inspection_date fields are auto fill with DATES from the InspectionController upon initializing the form.

Note: inspection_date is labeled as Next Inspection Due on the attached image.




public function actionCreate()

	{

		$model=new Inspection;

                $model->date_inspected = date('Y-m-d');

                $model->inspection_date = date('Y-m-d', strtotime('+7 days '));...



But I want different approach and changes are happening immediately after selecting status.

Any idea how to achieve it and please provide an example. Thanks in Advance.

Just a thought ::)

In the model:




protected function beforeSave() {

   switch ($this->status_id) {

      case self::GREEN_TAG:

         $this->inspection_date = date('Y-m-d', 

            strtotime($this->date_inspected, '+7 days '));

         $this->date_dismantled = null;

         break;

      case self::RED_TAG:

         $this->inspection_date = date('Y-m-d', 

            strtotime($this->date_inspected, '+3 days '));

         $this->date_dismantled = null;

         break;

     case self::DISMANTLED:

         $this->inspection_date = null;

         $this->date_dismantled = date('Y-m-d');

   }

   return parent::beforeSave();

}



Above is psydo-code AND off the top of my head, so I’m not sure about the strtotime($this-> ,’+7 days’)

Thanks jkofsky for the idea, I made some adjustments on the code to work;

Sorry I forgot to post this part of the model before;




    const STATUS_GREEN='1';

    const STATUS_RED='2';

    const STATUS_DISMANTLED='3';


    public function getStatusOptions()

	{

		return array(

                    self::STATUS_GREEN=>'Green Tag',

                    self::STATUS_RED=>'Red Tag',

                    self::STATUS_DISMANTLED=>'Dismantled',

		);

	}






protected function beforeSave() {

            switch ($this->status_id) {

                case self::STATUS_GREEN:

                   $this->inspection_date = date('Y-m-d', strtotime('+7 days '));

                   $this->date_dismantled = null;

                   break;

                case self::STATUS_RED:

                   $this->inspection_date = date('Y-m-d', strtotime('+7 days '));

                   $this->date_dismantled = null;

                   break;

                case self::STATUS_DISMANTLED:

                   $this->inspection_date = null;

                   $this->date_dismantled = date('Y-m-d');

            }

        return parent::beforeSave();

        }



However changes are happening before saving and not after selecting option from status_id dropdownlist instantly.

I don’t know if CAutoComplete can do the trick or some other widgets, Again thank you so much for your reply.

Do you have other thought how to do it the way I wish to happen?

Hi Charles Dave.

Try using JavaScript. Catch onchange event of the dropdownlist:


<?php

echo $form->dropDownList(

	$model,

	'status_id',

	$model->getStatusOptions(),

	array(

		'prompt' => 'Select Status',

		'onchange' => 'alert(1)'

	)

); ?>

Of course, instead of alert(1) use a more reasonable script. The script could check the list’s value and copy a prepared in advance value from a hidden field.

Thanks Alexandre, I wil google your suggestion but I really appreciate if you could give me a working code using my data.

I’m a newbie to yii and I don’t know my way around.

Tnx a lot.

Hi Charles Dave.

You can add two hidden fields in any place of your form:


	<?php echo CHtml::hiddenField('date_today', date('Y-m-d')) ?>

	<?php echo CHtml::hiddenField('date_plus7', date('Y-m-d', strtotime('+7 days '))) ?>

The fields are named ‘date_today’ and ‘date_plus7’ containing the today’s date and that of 7 days after today.

The dropdown element becomes:


<?php

echo $form->dropDownList(

	$model,

	'status_id',

	$model->getStatusOptions(),

	array(

		'prompt' => 'Select Status',

		'onchange' =>

			'if (this.value == "DISMANTLED")

			{

				this.form.elements["Inspection[inspection_date]"].value = ""

				this.form.elements["Inspection[date_dismantled]"].value = this.form.elements["date_today"].value

			}

			else

			{

				this.form.elements["Inspection[inspection_date]"].value = this.form.elements["date_plus7"].value

				this.form.elements["Inspection[date_dismantled]"].value = ""

			}'

	)

); ?>

Here this.value takes the selected value of the dropdown. I have used “DISMANTLED” value because I don’t know exact values you are using. this.form.elements[] refers to the form elements. CActiveForm gives them names in the form “Model[attribute]”, for example “Inspection[inspection_date]”.

Good coding!

Thank you so much Alexandre, it works like a charm.

I just changed




'if (this.value == "DISMANTLED")



with




'if (this.value == 3)



from model




    const STATUS_GREEN='1';

    const STATUS_RED='2';

    const STATUS_DISMANTLED='3';



To be perfect, it’s better:


'if (this.value == "' . $model->STATUS_DISMANTLED . '")

;)

Or even better :)


if (this.value == "' . self::STATUS_DISMANTLED . '")

Thanks Alexandre & jkofsky.

I have another one but more complicated, please take a look and give an example.

There are 3 Departments and 2 Facilities on my project.

Each department use 5 digits reference number but starts with different number.

(Department - Facility = Reference Number)

Ops & Maint - CUQ = 10001

Ops & Maint - DPP = 30001

AIM - CUQ = 50001

AIM - DPP = 70001

Shutdown - CUQ = 80001

Shutdown - DPP = 90001

using this form:




<div class="form">


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

	'id'=>'scaffold-form',

	'enableAjaxValidation'=>false,

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

     )); ?>


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


	<?php echo $form->errorSummary($model); ?>

        

        <div class="row">

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

		<?php $this->widget('zii.widgets.jui.CJuiDatePicker',

                        array(

                            'attribute' => 'date_erected',

                            'model' => $model,

                            // additional javascript options for the date picker plugin

                            'options' => array(

                                //'autoSize' => true,

                                'showAnim' => 'slideDown',

                                'showOn' => 'button',

                                'changeMonth' => true,

                                'changeYear' => true,

                                'dateFormat' => 'yy-mm-dd',

                            ),

                            'htmlOptions' => array(

                                'style' => 'height:20px;',

                            ),

                    ));?>

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

	</div>


        <div class="row">

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

		<?php echo $form->dropDownList($model,'department_id', Department::model()->getDepartmentOptions(), array('prompt'=>'Select Department')); ?>

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

	</div>

        

        <div class="row">

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

		<?php echo $form->dropDownList($model,'facility_id', Facility::model()->getFacilityOptions(), array('prompt'=>'Select Facility')); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'id',array('size'=>11,'maxlength'=>7)); ?>

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

	</div>       



after selecting a department_id and facility_id, is it possible to search database and populate the id(reference number) with the last reference number + 1 of the department-facilty selected using dropdownlist onChange event?

The reason I want to achieve this is because when creating a new scaffold, I don’t want to check what would be the next ref.# based on department - facilty serial instead it should be displayed automatically.