Clone Autocomplete

Hi guys,

I have a problem trying to clone a CAutoComplete. I have a table with 2 columns, each of them has a CAutoComplete.


<table>

	    <tr> 

	         <td><?php echo $form->labelEx($model,'user_id'); ?>

				<?php $this->widget('CAutoComplete', array(

									'model'=>$model,

									'attribute'=>'user_id',

									'url'=>$this->createUrl('user/suggest'),

									'multiple'=>false,

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

				)); ?>

	         <td><?php echo $form->labelEx($model,'profile'); ?>

					<?php $this->widget('CAutoComplete', array(

										'model'=>$model,

										'attribute'=>'profile',

										'url'=>$this->createUrl('profile/suggest'),

										'multiple'=>false,

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

					)); ?>

	    </tr>

	</table>

	<button id="cloneButton2">Add Row</button>

I want to clone the first row of the table with the "Add row" button. I do it like this:


<script type="text/javascript">

var i = 1;

$("#cloneButton2").click(function() {

$("table tr:first").clone().find("input").each(function() {

$(this).val('').attr('id', function(_, id) { return id + i });

}).end().appendTo("table");

</script>



This works ok, because the rows are added to the table, but the automplete event doesn´t work for the added rows, although it works for the first one.

Any suggestion?

You’ll have to attach the autocomplete to each field you dynamically add.

In this case the JUI widget is not good for you, you’ll have to include the jquery ui library then set the autocomplete settings in a variable and use that variable to instantiate the initial autocomplete and also the ones you dinamically add.

Thanks for your answer. I tried with a simple example following your instructions like this:




<html>

<head>

    <!-- script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script-->

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.js"></script>

    <script type="text/javascript">


        $(document).ready(function(){

            var myTags = ["aaa","PHP", "Perl", "Python"];

			$('body').delegate('input.tags', 'focusin', function() {

			    if($(this).is(':data(autocomplete)')) return;

			    $(this).autocomplete({

			        "source": myTags

			    });

			});

			var tagsdiv = $('#tags');

			$('body').delegate('a.copy', 'click', function(e) {

			    e.preventDefault();

			    $(this).closest('div').clone().appendTo(tagsdiv);

			});

        });

    </script>

</head>


<body>

    <div id="tags">

        <div>

            <label for="tags">Tags: </label>

            <input class="tags" />

            <a href="#" class="copy">Copy</a>

        </div>

    </div>    

</body>

</html>



This works ok, but i don´t want static data in my autocomplete, I want a remote request. I´ve tried several things, but it seems to me I´m not doing the correct ajax function:




<html>

<head>

    <!-- script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script-->

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.js"></script>

    <script type="text/javascript">


        $(document).ready(function(){

           		$('body').delegate('input.tags', 'focusin', function() {

			    if($(this).is(':data(autocomplete)')) return;

			    $(this).autocomplete({

			    	source: function( request, response ) {

			    		$.ajax({

			    		    //url:"http://127.0.0.1/myApp/user/suggestUser",

			    		    url: "<?php echo $this->createUrl('user/suggestUser')?>",

			    		    type:"GET",

			    		    dataType:"xml",

			    		    success:function(response){

				    		    alert('result ok');

			    		    },

			    		    error:function(){

			    		         alert('Failed request data from ajax page");

			    		    }	

					},

					minLength: 2,

			    });

			});

			

			var tagsdiv = $('#tags');

			$('body').delegate('a.copy', 'click', function(e) {

			    e.preventDefault();

			    $(this).closest('div').clone().appendTo(tagsdiv);

			});

        });

    </script>

</head>


<body>

    

    <div id="tags">

        <div>

            <label for="tags">Tags: </label>

            <input class="tags" />

            <a href="#" class="copy">Copy</a>

        </div>

    </div>

    

</body>

</html>



In my controller I have:




public function actionSuggestUser()

	{


		if(isset($_GET['q']) && ($keyword=trim($_GET['q']))!=='')

		{

                    ...



I know the controller works ok, because I have tested it with de CAutoComplete widget, but as I can´t clone it, I need to make an ajax function and I don´t know how to make it work.

http://jqueryui.com/demos/autocomplete/remote.html

Take a look in the page source. you were close enough :)

Thanks again twisted1919. In my previous example I followed this link or at least I tried.

With your link I tried with something like this:




$('body').delegate('input.tags', 'focusin', function() {

	if($(this).is(':data(autocomplete)')) return;

            $(this).autocomplete({

		source: "http://127.0.0.1/myApp/user/suggestUser",

		minLength: 2,

		select: function( event, ui ) {

		log( ui.item ?

		     "Selected: " + ui.item.value + " aka " + ui.item.id :

		     "Nothing selected, input was " + this.value );

		}

	    });

      });



It doesn´t work for me either. I´m new with Yii and JQuery, but I´m pretty sure I´m missing something really easy, but can´t figure it out.

how about using jquery’s on() method (http://api.jquery.com/on/) instead of delegate ?

I have tried with on() but no luck either. I think the problem is how i am doing the remote request. I have tried with (using delegate() and on()):




$('body').delegate('input.tags', 'focusin', function() {

        if($(this).is(':data(autocomplete)')) return;

            $(this).autocomplete({

                source: "http://127.0.0.1/myApp/user/suggestUser",

                minLength: 2,

                select: function( event, ui ) {

                log( ui.item ?

                     "Selected: " + ui.item.value + " aka " + ui.item.id :

                     "Nothing selected, input was " + this.value );

                }

            });

      });



and




$('body').delegate('input.tags', 'focusin', function() {

                            if($(this).is(':data(autocomplete)')) return;

                            $(this).autocomplete({

                                source: function( request, response ) {

                                        $.ajax({

                                            //url:"http://127.0.0.1/myApp/user/suggestUser",

                                            url: "<?php echo $this->createUrl('user/suggestUser')?>",

                                            type:"GET",

                                            dataType:"xml",

                                            success:function(response){

                                                    alert('result ok');

                                            },

                                            error:function(){

                                                 alert('Failed request data from ajax page");

                                            }   

                                        },

                                        minLength: 2,

                            });

                        });



But none of them work. What am i doing wrong?

Thanks in advance.

Neah, let’s try something like this:




jQuery(document).ready(function($){

	

	// define global autocomplete settings

	var autocompleteSettings={

		source: "/myApp/user/suggestUser",

		minLength: 2,

		select: function( event, ui ) {

			console.log( ui );

		}

	};

	

	//instantiate the existing field with the autocomplete.

	$("input.tags").autocomplete(autocompleteSettings);

	

	// create the action when the input field is cloned.

	var i = 1;

	$("#cloneButton2").click(function() {

		var $cloned=$("table tr:first").clone();

		$cloned.appendTo("table");

		$("input",$cloned).each(function() {

			$(this).val('').attr('id', function(_, id) { return id + i });

			$(this).autocomplete(autocompleteSettings);// this is the important bit.

		});

                return false;

	});

	

});



After you add the above code, the default input field, with autocomplete should work, then, after you clone next fields, those should use autocomplete too.

Try this way and let’s see how it goes.

P.S: not tested, there might be small issues with the code, but you can handle them.

Thanks again, again and again. It worked!!! I want to share my final code:




<html>

<head>

    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.js"></script>

    <script type="text/javascript">


		jQuery(document).ready(function($){

		        // define global autocomplete settings

		        var autocompleteSettings={

		        		'source': '/myApp/user/suggestUser',// the action that provides data

                        'minLength':1,

                        'select': function( event, ui ) {

                        	$(this).val( ui.item.user_name );

                         	console.log( ui );

                            return false;

                           

                    	}

		        };

		        //instantiate the existing field with the autocomplete.

		        $("#cloneTag").autocomplete(autocompleteSettings).data( 'autocomplete' )._renderItem = function( ul, item ) {

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

					.data( 'item.autocomplete', item )

					.append( '<a>' + item.user_code + '<br>' + item.user_name + '</a>' )

					.appendTo( ul );

				};

		        // create the action when the input field is cloned.

		        var i = 1;

		        var tagsdiv = $('#myTags');

		        $("#cloneButton").click(function() {

		                var $cloned=$('#cloneDiv').clone();

		                $cloned.appendTo(tagsdiv);

		                $("input",$cloned).each(function() {

	                        $(this).val('').attr('id', function(_, id) { return id + i });

	                        $(this).autocomplete(autocompleteSettings).data( 'autocomplete' )._renderItem = function( ul, item ) {

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

								.data( 'item.autocomplete', item )

								.append( '<a>' + item.user_code + '<br>' + item.user_name + '</a>' )

								.appendTo( ul );

							};// this is the important bit.

	                	});

		                return false;

		        });

		});

    </script>

</head>


<body>

    <div id="myTags">

        <div id="cloneDiv">

            <label for="tags">Tags: </label>

            <input class="tags" id="cloneTag"/>

            <a href="#" class="copy">Copy</a>

        </div>

    </div>

    <button id="cloneButton">Add Row</button>

    

</body>

</html>




Nice, i am glad it works after all :)

Also, nice you shared your final code, maybe someone else will need it :)

After all your help, share my code is the least I can do.

very nice its working and rescued me from unnecessary tensions :)