Cjuiautocomplete Added In A Module Dynamically

Hello,

I have a form that contains an autocomplete:




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

		'name'=>'Entity[entityAutoComplete]',

		'value'=> '',

		'source'=>$this->createUrl('entity/autoComplete'),// <- path to controller which returns dynamic data

		// additional javascript options for the autocomplete plugin

		'options'=>array(

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

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

				var destination = $(event.target).parent();

				var url = "'.Yii::app()->homeUrl.'";

				$.get(url+"?r=jtemplate/bubble",

					{ title: ui.item.label, 

					  id: ui.item.value,

					  type: "entity",

					  hiddenFieldName :  "Entity[bubbles][toAdd]",

					  remove: "true"

					},

					function(data){

						$(destination).append(data);

				});

				event.target.value ="";

				return false;

			}',


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

				//if it is empty add button

				if (ui.content.length === 0) {

					var input = $(event.target);

					if (input.parent().find(".addNew").length===0){

						input.after("<button class=addNew>Add</button>");

					}

					return false;

				}

				else {

					//else remove button

					var input = $(event.target);

					input.parent().find(".addNew").remove();

					return false;

				}

			}'

		),

		'htmlOptions'=>array(

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

			'onfocus' => 'js: this.value = null;'

		),

	));

	?>



Then something is selected from that autocomplete and then I render with ajax this CWidget view (Bubble.php) based on what was selected.


<span class="bubble <?php echo $this->type; ?>">

Bubble Type: 

<div class="row">

<?php

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

		'name'=>'Entity[bubbleAutoComplete]',

		'value'=> '',

		'source'=>Yii::app()->createAbsoluteUrl('bubble/autoComplete'),// <- path to controller which returns dynamic data

		// additional javascript options for the autocomplete plugin

		'options'=>array(

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

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

				var destination = $(event.target).parent();

				var url = "'.Yii::app()->homeUrl.'";

				$.get(url+"?r=jtemplate/bubble",

					{ title: ui.item.label, 

					  id: ui.item.value,

					  type: "entity",

					  hiddenFieldName :  "Entity[bubbles][toAdd]",

					  remove: "true"

					},

					function(data){

						$(destination).append(data);

				});

				event.target.value ="";

				return false;

			}',


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

				//if it is empty add button

				if (ui.content.length === 0) {

					var input = $(event.target);

					if (input.parent().find(".addNew").length===0){

						input.after("<button class=addNew>Add</button>");

					}

					return false;

				}

				else {

					//else remove button

					var input = $(event.target);

					input.parent().find(".addNew").remove();

					return false;

				}

			}'

		),

		'htmlOptions'=>array(

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

			'onfocus' => 'js: this.value = null;'

		),

	));

?>

</div>

<?php

	$random = rand();

	echo CHtml::link(CHtml::encode($this->title), 

		array($this->type.'/view', 'id'=>$this->id));


	if (isset($this->hiddenFieldName)){

		echo CHtml::hiddenField($this->hiddenFieldName.'['.$random.']',$this->id);

	}

	if ($this->remove==="true"){

		?>

		<span class="remove">X</span>

		<?php

	}

?>

</span>

I see that the widget (which contains another autocomplete) is being rendered and I can see the corresponding input. But that input doesn’t have the class=“ui-autocomplete-input”. I tried different sources (static array / absolute/relative url - without any luck) but it seems that the javascript is not initialized for this input to be an autocomplete… So how can we add cwidgets that contain functional autocomplete to be rendered ?

My Widget is this:


<?php

class Bubble extends CWidget {

 	

 	public $id;

 	public $title;

 	public $type;

 	public $hiddenFieldName;

 	public $remove; //the button for removal

    public function run() {

        $this->render('bubble');

    }

 

}

?>

Can you please help me with that?

Thanks in advance

Ok Solved it using the guideline from that post:

http://www.yiiframework.com/forum/index.php/topic/31576-ajax-and-widgets/page__view__findpost__p__232844

What I did is basically put this true parameter (see last line of code below) in the widget that was coming in each ajax response (view of CWidget Bubble.php). I stored the widget in a variable:


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

		'name'=>'Entity[bubbleAutoComplete]',

		'value'=> '',

		'source'=>Yii::app()->createAbsoluteUrl('bubble/autoComplete'),// <- path to controller which returns dynamic data

		// additional javascript options for the autocomplete plugin

		'options'=>array(

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

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

				var destination = $(event.target).parent();

				var url = "'.Yii::app()->homeUrl.'";

				$.get(url+"?r=jtemplate/bubble",

					{ title: ui.item.label, 

					  id: ui.item.value,

					  type: "entity",

					  hiddenFieldName :  "Entity[bubbles][toAdd]",

					  remove: "true"

					},

					function(data){

						$(destination).append(data);

				});

				event.target.value ="";

				return false;

			}',


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

				//if it is empty add button

				if (ui.content.length === 0) {

					var input = $(event.target);

					if (input.parent().find(".addNew").length===0){

						input.after("<button class=addNew>Add</button>");

					}

					return false;

				}

				else {

					//else remove button

					var input = $(event.target);

					input.parent().find(".addNew").remove();

					return false;

				}

			}'

		),

		'htmlOptions'=>array(

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

			'onfocus' => 'js: this.value = null;'

		),

	),true);

Then I used these two lines below it:




Yii::app()->getClientScript()->renderBodyEnd($html);

echo $html;

and the javascript started working for that dynamically/ajax added autocomplete widget :)

Of course this makes a new request to jquery.ui.js for each request…

So I had to install nlsclient that merges the javascript files !! and doesn’t make a 230kb request for each of my dynamically made widgets!

http://www.yiiframework.com/extension/nlsclientscript/

Hope this helps someone! It took me about 4 hours to solve my problem…

Great. Thanks for sharing

Great Solution Zifnab.

But it works for me with

Yii::app()->getClientScript()->render($html); than

Yii::app()->getClientScript()->renderBodyEnd($html);

I use twitter boostrap 3. After i do this way, my boostrap.js did not work. Do you know why?