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?
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]);
});
});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With