CAutoComplete populate HiddenField

I am using a CAutoComplete to aid in filtering a list of Players. The return shows Player.first_name, Player.second_name, Player.dob, Player.parent_name, Player.id in order to make sure the correct player is selected (to eliminate same name confusion). Is there a way to set the Player.id returned to a hidden field or for the id to be the value returned by the CAutoComplete field? I tried to follow the cookbook thinking that the hiddenfield would be filled by JS specified in the methodChain but I am not getting the desired result so I think I may not follow the example completely.

This is my complete form, I want to link current player to existing player (player_id_1, player_id_2 in db)




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

	'id'=>'playerlink-form',

	'enableAjaxValidation'=>false,

)); ?>


	


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

	<?php echo $form->hiddenField($playerLinkModel,'season_id',array('value'=>SeasonLeague::model()->getCurrentSeasonID()));?>

	<?php echo $form->hiddenField($playerLinkModel,'player_id_1',array('value'=>$playerData->id));?>

	<div class="row">

		<?php echo $form->labelEx($playerLinkModel,'Link To'); ?>

		<?php //echo $form->dropDownList($playerLinkModel,'player_id_2', CHtml::listData(Player::model()->findAll(),'id','concatened')); ?>

		<?php 

				

			  	$this->widget('CAutoComplete',

          array(

                         //name of the html field that will be generated

             'name'=>'player_link', 

                         //replace controller/action with real ids

             'url'=>array('currentlinks/autoCompleteLookup'), 

             'max'=>10, //specifies the max number of items to display

 

                         //specifies the number of chars that must be entered 

                         //before autocomplete initiates a lookup

             'minChars'=>2, 

             'delay'=>500, //number of milliseconds before lookup occurs

             'matchCase'=>false, //match case when performing a lookup?

 

                         //any additional html attributes that go inside of 

                         //the input field can be defined here

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

 

             'methodChain'=>".result(function(event,item){\$(\"#player_id_2\").val(item[4]);})",

             ));

		?>

		<?php CHtml::hiddenField('player_id_2');?>

		

		<?php echo $form->error($playerLinkModel,'Link To'); ?>

		

		

	</div>

		

	<div class="row">

		<?php echo $form->labelEx($playerLinkModel,'Link Type'); ?>

		<?php echo $form->dropDownList($playerLinkModel,'type', array('Guaranteed'=>'Guaranteed','Sibling'=>'Sibling','Friend'=>'Friend',)); ?>

		<?php echo $form->error($playerLinkModel,'Link Type'); ?>

	</div>


	


	<div class="row buttons">

		<?php echo CHtml::submitButton($playerLinkModel->isNewRecord ? 'Add' : 'Add'); ?>

	</div>


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




From my controller (which needs some some refactoring but trying to get a proof of concept working):




public function actionAutoCompleteLookup()

    {

       if(Yii::app()->request->isAjaxRequest && isset($_GET['q']))

       {

            /* q is the default GET variable name that is used by

            / the autocomplete widget to pass in user input

            */

          $name = $_GET['q']; 

                    // this was set with the "max" attribute of the CAutoComplete widget

          $limit = min($_GET['limit'], 50); 

          $criteria = new CDbCriteria;

          $criteria->condition = "last_name LIKE :sterm OR first_name LIKE :sterm";

          $criteria->params = array(":sterm"=>"%$name%");

          $criteria->limit = $limit;

          $userArray = Player::model()->findAll($criteria);

          $returnVal = '';

          foreach($userArray as $userAccount)

          {

             $returnVal .= $userAccount->getAttribute('first_name').' '

                                         .$userAccount->getAttribute('last_name').' '

                                         .$userAccount->getAttribute('dob').' '

                                         .$userAccount->getAttribute('parent_name').' '

                                         .$userAccount->getAttribute('id')."\n";

             

          }

          echo $returnVal;

       }

    }



When I do a print of the post data I get the following:




Array ( [PlayerLink] => Array ( [season_id] => 3 [player_id_1] => 6 [type] => Guaranteed ) [player_link] => John Doe 0000-00-00 Jim and Jane Doe 1 [yt0] => Add ) 



I am looking for the additional hiddenfield to be present with value 1 for John Doe

I have gone back and I am trying to use CJuiAutoComplete since CAutoComplete is deprecated or at least I read that somewhere.

I have the following

controller code:




