Twitter Bootstrap typeahead: get context / calling element with `this`
Solution 1
You are inside another function so you need to save a reference to the element in the outer closure, this can then be passed into the event handler of the inner closure. You can do that using an $.each()
call to loop through the selector saving a reference to the element (this) each time - e.g.
$('#client-search, #endClient-search, #other-search').each(function() {
var $this = $(this);
$this.typeahead({
...
,updater: function (item) {
var target = $this.attr('id').split('-')[0] + '-id';
$('#'+target).val(mapped[item]);
return item;
}
...
});
Solution 2
The accepted answer is a good one, but just wanted to share an alternative that doesn't actually require the outer closure. I'm using bootstrap v2.3.1 and the input is available to you from this.$element
.
Eg:
$(':input[data-typeahead-url]').typeahead({
source: function (query, process) {
$.get(this.$element.attr('data-typeahead-url'), { query: query }, function (data) {
labels = [];
mapped = {};
$.each(data, function(i,item) {
mapped[item.label] = item.value;
labels.push(item.label);
});
process(labels);
});
}
,updater: function (item) {
$('#'+this.$element.attr('data-typeahead-target')).val(mapped[item]);
return item;
}
,items: 10
,minLength: 2
});
Peter Di Cecco
Among other things, I am a... Software and web developer Musician Karaoke enthusiast Camping aficionado Developer of table top games A general, over-all geek Some programming languages and tools I've used: JavaScript, Node.js, Vue.js, NestJS, Knex.js, jQuery, HTML5, CSS, Twitter Bootstrap, jQuery UI SQL, PostgeSQL, Microsoft SQL Server, Python, Bash, git Java, J2EE, Java EE, Hibernate, Struts, Tomcat, Play! Framework
Updated on June 05, 2022Comments
-
Peter Di Cecco almost 2 years
I am using the Typeahead component of Twitter Bootstrap 2.1.1, and jQuery 1.8.1
I am trying to access the text box element from within typeahead's
updater
function. Here is my current code, which works great:$('#client-search').typeahead({ source: function (query, process) { $.get(url, { query: query }, function (data) { labels = []; mapped = {}; $.each(data, function(i,item) { mapped[item.label] = item.value; labels.push(item.label); }); process(labels); }); } ,updater: function (item) { $('#client-id').val(mapped[item]); return item; } ,items: 10 ,minLength: 2 });
I have many typeahead search boxes on the same page. Each search box has an id
#xxx-search
and a corresponding hidden input with id#xxx-id
. I'd like to re-use the same code for everything by doing something like this:$('#client-search, #endClient-search, #other-search').typeahead({ ... ,updater: function (item) { var target = $(this).attr('id').split('-')[0] + '-id'; $('#'+target).val(mapped[item]); return item; } ...
I thought that
this
would refer to the text box element in use, but apparently not, because I get an undefined error in firebug:$(this).attr("id") is undefined
When I use
this
instead of$(this)
, I get:this.attr is not a function
Can anyone help make this work?
UPDATE: THE ANSWER, AND MORE!
Thanks to benedict_w's answer below, not only does this work perfectly now, but I have also made this much better in terms of re-usability.
Here is what my
<input>
s look like:<input type="text" autocomplete="off" id="client-search" data-typeahead-url="/path/to/json" data-typeahead-target="client-id"> <input type="hidden" id="client-id" name="client-id">
Notice how the search box references the hidden id. Here's the new js:
$(':input[data-typeahead-url]').each(function(){ var $this = $(this); $this.typeahead({ source: function (query, process) { $.get($this.attr('data-typeahead-url'), { query: query }, function (data) { labels = []; mapped = {}; $.each(data, function(i,item) { mapped[item.label] = item.value; labels.push(item.label); }); process(labels); }); } ,updater: function (item) { $('#'+$this.attr('data-typeahead-target')).val(mapped[item]); return item; } ,items: 10 ,minLength: 2 }); });
-
benedict_w over 11 yearsYou will find some more discussion about JavaScript Closures here: stackoverflow.com/questions/111102/…
-
nizam.sp almost 11 yearsI was struggling with this problem for 2 hours. You saved my day!