CJuiAutoComplete - If the user doesn't select from the list

Dear All,

I have a CJuiAutoComplete , where user selects his company name from the given list . For this I am using DAO layer and getting the company name and ID from the database . If user selects the company name , I am assigning ID to a hidden field ( In SELECT event ) .During the form submit I am inserting the ID in database against the user . No issues at this level .

Now comes the case , for example there is a company called "Test Company " , even the CJuiAutoComplete suggests it if user without selecting it and just types it … how do I get the ID of it and insert it in database ? Because here user didn’t select it , he written the company name fully … . Below is the code I have, working fine for user selection ( If the hidden field doesn’t have any value I am assuming it as a new company after form submit, But in the above case it is not a new company , the user has not selected any and just typed existing company name)

Thanks for your help

Regards

Yii Fan

CONTROLLER


  public function actionSetCompany(){


		if(isset($_GET['term'])){

			$autoCompleate=new MyAutoComplete();

			$models=$autoCompleate->getCompany($_GET['term']);

			echo CJSON::encode($models);

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

		}

	}

MODELER


 public function getCompany($company){

		$sql="SELECT name value,id id FROM list_companies WHERE name LIKE '%$company%'  LIMIT 10";

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

		$rowArray=$command->queryAll();

		return $rowArray;

	 }

VIEW


<?php


 echo CHtml::beginForm();


 echo CHtml::hiddenField("my_company_id");


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

			'name'=>'searchCompany',

			'id'  => 'searchCompany',

		   'source'=>'js: function(request, response) {

			   $.ajax({

				   url: "'.$this->createUrl('updateProfile/autoCompany').'",

				   dataType: "json",

				   data: {

					   term: request.term,

				   },

				   success: function (data) {

						   response(data);

				   }

			   })

			}',

			 'options' => array(

							'showAnim' => 'fold',

							'minLength' => '2',

							'select'=>'js:function( event, ui ) {

									$("#my_company_id").val(ui.item.id);

									alert(ui.item.id);

							}',


			 ),


			 'htmlOptions' => array(

			 )




		));


echo CHtml::endForm();

?>

Hi,

i had exactly the same problem. I have solved it with following widget code -> http://pastie.org/3115690. Extract parts you need ;).

My ajax response looks like this:


[{"id":10,"label":"City 1","value":"City 1"},{"id":12,"label":"City 2","value":"City 2"}]

Regards Robert

Thanks a lot bn77 for your help . This is simply wonderful

Regards

Kiran

no problem, i transformed this code waste into an widget, that extends the yii AutoComplete Widget. DRY -> don’t repeat yourself…


<?php

/**

 * JqueryUiAutoComplete class file.

 *

 * @author Robert Bernhard <bloddynewbie@gmail.com>

 */

\Yii::import ('zii.widgets.jui.CJuiAutoComplete');


/**

 * JqueryUiAutoComplete erweitert CJuiAutoComplete

 *

 * 1. Aktivierung/Deaktivierung einer Zwangsauswahl

 * 2. Anzeige der übereinstimmen Wortphrase im AutoComplete

 * 3. Implementierung eines Hiddenfeldes für einen verborgenen ID Feldes

 *

 * @author Robert Bernhard <bloddynewbie@gmail.com>

 * @package application.components.widgets

 * @subpackage jui

 */

class JqueryUiAutoComplete extends CJuiAutoComplete

{

	/**

 	* zwanghafte Selektion erforderlich

 	* @var boolean $requiredSelection wenn gesetzt, wird der eingegebene Value gegen die Suggestion geprüft und bei Bedarf geleert 

 	*/

	public $requiredSelection = false;

	

	/**

 	* Anzeige der Suchphrase in Suggest

 	* @var boolean $showMatchingResult - wenn gesetzt, wird im Suggest der übereinstimende Teile der Eingabe fett markiert

 	*/

	public $showMatchingResult = false;

	

	/**

 	* Verwendung eines Hidden ID Feldes

 	* @var string $hiddenFieldName - wenn nicht null, wird die ID der ausgewählten Suggestion in dieses Feld gespeichert

 	*/

	public $hiddenIdFieldName = null;

	

	/**

 	* @var int $minLength Mindestlänge der Eingabe, bevor der Suggest aktiv wird

 	*/

	public $minLength = 3;

	

	/**

 	* @var string unique ID des Attributes

 	*/

	private $attributeId;

	

	/**

 	* @var string dient als proxy zum Ablegen und Abgreifen der Ajax Response Daten zur späteren Validierung

 	*/

	private $jqueryDataProxy;


	/**

 	* Renders the open tag of the dialog.

 	* This method also registers the necessary javascript code.

 	*/

	public function run ()

	{

		$this->createSource ();

		$this->createOptions ();

		

		parent::run ();

	}

	

