在单个页面中使用多个bootstrap Typeahead字段?

时间:2013-01-22 06:08:52

标签: jquery twitter-bootstrap scope typeahead

我已经修改了bootstrap typeahead,以便在选择了typeahead元素时将id与元素相关联。

function addTypeahead(element)
 {
     var labels, mapped;
     var myElement = $(element);
     console.log(myElement);
    myElement.typeahead({
        source: function (query, process){
            $.post('/edit/unassigned_list', {q: query}, function(data){
                labels = [];
                mapped = {};
                //console.log(data);
                $.each(data, function(i, item){
                    var query_label = item.name;
                    mapped[query_label] = item;
                    labels.push(query_label);
                });

                process(labels);    
            }, "JSON");
        },
        updater: function (query_label){
            var item = mapped[query_label];
            myElement.attr('person_id', item.id);
            return query_label;
        }
        });

 }

这很有效。但是,当我尝试将其设置为跨多个元素时,我最终会在第一个元素上使用它(我认为因为我不小心让它泄漏到全局范围或者我做了一些可怕的错误)。我给你举个例子

我有多个标记为#project-auto- *的项目元素,我在我的文档(就绪)部分中运行以下代码:

$("[id^=project-auto-]").each(function(index, element){
        var local = $(element);
        addTypeahead(element);
    });

如果我只是遍历和控制台记录它们都显示的每个元素。但是,如果我尝试将typeahead应用于其中任何一个,则只有第一个具有typeahead(并且它正常工作),但循环在第一个应用程序之后终止。我一直在挠头,玩不同的范围(因此为什么所有的范围嵌套)无济于事。我做过一些我完全错过的超级傻事吗?

1 个答案:

答案 0 :(得分:5)

基本上,我使用匹配自动完成的模式遍历id。然后我将Bloodhound和typeahead初始化为符合模式标准的元素。我从用于搜索的刀片模板上设置的js变量中获取了search_url。 请参阅以下代码:

  $(function () {

  var $element = $('[id$=filter_autocomplete]');

  if ($element.length > 0) {
    // Loop through each element that is autocomplete
    $.each($element, function (index, element) {

       // $form      obj       name of the closest form
       // formData   string    name of the resource making the request
       // paramName  string    name of the string field
       // primaryKey string    name of the primary key
       // id         string    id of the element

      var $form = $(element).closest('form');
      var formData = $form.data('resource');
      var paramName = $(element).attr('data-field');
      var primaryKey = $(element).attr('data-primaryKey');
      var id = $(element).attr('id');

      // Sets the bhEngine as new Bloodhound object
      var bhEngine = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace(paramName),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: search_url + '?value=%QUERY&resource=' + formData +  '&input_id='          + paramName,
          wildcard: "%QUERY"
        }
      });

      // Set up typeahead for each element
      $(element).typeahead(null, {
        name: paramName,
        display: paramName,
        minLength: 0,
        highlight: true,
        hint: true,
        source: bhEngine.ttAdapter(),
        templates: {
          empty: [
            '<div class="no-items">' +
            '<p class="alert alert-danger">',
            '<strong>No Items Found</strong>',
            '</p></div>'
          ].join('\n')
        }
      }).on('typeahead:selected', function (obj, datum) {
        // Set the hidden primary key field
        $("#hidden\\|" + paramName).val(datum[primaryKey]);
      });
    });
  }
});