Ejuicombobox Throwing Undefined Offset Error On Specific Model Attributes

Hi,

I downloaded the Editable combo box control with Auto-complete and added the extension. I am having problem with patient_id and problem_definition_id attributes of the model. Works fine for problem_duration_id and some other attributes. When I use them for the combo box I receive the following error:

3910

EJuiComboBox-Undefined Offset.png

Following is the code that i have used in my view:




$this->widget('ext.combobox.EJuiComboBox', array(

    'model' => $PatientProblem,

    'attribute' => 'problem_definition_id',

    'id'=>'eeed',

    'data'=>Yii::app()->cache->get('PATIENT_PROBLEM'),

    // options passed to plugin

    'assoc'=>true,

    'options' => array(

        'allowText' => false,),

    // Options passed to the text input

    'htmlOptions' => array('size' => 6),

));



Following is the my model:




<?php


/**

 * This is the model class for table "patient_problem".

 *

 * The followings are the available columns in table 'patient_problem':

 * @property integer $problem_id

 * @property integer $problem_definition_id

 * @property integer $patient_id

 * @property integer $curr_or_history

 * @property integer $patient_visit_id

 * @property string $problem_notes

 * @property string $chronic

 * @property string $alert_on_dashboard

 * @property integer $problem_duration_id

 * @property integer $create_acc_id

 * @property integer $create_user_id

 * @property string $create_date

 * @property integer $create_acc_assign_id

 * @property integer $update_acc_id

 * @property integer $update_user_id

 * @property string $update_date

 * @property integer $update_acc_assign_id

 *

 * The followings are the available model relations:

 * @property Patient $patient

 * @property ListOfValues $currOrHistory

 * @property PatientVisit $patientVisit

 * @property ListOfValues $problemDefinition

 * @property ListOfValues $problemDuration

 */

class PatientProblem extends CActiveRecord

{

	/**

	 * Returns the static model of the specified AR class.

	 * @param string $className active record class name.

	 * @return PatientProblem the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'patient_problem';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('problem_definition_id, patient_id, curr_or_history, patient_visit_id, problem_duration_id, create_acc_id, create_user_id, create_acc_assign_id, update_acc_id, update_user_id, update_acc_assign_id', 'numerical', 'integerOnly'=>true),

			array('chronic, alert_on_dashboard', 'length', 'max'=>1),

			array('problem_notes, problem_reported_date, create_date, update_date', 'safe'),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('problem_id, problem_definition_id, patient_id, curr_or_history, patient_visit_id, problem_notes, problem_reported_date, chronic, alert_on_dashboard, problem_duration_id, create_acc_id, create_user_id, create_date, create_acc_assign_id, update_acc_id, update_user_id, update_date, update_acc_assign_id', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'patient' => array(self::BELONGS_TO, 'Patient', 'patient_id'),

			'currOrHistory' => array(self::BELONGS_TO, 'ListOfValues', 'curr_or_history'),

			'patientVisit' => array(self::BELONGS_TO, 'PatientVisit', 'patient_visit_id'),

			'problemDefinition' => array(self::BELONGS_TO, 'ListOfValues', 'problem_definition_id'),

			'problemDuration' => array(self::BELONGS_TO, 'ListOfValues', 'problem_duration_id'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'problem_id' => 'Problem',

			'problem_definition_id' => 'Problem Definition',

			'patient_id' => 'Patient',

			'curr_or_history' => 'Curr Or History',

			'patient_visit_id' => 'Patient Visit',

			'problem_notes' => 'Problem Notes',

			'problem_reported_date'=>'Report Date',

			'chronic' => 'Chronic',

			'alert_on_dashboard' => 'Alert On Dashboard',

			'problem_duration_id' => 'Problem Duration',

			'create_acc_id' => 'Create Acc',

			'create_user_id' => 'Create User',

			'create_date' => 'Create Date',

			'create_acc_assign_id' => 'Create Acc Assign',

			'update_acc_id' => 'Update Acc',

			'update_user_id' => 'Update User',

			'update_date' => 'Update Date',

			'update_acc_assign_id' => 'Update Acc Assign',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('problem_id',$this->problem_id);

		$criteria->compare('problem_definition_id',$this->problem_definition_id);

		$criteria->compare('patient_id',$this->patient_id);

		$criteria->compare('curr_or_history',$this->curr_or_history);

		$criteria->compare('patient_visit_id',$this->patient_visit_id);

		$criteria->compare('problem_notes',$this->problem_notes,true);

		$criteria->compare('problem_reported_date',$this->problem_reported_date,true);

		$criteria->compare('chronic',$this->chronic,true);

		$criteria->compare('alert_on_dashboard',$this->alert_on_dashboard,true);

		$criteria->compare('problem_duration_id',$this->problem_duration_id);

		$criteria->compare('create_acc_id',$this->create_acc_id);

		$criteria->compare('create_user_id',$this->create_user_id);

		$criteria->compare('create_date',$this->create_date,true);

		$criteria->compare('create_acc_assign_id',$this->create_acc_assign_id);

		$criteria->compare('update_acc_id',$this->update_acc_id);

		$criteria->compare('update_user_id',$this->update_user_id);

		$criteria->compare('update_date',$this->update_date,true);

		$criteria->compare('update_acc_assign_id',$this->update_acc_assign_id);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}

	/* The code till this line is Gii generated. All the code beyond this point is cutom code. */