public function actionAutocomplete()

    {

      $res = array();

      $term = Yii::app()->getRequest()->getParam('term', false);

      

      if ($term)

      {

      	

         // test table is for the sake of this example

         $sql = 'SELECT first_name, last_name, id FROM tbl_player where first_name like :fname OR last_name like :lname';

         $cmd = Yii::app()->db->createCommand($sql);

         $cmd->bindValue(":lname","%".$term."%", PDO::PARAM_STR);

         $cmd->bindValue(":fname","%".$term."%", PDO::PARAM_STR);

         $res = $cmd->queryAll();

         

      }

      

      

      echo CJSON::encode($res);

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

   }



My widget:




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

    //'model'=>$model,

    //'attribute'=>'name',

    'id'=>'country-single',

    'name'=>'country_single',

    'source'=>$this->createUrl('currentlinks/autocomplete'),

    'options'=>array(

		'minLength'=>'1', // min chars to start search

		'select'=>'js:function(event, ui) { console.log(ui.item.id +":"+ui.item.value); }',

		'showAnim'=>'fold',

	),


    'htmlOptions'=>array(

        'size'=>'40'

    ),

));



I am not getting the results of my autocomplete query.

If I replace $res with a simple string like $res = ‘test’;

I get

t

e

s

t

returned in my autocomplete. If I run a test on my autocomplete by hardcoding $term I get the expected array [{"first_name":"Carson","last_name":"Palmer","id":"1"}]. If I do a CJSON::encode on $term I get the keystrokes displayed on individual lines.

t

e

s

t

when I do the CJSON on the query result I see a small rectangle outline but nothing else.

I would like to present multiple fields to the end user but submit only the ID. Please help me.

This may help regarding displayed vs returned value.

/Tommy

Thanks Tommy. I can’t even get to a point to worry about populating the field since I can’t get the data to show up for the user to select. I have added some tracing and I am getting the following out put when tracing the CJSON::encode method call

autocomplete CJSON returns [{"first_name":"Joe","last_name":"Creary","id":"6"},{"first_name":"Oliver","last_name":"Cradle","id":"10"}]

if the echo string is

[{"first_name":"Joe","last_name":"Creary","id":"6"},{"first_name":"Oliver","last_name":"Cradle","id":"10"}]

all of the examples have the autocomplete method doing the following:


 echo CJSON::encode($res);

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



My assumption is that the AJAX calls are expecting a CJSON formatted string and will parse and display the data accordingly. What am I missing?

As pointed out in the example, the string to be displayed for each dropdown row should go into the label array member. So in the example there are three array members for each record (named label, value, id). Finally you convert the whole array to json (just like you already did).

/Tommy

so I need to do something like




$arr = array();

foreach($res as $resitem)

{

     $arr[]= array('label'=>$resitem["first_name"],

                   'value'=>$resitem["first_name"],

                   'id'=>$resitem["id"]

                 );

}


echo CJSON::encode($arr);

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






I think I have confused myself on getting the data out of $res which should be an array.

Edit: That works, however if I click an item in the list it doesn’t populate the text field.

Edit2: That is fixed the text field width was too small.

Thank you for clarifying your earlier post!! And for taking the time to help!

view code should be

<div class="row">

<?php echo CHtml::label(‘name’,’’); ?>

<?php

$this->widget(‘CAutoComplete’,array(

‘name’=>‘level1’,

‘url’=>CController::createUrl(‘Dependent/autocompletelookup’),

‘minChars’=>1,

‘delay’=>100, //number of milliseconds before lookup occurs

‘matchCase’=>false, //match case when performing a lookup?

‘methodChain’=>".result(function(event,item){\$(\"#user_id1\").val(item[1]);})",

));

?&gt;

<?php echo CHtml::hiddenField(‘user_id1’); ?>

</div>

and controller code

public function actionAutoCompleteLookup()

{

if(Yii::app()->request->isAjaxRequest && isset($_GET[‘q’]))

{

$org = Yii::app()->user->getState(‘org_id’);

$name = $_GET[‘q’];

$limit = min($_GET[‘limit’], 50);

$userArray = Employee::model()->findAll(array(

‘condition’ => ‘t.employee_first_name LIKE :name and employee_info_transaction_id IN(select employee_transaction_id from employee_transaction where employee_transaction_user_id in(select assign_user_id from assign_company_user_table where assign_org_id=’.Yii::app()->user->getState(‘org_id’).’ ))’,

‘params’ => array(’:name’ => “%$name%”),

));

$returnVal = ‘’;

foreach($userArray as $userAccount)

{

$returnVal .= $userAccount->getAttribute(‘employee_first_name’)." “.$userAccount->getAttribute(‘employee_middle_name’).” “.$userAccount->getAttribute(‘employee_last_name’).’|’.$userAccount->getAttribute(‘employee_info_transaction_id’).”\n";

}

echo $returnVal;

}

}