template react bootstrap javascript jquery twitter-bootstrap closures typeahead

javascript - react - typeahead scrollable



Twitter Bootstrap typeahead: obtiene el elemento context/calling con `this` (2)

Estoy usando el componente Typeahead de Twitter Bootstrap 2.1.1 y jQuery 1.8.1

Estoy intentando acceder al elemento del cuadro de texto desde dentro de la función de updater de typeahead. Aquí está mi código actual, que funciona muy bien:

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

Tengo muchos cuadros de búsqueda de typeahead en la misma página. Cada cuadro de búsqueda tiene un id #xxx-search y una entrada oculta correspondiente con id #xxx-id . Me gustaría reutilizar el mismo código para todo haciendo algo como esto:

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

Pensé que this se referiría al elemento de cuadro de texto en uso, pero aparentemente no, porque recibo un error indefinido en firebug:

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

Cuando uso this lugar de $(this) , obtengo:

this.attr is not a function

¿Alguien puede ayudar a hacer que esto funcione?

ACTUALIZACIÓN: LA RESPUESTA, Y MÁS!

Gracias a la respuesta de benedict_w a continuación, no solo funciona perfectamente ahora, sino que también he mejorado mucho en términos de reutilización.

Aquí es cómo se ve mi <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">

Observe cómo el cuadro de búsqueda hace referencia a la identificación oculta. Aquí está el nuevo 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 }); });


Está dentro de otra función, por lo que necesita guardar una referencia al elemento en el cierre exterior, esto puede luego pasar al controlador de eventos del cierre interior. Puede hacerlo usando una $.each() para recorrer el selector guardando una referencia al elemento (esto) cada vez, por ejemplo

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


La respuesta aceptada es buena, pero solo quería compartir una alternativa que en realidad no requiere el cierre exterior. Estoy usando bootstrap v2.3.1 y la entrada está disponible para usted desde this.$element .

P.ej:

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