	public function beforeSave(){

		$retval=false;

		if ($this->isNewRecord){

			//Handling duplicate Entries for Problem in one visit.

			$criteria = new CDbCriteria;

			$criteria->compare('problem_definition_id', $this->problem_definition_id);

			$criteria->compare('patient_id', $this->patient_id);

			$criteria->compare('patient_visit_id', $this->patient_visit_id);

			$PatientProblem = $this->model()->findAll($criteria);

			if (count($PatientProblem)==0){

				$retval=true;

				$this->setAttribute('create_date',date("Y-m-d H:i:s"));

				$this->setAttribute('create_user_id',Yii::app()->user->id);

				$this->setAttribute('create_acc_id',Yii::app()->user->assigner_account_id);

				$this->setAttribute('create_acc_assign_id',Yii::app()->user->acc_assign_id);

			}

			else{

				$errorMsg='';

				$criteria = new CDbCriteria;

				$criteria->compare('mCode','VISIT_PROBLEM_EXISTS');

				$criteria->compare('mLang',Yii::app()->user->account_lang);

				$SysMsgs=SystemMessages::model()->findAll($criteria);

				if (count($SysMsgs)>0){

 					$errorMsg='"'.$this->problemDefinition->group_display_val.'"'.$SysMsgs[0]->mDesc.' Code['.$SysMsgs[0]->mId.']';

				}

				else{

					$errorMsg=$this->problemDefinition->group_display_val.' already recorded.';

				}

				throw new Exception($errorMsg);

				$retval=false;	

			}

		}

		else{

			$this->setAttribute('update_date',date("Y-m-d H:i:s"));

			$this->setAttribute('update_user_id',Yii::app()->user->id);

			$this->setAttribute('update_acc_id',Yii::app()->user->assigner_account_id);

			$this->setAttribute('update_acc_assign_id',Yii::app()->user->acc_assign_id);

			$retval=true;

		}

		return $retval;

	}


	public function getProb_def_id(){

		return $this->problem_definition_id;

	}

	

	public function setProb_def_id($val){

		$this->problem_definition_id=$val;

	}


	public function getProblemFlaged(){

		return $this->alert_on_dashboard=='1' ?  CHtml::image(Yii::app()->baseUrl .'/images/Flagredicon.png') : '';  


	}

	public function getProblemFlagSrc(){

		return $this->alert_on_dashboard=='1' ?  Yii::app()->baseUrl .'/images/Flagredicon.png' :'';

	}

	public function getProblemChronic(){

		return $this->chronic=='1' ?  CHtml::image(Yii::app()->baseUrl .'/images/tickedS.jpg') : '';  


	}

		

	public function getProblemDel(){

		return '&nbsp<a class="delete" title="Delete"  onclick="DeletePatProblem('.$this->problem_id.'); return false; " href="#"><img src="/webapp/assets/50005a14/gridview/delete.png" alt="Delete" /></a>&nbsp<a class="delete" title="Update"  onclick="UpdatePatProblem(this,'.$this->problem_id.','.$this->problem_definition_id.','.$this->curr_or_history.',\''.$this->problem_notes.'\','.$this->problem_duration_id.','.$this->chronic.','.$this->alert_on_dashboard.'); return false; " href="#"><img src="/webapp/assets/50005a14/gridview/update.png" alt="Update" /></a>';	

	}


}



Following is the code of EJuiComboBox.php




<?php


