Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using multiple bootstrap Typeahead fields in a single page?

I've modified the bootstrap typeahead to associate an id with an element when a typeahead element is selected.

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;
        }
        });

 }

This is working great. However, when I try to set this up to work across multiple elements I end up having it conk out on the first element (I think because I'm accidentally letting it leak into global scope or I've done something hideously wrong). I'll give you an example

I have multiple project elements labeled as #project-auto-* and I run this following code in my document(ready) section:

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

If I just iterate through and console log each element they all display. If I however try to apply a typeahead to any of these only the first has the typeahead (and it works properly) but the loop terminates after the first application. I've been scratching my head and playing around with different scopes (thus why all the scope nesting) to no avail. Have I done something super silly that I've totally missed?

like image 749
Schroedinger Avatar asked Jan 22 '13 06:01

Schroedinger


1 Answers

Essentially I loop through the ids with a pattern matching autocomplete. then I initialized Bloodhound and typeahead to element that matched the criteria of the pattern. I got the search_url from a js variable that is set up on the blade template for search. See the code below:

  $(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]);
      });
    });
  }
});
like image 120
jdubu423 Avatar answered Oct 09 '22 01:10

jdubu423