2012-09-13 4 views
17

używam komponentu Typeahead Twitter Bootstrap 2.1.1 i jQuery 1.8.1Twitter Bootstrap wpisywanie znaków z wyprzedzeniem: uzyskać kontekst/element z `nazywając this`

Próbuję uzyskać dostęp do elementu pola tekstowego od wewnątrz wpisywanie znaków z wyprzedzeniem-tych Funkcja updater. Oto mój aktualny kod, który działa świetnie:

$('#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 
}); 

Mam wiele pól wyszukiwania z nagłówkiem na tej samej stronie. Każde pole wyszukiwania ma identyfikator #xxx-search i odpowiednie ukryte wejście z identyfikatorem #xxx-id. Chciałbym, aby ponownie użyć tego samego kodu na wszystko robiąc coś takiego:

$('#client-search, #endClient-search, #other-search').typeahead({ 

    ... 

    ,updater: function (item) { 
     var target = $(this).attr('id').split('-')[0] + '-id'; 
     $('#'+target).val(mapped[item]); 
     return item; 
    } 

    ... 

Myślałem, że this będzie odnosić się do elementu pola tekstowego w użyciu, ale najwyraźniej nie, bo się niezdefiniowany błąd w Firebug

$(this).attr("id") is undefined 

kiedy używam this zamiast $(this), otrzymuję:

this.attr is not a function 

Czy ktoś może pomóc to wo rk?


AKTUALIZACJA: ODPOWIEDŹ I WIĘCEJ!

Dzięki poniższej odpowiedzi od benedict_w, nie tylko działa to idealnie teraz, ale mam również o wiele lepsze pod względem ponownego użycia.

Oto co moi <input> s wyglądać następująco:

<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"> 

zauważyć jak pole wyszukiwania odwołuje się do ukrytego identyfikatora. Oto nowe 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 
    }); 
}); 
+0

Otrzymuję wyświetlanie „nieokreślonych” Opcje w rozwijanym podczas korzystania z tego rozwiązania. – Xeoncross

+0

@Xeoncross: zarówno bootstrap, jak i jQuery zostały zaktualizowane kilka razy od czasu opublikowania tego pytania. Może nie być już istotne dla używanych wersji. –

Odpowiedz

24

Jesteś wewnątrz innej funkcji więc trzeba zapisać referencję do elementu zewnętrznego zamknięcia, może być następnie przekazany do obsługi zdarzeń wewnętrznego zamknięcia. Możesz to zrobić, używając wywołania $.each(), aby przechodzić przez selektor, zapisując odwołanie do elementu (tego) za każdym razem - np.

$('#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; 
     } 
     ... 
    }); 
+0

Znajdziesz więcej dyskusji na temat zamknięć JavaScript tutaj: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work –

+0

Dzięki temu, że działał jak urok! –

+0

Walczyłem z tym problemem przez 2 godziny. Uratowałeś mój dzień! –

4

Przyjęta odpowiedź jest dobra, ale po prostu chciała się podzielić alternatywą, która w rzeczywistości nie wymaga zewnętrznego zamknięcia. Używam bootstrap v2.3.1, a dane wejściowe są dostępne od this.$element.

Np

$(':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 
}); 
Powiązane problemy