/**

 * jQuery combobox Yii extension

 * 

 * Allows selecting a value from a dropdown list or entering in text.

 * Also works as an autocomplete for items in the select.

 *

 * @copyright © Digitick <www.digitick.net> 2011

 * @license GNU Lesser General Public License v3.0

 * @author Ianaré Sévi

 * @author Jacques Basseck

 *

 */

Yii::import('zii.widgets.jui.CJuiInputWidget');


/**

 * Base class.

 */

class EJuiComboBox extends CJuiInputWidget

{

	/**

	 * @var array the entries that the autocomplete should choose from.

	 */

	public $data = array();

	public $assoc;

	/**

	 * @var string A jQuery selector used to apply the widget to the element(s).

	 * Use this to have the elements keep their binding when the DOM is manipulated

	 * by Javascript, ie ajax calls or cloning.

	 * Can also be useful when there are several elements that share the same settings,

	 * to cut down on the amount of JS injected into the HTML.

	 */

	public $scriptSelector;

	public $defaultOptions = array('allowText' => true);


	protected function setSelector($id, $script, $event=null)

	{

		if ($this->scriptSelector) {

			if (!$event)

				$event = 'focusin';

			$js = "jQuery('body').delegate('{$this->scriptSelector}','{$event}',function(e){\$(this).{$script}});";

			$id = $this->scriptSelector;

		}

		else

			$js = "jQuery('#{$id}').{$script}";

		return array($id, $js);

	}


	public function init()

	{

		$cs = Yii::app()->getClientScript();

		$assets = Yii::app()->getAssetManager()->publish(dirname(__FILE__) . '/assets');

		$cs->registerScriptFile($assets . '/jquery.ui.widget.min.js');

		$cs->registerScriptFile($assets . '/jquery.ui.combobox.js');


		parent::init();

	}


	/**

	 * Run this widget.

	 * This method registers necessary javascript and renders the needed HTML code.

	 */

	/*

	public function run()

	{

		list($name, $id) = $this->resolveNameID();


		if (is_array($this->data) && !empty($this->data)){

			$data = array_combine($this->data, $this->data);

			array_unshift($data, null);

		}

		else

			$data = array();


		echo CHtml::dropDownList(null, null, $data, array('id' => $id . '_select'));


		if ($this->hasModel())

			echo CHtml::activeTextField($this->model, $this->attribute, $this->htmlOptions);

		else

			echo CHtml::textField($name, $this->value, $this->htmlOptions);


		$this->options = array_merge($this->defaultOptions, $this->options);


		$options = CJavaScript::encode($this->options);


		$cs = Yii::app()->getClientScript();


		$js = "combobox({$options});";


		list($id, $js) = $this->setSelector($id, $js);

		$cs->registerScript(__CLASS__ . '#' . $id, $js);

	}

	*/

public function run()

    {

        list($name, $id) = $this->resolveNameID();

 

        if (is_array($this->data) && !empty($this->data)){

            //if $data is not an assoc array make each value its key

            if($this->assoc){

                $data=$this->data;      

            }

            else{

                $data=array_combine($this->data, $this->data);

 

            }

            //does the same as array_unshift($data,null) but does not break assoc arrays

            $data=array(""=>"")+$data;

        }

        else

            $data = array();

 

        if ($this->hasModel())

            echo CHtml::activeDropDownList($this->model,$this->attribute,$data);

        else

            echo CHtml::dropDownList($name, $this->value, $data);

 

        echo CHtml::textField(null,($this->hasModel()?($data[$this->model->{$this->attribute}]):$data[$this->value]),array('id'=>$id.'_combobox'));

 

        $this->options = array_merge($this->defaultOptions, $this->options);

 

        $options = CJavaScript::encode($this->options);

 

        $cs = Yii::app()->getClientScript();

 

        $js = "combobox({$options});";

 

        list($id, $js) = $this->setSelector($id.'_combobox', $js);

        $cs->registerScript(__CLASS__ . '#' . $id, $js);

    }

}




Any help would greatly appreciated.

Regards,

I solved the problem. By default, Yii gets the Not Null attribute of a column during runtime from the database, so if a column is marked as Not Null in database, it applies zero (0) as its default value. When "$this->model->{$this->attribute}" was getting executed, it was putting "0" instead of "problem_definition_id" which was throwing error. After making the column to Nullable in database, the error vanished. But since this does not seem a good solution. So after I created the $PatientProblem object, I explicitly set the problem_definition_id to null and it resolved the error.