How to make CJuiAutoComplete efficient

The following is the action that returns the terms for a CJuiAutoComplete field. It works fine, but having to manually convert the results to an array seems messy and I was wondering if there was a neater way? If just put the AR result directly into the json encoding it isn’t working.




	public function actionCats($term)

	{

		$rows = Cat::model()->findAll(

			array(

				'select'=>'name',

				'condition' => 'name LIKE :string',

				'params' => array(

					':string'=>$term. '%',

				)

			)

		);

		foreach ($rows as $row)

		{

			$json_array[] = $row->name;

		}

		$json = CJSON::encode($json_array);

		echo $json;


	}



Try this:




//

// please change {{cat}} according to your model table

public function actionCats($term)

{

   

        $query ="SELECT name FROM {{cat}} WHERE name LIKE :string";


	$command =Yii::app()->db->createCommand($query);


	$command->bindValue(":string", '%'.$term.'%', PDO::PARAM_STR);


	$result =$command->queryColumn();


	echo CJSON::encode($result);


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

}

Thanks Antonio

I was trying to do it within the model, but this will do.

My pleasure! It is always good to share knowledge on this AMAZING framework.

is is possible to add a chain method ( on the result of CJuiAutoComplete ) to also populate an hidden field?

I mean, with CJuiAutoComplete I want to find usernames LIKE $_GET[‘q’] but also populate an hidden_field ‘user_id’ because of username is not unique.

@SystemicPlural: you can also find an example here.

bye,

Giovanni.

check http://jqueryui.com/demos/autocomplete/#events

You can add a function to the options like this (check ‘change’):


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

            'name'=>'Something[something_name]',

            'value' => '',

            

            'sourceUrl' => $this->createUrl('/admin/something/getSomething'),

            

            'options'=>array(

                'showAnim'=>'fold',

                'minLength' => 3,                

                'change' => 'js:function(event, ui){alert("!!!")}'

            ),

            'htmlOptions'=>array(

                'style'=>'height:16px;'

            ),

        ));

Hi,

I got Autocompletion up and running, as it selects usernames and shows them.

Thanks for your advice so far :slight_smile:

But what I just don’t get is how I can populate the picked item to an action via _GET Method.

Are there any suggestions?

Best regards

Ralf

I don’t fully understand your question, could you describe the situation more?

You want to send a request to the server with the value? Just put the ajax request into the event handler js function like I showed above.

Yes, I’ve read your posting, but I just don’t know, what kind of event I have to send :slight_smile:

I guess, I’ve to change




 'change' => 'js:function(event, ui){alert("!!!")}'



So I tried to google something about opening URL’s with an event, but that left me with the question, how can I generic put the choice in an GET Request which is targeting to an action like CActiveForm is doing.

Like




change' => 'js:function(event, ui){something("controller/action&User[username]=GenericSearchString&yt0=Search")}'



The part behind the "&" has to be generic, right?

I’m just not very familiar with the Ajax-Stuff… sorry for that :slight_smile:

Best regards

Ralf

I’m screwed. I have no idea how to go on from now with that whole AutoCompletion Desaster…

What I would like to do:

I have searchform in the sidebar. You should be able to type in some letters and CJuiAutoComplete is doing it’s job.

When you selected a suggested item from a list and hit ENTER a search should be initiated with the selected value.

Sounds easy… but it isn’t.

What is working:

I followed the Playground-instructions and yes, it works like a charm. There are appearing items during typing into the input-box. And yes, I can select those items. Pretty cool!

What isnt’ working:

The code for some explanation




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

    'name'=>'username',

    'value'=>'',

    'source'=>$this->createUrl('user/autoComplete'),

    // additional javascript options for the autocomplete plugin

    'options'=>array(

            'showAnim'=>'fold',

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

    ),

));



As you can see, I putted in a select Event. The function is just for debugging and it says "undefined".

Thats Problem number 1. Why does it says its undefinded? I guess it’s because I missed something.

I do have a controlleraction called actionIndex (user/index - which resides in the UserController.php as the actionAutoComplete).

What I would like to do is to pump the selected item via _GET into the actionIndex because there is the Code to render a search-view etc. doinf all the $model stuff.

So I just dont get it to work in that way and I have no idea after hours of research and try and error.

Maybe someone has any idea…

Thanks a lot.

First part:

The cause of the missing ‘id’ could be server related. YOu have to send the data like this:


$arr = array();

foreach($models as $model) {

    $arr[] = array(

        'label'=>$model->some_attr,  // label for dropdown list          

        'value'=>$model->some_attr,  // value for input field          

        'id'=>$model->id,            // return value from autocomplete

        );      

}

echo CJSON::encode($arr);

The ui parameter to the ‘select’ event represents one ‘row’ form the JSON-ed data.

Second part:

You want to use the selected search parameter to load another page with the search results? If so, you don’t have to use AJAX for that, just use document.location to set the redirect.

If you want to update the gridview on the right side, I don’t have idea for that.

Dear szako,

thanks a lot for your help!

I guess I will take a step back and first do some research on JavaScript and AJAX to be more familiar with this kind of stuff.

Best regards

Ralf

Okay, I solved it somehow.

The magic lies in CActiveForm together with CJuiAutoComplete and the relation to a model and an <imput id=’’>

The Code goes like this, in the _view File:





// Okay, thats the normal form.

// Recognize, that there is no $form->textField($model,'username')!!

// It's coming thru CJuiAutoComplete!

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

	'action'=>Yii::app()->createUrl('user'),

	'method'=>'get',

));

?>


// Instead of the textField you take the AutoComplete Widget.

// But some things are important:	

<?php

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

     // put in your $model Objekt

    'model'=>$model,

     // and it's needed attribute

    'attribute'=>'username',

    'value'=>'',

    'source'=>$this->createUrl('user/autoComplete'),

    // additional javascript options for the autocomplete plugin

    'options'=>array(

            'showAnim'=>'fold',

             // This is an propper function to fire the form after selecting an item (thx@ Mike :-))

             'select' => 'js:function(event, item){ $(this).parents("form").submit(); }'

    ),

     

));

?>

	<div class="row buttons">

		<?php echo CHtml::submitButton('Search'); ?>

	</div>

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






So, thats it :slight_smile:

Best regards

Ralf

Cool :)

I didn’t really understand what you wanted to achieve.

With the exception that there is a small bug (typo) in that Yii Playground example. I.e. there should be line:


'name'=>'term',

instead of:


'name'=>'test1',

EDIT: Or shouldn’t? Got confused! :expressionless:

Shouldn’t; term is a parameter used by the ajax call (using get method) to retrive the list of items matching the user input, while test1 is just the id of the text input field.

bye,

Giovanni.