2012-12-13 2 views
2

Используя образец ниже, у меня есть tr, который я дублирую. Он содержит jQuery autocomplete. При первом клонировании функция автозаполнения не работает, так как присоединенный data("items") имеет значение NULL. Во второй раз, когда нажата кнопка «Добавить», работает автозаполнение. После этого нажатие кнопки «Добавить» еще раз создает неработоспособную автозаполнение.jQuery clone() копирует данные ... иногда ...?

Добавление точки останова внутри функции makeAutoComplete показывает, что items всегда равно null, за исключением тех случаев, когда при нажатии «Добавить второй раз!

Может ли кто-нибудь объяснить это странное поведение?

HTML/JS (Fiddle здесь: http://jsfiddle.net/SDvF4/12/)

<!DOCTYPE html> 

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <meta charset="utf-8" /> 
     <title>Test!</title> 
     <style type="text/css"> 
      tr.Template 
      { 
       display: none; 
      } 
     </style> 
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script> 
     <script type="text/javascript" src="http://code.jquery.com/ui/1.8.18/jquery-ui.js"></script> 
     <script type="text/javascript"> 
      $(document).ready(function() 
      { 
       var textbox = $(".AutoComplete"); 

       makeAutoComplete(textbox); 

       $("#addButton").click(function() 
       { 
        var attrRegex = /\d+/; 
        var template = $("tr.Template"); 
        var newRow = template.clone(false); 
        var newRowIndex = (template.siblings().length + 1); 

        newRow.removeClass("Template"); 
        newRow.find("*[id]").each(function() 
        { 
         var element = $(this); 

         element.attr("id", element.attr("id").replace(attrRegex, newRowIndex)); 
        }); 
        newRow.find("*[name]").each(function() 
        { 
         var element = $(this); 

         element.attr("name", element.attr("name").replace(attrRegex, newRowIndex)); 
        }); 
        newRow.insertBefore(template); 
        newRow.find(".AutoComplete").each(function() 
        { 
         makeAutoComplete($(this)); 
        }); 
       }); 
      }); 

      function makeAutoComplete(textbox) 
      { 
       var items = textbox.data("items"); 
       var test = textbox.data("test"); 

       if (items == null) 
       { 
        if (test == "JSM") 
         alert("ERROR: data.items not copied but data.test was!"); 
        else 
         alert("ERROR: data.items not copied nor was data.test!"); 
       } 

       textbox.autocomplete(
       { 
        minLength: 0, 
        source: items 
       }); 
      } 
     </script> 
    </head> 
    <body> 
     <table> 
      <tbody> 
       <tr class="Template"> 
        <td> 
         <input id="test_0" name="test_0" class="AutoComplete" type="text"/> 
         <script type="text/javascript"> 
          var testData = [{ label: "One", value: 1 }, { label: "Two", value: 2 }]; 

          $("#test_0").data("items", testData); 
          $("#test_0").data("test", "JSM"); 
         </script> 
        </td> 
       </tr> 
      </tbody> 
     </table> 
     <br/><br/> 

     <button id="addButton">Add</button>​ 
    </body> 
</html> 
+2

Вы используете неправильные идентификаторы. Они начинаются с '-1', а также становятся' 0', что является идентификатором шаблона. Используйте '+ 1' вместо' - 1' для 'newRowIndex'. Не уверен, почему '.clone()' раскрывает другое поведение из-за этого. – pimvdb

+0

Спасибо, хорошая находка. Это объясняет, почему второй клоун работал, а другие - нет - у него был тот же идентификатор, что и шаблон, но появился перед ним. –

+1

Оба атрибута данных никогда не копируются. Вы используете '.clone (false)' - из документов, которые он указывает: 'A Boolean указывает, следует ли копировать обработчики событий и данные вместе с элементами.' –

ответ

1

Были несколько вопросов, которые я должен был исправить, чтобы получить эту работу.

Сначала был указан @pimvdb - я не правильно идентифицировал элементы, поэтому вторая новая строка имела тот же идентификатор, что и строка шаблона.

Во-вторых, вы не можете просто вызвать autocomplete на виджет, который уже autocomplete - сначала вы должны уничтожить его:

textbox.autocomplete("destroy"); 
textbox.removeData("autocomplete"); 

12-я редакция работает правильно: http://jsfiddle.net/SDvF4/12/

Смежные вопросы