type template remote bootstrap twitter-bootstrap typeahead

twitter-bootstrap - template - typeahead states



Twitter bootstrap typeahead valores mĂșltiples? (5)

Este es un excelente reemplazo para las cajas de selección:

http://ivaynberg.github.io/select2/

(Si usa la versión multivalor)

Estoy usando Twitter Bootstrap con Jquery. Quiero usar la función TYPEAHEAD para un área de texto, que tengo que trabajar muy fácilmente. Pero también lo necesito para permitir una selección múltiple .

Con eso quiero decir, después de seleccionar una palabra de la función de autocompletar, me lleva de vuelta a textarea con un espacio extra después y luego, si empiezo a escribir de nuevo, me ofrece volver a hacerlo.

Aquí hay un bin JS: http://jsbin.com/ewubuk/1/edit (Nada especial adentro).

¿Existe una solución fácil para permitir la selección múltiple con typeahead? Si es así, ¿cómo?

Gracias por adelantado.


La respuesta principal ya no parece funcionar con el último typeahead , por lo que ofrezco lo siguiente.

FIDDLE

function MultiTypeahead(id, data, trigger, vertAdjustMenu) { trigger = (undefined !== trigger) ? trigger : ''''; var validChars = /^[a-zA-Z]+$/; function extractor(query) { var result = (new RegExp(''([^,; /r/n]+)$'')).exec(query); if(result && result[1]) return result[1].trim(); return ''''; } var lastUpper = false; function strMatcher(id, strs) { return function findMatches(q, sync, async) { var pos = $(id).caret(''pos''); q = (0 < pos) ? extractor(q.substring(0, pos)) : ''''; if (q.length <= trigger.length) return; if (trigger.length) { if(trigger != q.substr(0, trigger.length)) return; q = q.substr(trigger.length); } if (!q.match(validChars)) return; var firstChar = q.substr(0, 1); lastUpper = (firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase()); var cpos = $(id).caret(''position''); $(id).parent().find(''.tt-menu'').css(''left'', cpos.left + ''px''); if (vertAdjustMenu) $(id).parent().find(''.tt-menu'').css(''top'', (cpos.top + cpos.height) + ''px''); var matches = []; var matches = [], substrRegex = new RegExp(q, ''i''); $.each(strs, function(i, str) { if (str.length > q.length && substrRegex.test(str)) matches.push(str); }); if (!matches.length) return; sync(matches); }; }; var lastVal = ''''; var lastPos = 0; function beforeReplace(event, data) { lastVal = $(id).val(); lastPos = $(id).caret(''pos''); return true; } function onReplace(event, data) { if (!data || !data.length) return; if (!lastVal.length) return; var root = lastVal.substr(0, lastPos); var post = lastVal.substr(lastPos); var typed = extractor(root); if (!lastUpper && typed.length >= root.length && 0 >= post.length) return; var str = root.substr(0, root.length - typed.length); str += lastUpper ? (data.substr(0, 1).toUpperCase() + data.substr(1)) : data; var cursorPos = str.length; str += post; $(id).val(str); $(id).caret(''pos'', cursorPos); } this.typeahead = $(id).typeahead({hint: false, highlight: false}, {''limit'': 5, ''source'': strMatcher(id, data)}) .on(''typeahead:beforeselect'', beforeReplace) .on(''typeahead:beforeautocomplete'', beforeReplace) .on(''typeahead:beforecursorchange'', beforeReplace) .on(''typeahead:selected'', function(event,data){setTimeout(function(){ onReplace(event, data); }, 0);}) .on(''typeahead:autocompleted'', onReplace) .on(''typeahead:cursorchange'', onReplace) ; }

EDITAR: Al darme cuenta de que el código anterior tenía demasiadas cosas adicionales, lo reduje a un mínimo ejemplo de trabajo.

This es lo que se publicó anteriormente ..


Llego tarde a la fiesta, pero esto es lo que se me ocurrió para Bootstrap v4. También requiere d3 (ya que no estoy tan familiarizado con jQuery).

Puede ver un ejemplo que se ejecuta en http://sumneuron.gitlab.io/multitags/

Tiene algunas características útiles, está escrito claramente, y debería hacer que cualquier persona que encuentre un buen comienzo. Especialmente si alguna vez tuvo curiosidad sobre cómo se implementa el etiquetado.

El código está disponible en https://gitlab.com/SumNeuron/multitags/pipelines

La lógica es más o menos la siguiente:

if keydown in [enter, ","]: // logic of function "doneTyping" text = parse(text) // get text from textarea and grab latest value if text is valid: renderTag(text) // put the text in a tag element updateHiddenForm(text) // update the hidden form to include the tag else: notifyUserOfInvalidTag(text) // alert user else: // logic of function "stillTyping" suggest = bloodhoundSearch(text) // use twitter typeahead updateSuggestionBox(suggest) // display results from typeahead


Supongo que podría editar el complemento para permitir selecciones múltiples (simplemente no cierre el menú desplegable) y agregue los valores seleccionados separados por comas. El único problema que veo es que no sabes cuándo cerrar el menú desplegable.


Editar Ya hubo un tirón sobre eso: https://github.com/twitter/bootstrap/pull/2007

Puedes acercarte al comportamiento deseado usando un proxy para el typeahead: Demo (jsfiddle)

var $myTextarea = $(''#myTextarea''); $(''.typeahead'').typeahead({ source: source, updater: function(item) { $myTextarea.append(item, '' ''); return ''''; } });

Creo que el método de updater está diseñado para este tipo de cosas, solo devuelve lo que se mostrará.

O si realmente desea que todo esté en el mismo elemento de entrada , deberá sobrescribir más métodos para que solo coincida con el elemento actualmente escrito: Demo (jsfiddle)

function extractor(query) { var result = /([^,]+)$/.exec(query); if(result && result[1]) return result[1].trim(); return ''''; } $(''.typeahead'').typeahead({ source: source, updater: function(item) { return this.$element.val().replace(/[^,]*$/,'''')+item+'',''; }, matcher: function (item) { var tquery = extractor(this.query); if(!tquery) return false; return ~item.toLowerCase().indexOf(tquery.toLowerCase()) }, highlighter: function (item) { var query = extractor(this.query).replace(/[/-/[/]{}()*+?.,///^$|#/s]/g, ''//$&'') return item.replace(new RegExp(''('' + query + '')'', ''ig''), function ($1, match) { return ''<strong>'' + match + ''</strong>'' }) } });

Esta no es una prueba idiota, porque tienes que escribir al final, después del personaje especial.