	/**

 	* erstellt das source-Attribut für jQuery

 	*/

	private function createSource ()

	{

		$this->attributeId   	= \CHtml::getActiveId ($this->model, $this->attribute);

		$sourceUrl	           = $this->sourceUrl;

		$this->sourceUrl   	= null;

		$this->jqueryDataProxy = 'reponseDataFor' . $this->attributeId;

		

		$juiRenderMethod = $juiMatcherCode = null;

		if ($this->showMatchingResult)

		{

			$juiRenderMethod = '

				// overwrite renderer to display bold text as html

				$("#' . $this->attributeId . '").data ("autocomplete")._renderItem = function (ul, item) {

					return $("<li></li>")

						.data ("item.autocomplete", item)

						.append ("<a>" + item.label + "</a>")

						.appendTo (ul);

				};';

			

			$juiMatcherCode = '

				var matcher = new RegExp ($.ui.autocomplete.escapeRegex (request.term), "i");

				var text	= $(this).value;


				// format mathing label elements with bold html

				for (key in data)

				{

					if (data [key].label && ( !request.term || matcher.test (data [key].label))) {

						data [key].label = data [key].label.replace (

							new RegExp(

								"(?![^&;]+<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />(?!<[^<>]*)(" +

								$.ui.autocomplete.escapeRegex (request.term) +

								")(?![^<>]*>)(?![^&;]+<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/wink.gif' class='bbc_emoticon' alt=';)' />", "gi"

							), "<strong>$1</strong>");

					}

				}';

		}

		

		$this->source = 'js:

			function (request, response) {

				' . $juiRenderMethod . '


				$.ajax ({

					type: "post",

					url:  "' . $sourceUrl . '",

					data: { 

						term: request.term,

						' . \Yii::app()->request->csrfTokenName . ': "' . \Yii::app()->request->getCsrfToken() . '"

					},

					dataType: "json",

					success: function (data) {

						// register data in jQuery to access it later

						$.' . $this->jqueryDataProxy . ' = data;

						

						' . $juiMatcherCode . '


						response(data);

					}

				});

			}';

	}

	

	private function createOptions ()

	{

		$requiredSelection = null;

		if ($this->requiredSelection)

		{

			$requiredSelection = '$(this).val ("");';

		}

		

		$optionSelect = $optionChange = $fillHiddenField = null;

		if (!is_null ($this->hiddenIdFieldName))

		{

			echo \CHtml::activeHiddenField ($this->model, $this->hiddenIdFieldName);

			

			$optionSelect = 'js: 

				function (event, ui) { 

					if (!ui.item)

					{

						return false;

					}


					$("#' . \CHtml::getActiveId ($this->model, $this->hiddenIdFieldName) . '").val (ui.item.id);

				}';

			

			$requiredSelection .= '$("#' . \CHtml::getActiveId ($this->model, $this->hiddenIdFieldName) . '").val ("");';

			$fillHiddenField    = '$("#' . \CHtml::getActiveId ($this->model, $this->hiddenIdFieldName) . '").val ($.' . $this->jqueryDataProxy . ' [key].id);';

		}

			

		$optionChange = 'js: 

			function (event, ui) {

				if ( !ui.item )

				{

					var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "{:content:}quot;, "i");


					for (key in $.' . $this->jqueryDataProxy . ')

					{

						if ($.' . $this->jqueryDataProxy . ' [key].value.match (matcher))

						{

							$(this).val ($.' . $this->jqueryDataProxy . ' [key].value);

							' . $fillHiddenField . '


							return false;

						}

					}


					' . $requiredSelection . '


					return false;

				}

			}';

		

		$this->options = array (

			'minLength' => $this->minLength,

			'select'	=> $optionSelect,

			'change'	=> $optionChange,

		);

	}

}

use with:





<?php

	$this->widget (

		// put in your own widget path here, my path is application/components/widgets/JqueryUiAutoComplete/JqueryUiAutoComplete.php

		'application.components.widgets.JqueryUiAutoComplete.JqueryUiAutoComplete',

		array (

			'attribute'	         => 'city',

			'hiddenIdFieldName' 	=> 'cityId',

			'model'		         => $model,

			'sourceUrl'	         => $this->createUrl ('/profile/default/citysearch'),

			'requiredSelection'  => true,

			'showMatchingResult' => true,

		)

	);

?>



Your view looks much smarter with that stuff ;-).

Regards

Robert

Thank You Robert for this widget . I am going to use it and let you know if I see any issues . I see some "\" added before "Yii::import" and "CHtml::" .

You can release it as extension :) . About my view … ::) :lol: :lol:

I have tried using this without any success. It does not display the control and anything else after that point, the style is effected as well… I am pretty confused as I am new to Yii. Any ideas?