Twitter Bootstrap typeahead: получить контекст/вызывающий элемент с `this`
Я использую Typeahead компонент Twitter Bootstrap 2.1.1 и jQuery 1.8.1
Я пытаюсь получить доступ к элементу текстового поля из функции typeahead updater
. Вот мой текущий код, который отлично работает:
$('#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
});
У меня есть много поисковых полей typeahead на той же странице. В каждом окне поиска есть id #xxx-search
и соответствующий скрытый ввод с id #xxx-id
. Я хотел бы повторно использовать один и тот же код для всего, выполнив что-то вроде этого:
$('#client-search, #endClient-search, #other-search').typeahead({
...
,updater: function (item) {
var target = $(this).attr('id').split('-')[0] + '-id';
$('#'+target).val(mapped[item]);
return item;
}
...
Я думал, что this
будет ссылаться на используемый элемент текстового поля, но, видимо, нет, потому что я получаю ошибку undefined в firebug:
$(this).attr("id") is undefined
Когда я использую this
вместо $(this)
, я получаю:
this.attr is not a function
Может кто-нибудь помочь сделать эту работу?
ОБНОВЛЕНИЕ: ОТВЕТ И БОЛЬШЕ!
Благодаря ответу benedict_w ниже, это не только отлично работает сейчас, но я также сделал это намного лучше с точки зрения повторного использования.
Вот как выглядит мой <input>
:
<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">
Обратите внимание, как окно поиска ссылается на скрытый идентификатор. Здесь новый 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
});
});
Ответы
Ответ 1
Вы находитесь внутри другой функции, поэтому вам нужно сохранить ссылку на элемент во внешнем закрытии, тогда ее можно передать в обработчик события внутреннего закрытия. Вы можете сделать это с помощью вызова $.each()
для циклического переключения селектора, сохраняющего ссылку на элемент (это) каждый раз - например,
$('#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;
}
...
});
Ответ 2
Принятый ответ является хорошим, но просто хотел поделиться альтернативой, которая фактически не требует внешнего закрытия. Я использую bootstrap v2.3.1, и вход доступен вам от this.$element
.
Например:
$(':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
});