views:

859

answers:

3

I am using Jörn Zaefferer's jquery autocomplete plugin, and I can't seem to figure out how to make it work when I clone an autocomplete field. It almost works, in that the cloned autocomplete field displays the choices when the I type in text, but I cannot select items. At first I thought it was a browser-compatibility issue, but it happens in both FF3 and Safari, so I'm guessing there's a gotcha I've missed.

Here is a working example of what I'm doing:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Autocomplete Clone Demo</title>
<style>
body {
margin: 40px;
}
.hide_element {
display: none;
}
</style>
<link rel="stylesheet" href="http://dev.jquery.com/view/trunk/plugins/autocomplete/jquery.autocomplete.css" type="text/css" />
<script src="http://code.jquery.com/jquery-latest.js"&gt;&lt;/script&gt;
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/autocomplete/jquery.autocomplete.js"&gt;&lt;/script&gt;
<script type="text/javascript">
    function setAutocomplete()
    {
        var users = [
          { name: "Fred", id: "1" },
          { name: "Barney", id: "2" },
          { name: "Wilma", id: "3" }
        ];

        $(".user_selector").autocomplete(users, 
            {
                mustMatch: true,
                matchContains: true,
                minChars: 2,
                formatResult: function(row) { return row.name; },
                formatItem: function(row, i, max) { return row.name; }
            }
        );
    }

    var current= 0;

    var addParticipantFields = function() 
    {
        current++;
        $newParticipant = $("#template").clone(true);
        $newParticipant.removeAttr("id");
        $newParticipant.removeClass("hide_element");
        $prefix = "extra" + current;
        $newParticipant.children("div").children(":input").each(function(i) {
            var $currentElem= $(this);
            $currentElem.attr("name",$prefix+$currentElem.attr("name"));
        });
        $newParticipant.appendTo("#participantsField");
        setAutocomplete();
    }

    $(document).ready(function() {
        setAutocomplete();
        $("#addParticipant").live("click", addParticipantFields);

    });
</script>

</head>
<body>
<h1>Test Autocomplete Cloning</h1>
<form id="demo" method="post" action="">
<fieldset id="participantsField">
<label>Participants</label>
<div class="participant">
    <input class="user_selector" name="user" size="30"/>
</div>
</fieldset>

<!-- This is the template for adding extra participants -->
<div class="participant hide_element" id="template">
    <input class="user_selector" name="_user" size="30"/>
</div>

<p><input type="button" id="addParticipant" value="Add Another Participant"></p>
<p><input class="button" type="submit" value="Submit"/></p>
</form>
</body>
</html>
+1  A: 

Make

$newParticipant = $("#template").clone(true);

like so

$newParticipant = $("#template").clone();

Your example works for me in FF when you don't clone events on #template.

james
I'm not sure why, but this does indeed work. I encountered the same problematic autocomplete behavior described earlier, but in the non-cloned input boxes after doing this fix -- but I can't seem to reproduce it now so I guess the events get messed up from time to time.
Rob
had same problem, but i had to clone() with event handlers, workaround for that was to unautocomplete() and then autocomplete() on element again, much easier than reconecting all event handlers for all elements again after clone()ing
CountZero
+1  A: 

first of all:

$newParticipant.children("div").children(":input").length == 0

so there is no children returned by this line. Use

$newParticipant.children()

instead. It returns 1 chield instead. But steel don't work for me. Have to think more.

Dmytro Leonenko
Good catch - thanks for pointing that out.
Rob
A: 

I want to clone event. Help me.