showing not dynamically change jquery jquery-chosen multiple-select

jquery - not - select2 selected



Permitir nuevos valores con selected.js multiple select (10)

Estoy usando el plugin chosen.js http://harvesthq.github.com/chosen/ con jQuery para permitir al usuario seleccionar múltiples opciones de una selección. Sin embargo, ahora quiero permitirles crear valores que aún no están presentes. ¿Alguna idea de cómo hacerlo?

EDITAR: algo similar a la propia barra de selección / creación de etiquetas de SO estaría cerca de lo que busco

Preferiblemente sin cambiar o editar el complemento, pero lo hará si es necesario.

El código: HTML:

<p>Select something</p> <select name="theSelect[]" multiple="multiple"> <option value="First Option">First Option</option> <option value="Second Option">Second Option</option> </select>

Javascript:

$(function(){ $(''select'').chosen(); });

Entonces, si un usuario escribe "Tercera opción", me gustaría agregar eso a la lista y hacer que se seleccione. El valor y el nombre de visualización son / serán los mismos, por lo que no es una preocupación


Actualización de la respuesta de leogdion para selección múltiple ( gist )

$(".chosen-select-with-add-new").chosen({ no_results_text: "Click Enter or Tab to add new option", width: ''100%'' }).parent().find(''.chosen-container .search-field input[type=text]'').keydown(function (evt) { // get keycode const stroke = evt.which != null ? evt.which : evt.keyCode; // If enter or tab key if (stroke === 9 || stroke === 13) { const target = $(evt.target); // get the list of current options const chosenList = target.parents(''.chosen-container'').find(''.chosen-choices li.search-choice > span'').map(function () { return $(this).text(); }).get(); // get the list of matches from the existing drop-down const matchList = target.parents(''.chosen-container'').find(''.chosen-results li'').map(function () { return $(this).text(); }).get(); // highlighted option const highlightedList = target.parents(''.chosen-container'').find(''.chosen-results li.highlighted'').map(function () { return $(this).text(); }).get(); // Get the value which the user has typed in const newString = $.trim(target.val()); // if the option does not exists, and the text doesn''t exactly match an existing option, and there is not an option highlighted in the list if ($.inArray(newString, matchList) < 0 && $.inArray(newString,chosenList) < 0 && highlightedList.length == 0) { // Create a new option and add it to the list (but don''t make it selected) const newOption = ''<option value="'' + newString + ''" selected="selected">'' + newString + ''</option>''; const choiceSelect = target.parents(''.chosen-container'').siblings(''.chosen-select-with-add-new''); choiceSelect.append(newOption); // trigger the update event choiceSelect.trigger("chosen:updated"); // tell chosen to close the list box choiceSelect.trigger("chosen:close"); return true; } // otherwise, just let the event bubble up return true; } })

Ejemplo de uso en rieles (delgado)

.tag-list label.control-label.h5 Tag list = select_tag :tag_list, options_for_select(ActsAsTaggableOn::Tag.order(''taggings_count desc'').pluck(:name), @publication.tags.map(&:name)), multiple: true, data: { placeholder: ''north, east, south, west'' }, class: ''chosen-select-with-add-new''


Aquí hay una forma simple en que lo hice:

$(".search-field").find("input").live( "keydown", function (evt) { var stroke; stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; if (stroke == 9) { // 9 = tab key $(''#tags'').append(''<option value="'' + $(this).val() + ''" selected="selected">'' + $(this).val() + ''</option>''); $(''#tags'').trigger(''chosen:updated''); } });


He actualizado el código de 3nochroot una vez más. Ahora solo tengo un selector para encontrar la entrada de selección múltiple.

$(document).ready(function() { $(".js-choicelist").chosen({ //config comes here }).parent().find(''.chosen-container .search-field input[type=text]'').keydown( function (evt) { var stroke, _ref, target, list; // get keycode stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; // If enter or tab key if (stroke === 9 || stroke === 13) { target = $(evt.target); // get the list of current options chosenList = target.parents(''.chosen-container'').find(''.chosen-choices li.search-choice > span'').map(function () { return $(this).text(); }).get(); // get the list of matches from the existing drop-down matchList = target.parents(''.chosen-container'').find(''.chosen-results li'').map(function () { return $(this).text(); }).get(); // highlighted option highlightedList = target.parents(''.chosen-container'').find(''.chosen-results li.highlighted'').map(function () { return $(this).text(); }).get(); // Get the value which the user has typed in var newString = $.trim(target.val()); // if the option does not exists, and the text doesn''t exactly match an existing option, and there is not an option highlighted in the list if ($.inArray(newString,matchList) < 0 && $.inArray(newString,chosenList) < 0 && highlightedList.length == 0) { // Create a new option and add it to the list (but don''t make it selected) var newOption = ''<option value="'' + newString + ''">'' + newString + ''</option>''; var choiceSelect = target.parents(''.select-multiple'').find(''select''); choiceSelect.prepend(newOption); // trigger the update event choiceSelect.trigger("chosen:updated"); // tell chosen to close the list box choiceSelect.trigger("chosen:close"); return true; } // otherwise, just let the event bubble up return true; } } )

})


Me topé con esto buscando las mismas ideas. Parece que es una solicitud de características bastante popular, y un par de bifurcaciones lo han implementado. Parece que se fusionará en la rama maestra lo suficientemente pronto.

+1 para este tirón en particular que funcionó de forma encantadora: https://github.com/harvesthq/chosen/pull/166

Puede ver el tenedor de Koenpunt aquí: https://github.com/koenpunt/chosen


Probé varias soluciones dadas aquí y en otros lugares, sin embargo, ninguna funcionó en selected.js 1.8.5 (jQuery: 3.3.1) y terminé con lo siguiente, ya que no quería usar un tenedor que podría no estar siempre arriba. hasta la fecha en la rama maestra:

Para el caso de que no quiera ningún .chosen-select para permitir nuevos valores, agregué una nueva clase .chosen-newValuesAllowed . Establecí un controlador de eventos en esta clase donde CTRL + I agrega el nuevo valor si aún no está presente. El enfoque en el campo de entrada no se pierde después. En mi ejemplo, verifico el innerHTML de ya que @value realmente contiene los identificadores de la base de datos y, por lo tanto, el nuevo valor, que es una cadena en mi ejemplo que sería procesado por el servidor más adelante, nunca se pudo encontrar en @value. Si desea comprobar @value, consulte el comentario dentro del fragmento. El código maneja selecciones individuales y múltiples.

$(document).on("keydown", ".chosen-container.chosen-newValuesAllowed input", function(e) { if (e.ctrlKey === true && e.keyCode === 73) { // CTRL + I e.preventDefault(); var newValue = $(this).val(); if (newValue) { try { // only add if there is no option having the content/text of "input" yet! // instead of filter() for the content of <option> you can check on its @value by: find("option[val=''...'']") var $selectElement = $(e.target).closest("div.chosen-container").prev(); // the previous sibling should be the <select>. If not, grab it some other way, e.g. via @id if (!$selectElement.find("option").filter(function () { return $(this).html() === newValue; }).length) { if (!$selectElement.attr("multiple")) { // unselect for single-select $selectElement.val(''''); } $selectElement.append(''<option val="'' + newValue + ''" selected>'' + newValue + ''</option>''); $selectElement.trigger(''chosen:updated''); } } catch(error) { // pass } e.target.focus(); } return false; } });

Otra solución sería llamar a la función activable elegida: no_results si solo se deben agregar nuevos valores si no hay un resultado explícito:

$(".chosen-select.chosen-newValuesAllowed").on("chosen:no_results", function(e, data){ var newValue = data.chosen.get_search_text(); ... });


Sé que esta no es la respuesta, pero, una solución alternativa.

Estaba buscando la parte agregada sobre la marcha y descubrí que http://ivaynberg.github.com/select2/#tags proporciona lo mismo que otros materiales seleccionados como "Etiquetado".


Según la documentación puedes intentar hacer algo como esto:

$(''select'').append(''<option>test</option>''); $(''select'').trigger(''liszt:updated'');

Como Tony declaró en los comentarios a continuación:

"A partir de la versión 1.0, el activador ahora" elegido: actualizado ". Consulte harvesthq.github.io/chosen/#change-update-events "


Simplemente puede adjuntar un evento al cuadro de texto de entrada para escuchar un código de carácter particular. Después de eso, agregue la opción y active la actualización en el menú desplegable.

var dropDown = $(''select.chosen''); dropDown.parent().find(''.chzn-container .chzn-search input[type=text]'').keydown( function (evt) { var stroke, _ref, target, list; // get keycode stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; target = $(evt.target); // get the list of current options list = target.parents(''.chzn-container'').find(''.chzn-choices li.search-choice > span'').map(function () { return $(this).text(); }).get(); if (stroke === 9 || stroke === 13) { var value = $.trim(target.val()); // if the option does not exists if ($.inArray(value,list) < 0) { var option = $(''<option>''); option.text(value).val(value).appendTo(dropDown); option.attr(''selected'',''selected''); // add the option and set as selected } // trigger the update event dropDown.trigger("liszt:updated"); return true; } });


Solo estaba tratando de resolver el mismo problema. Terminé modificando un poco el código fuente. Aquí está la nueva función keyup_checker. Eche un vistazo al caso 13:

AbstractChosen.prototype.keyup_checker = function(evt) { var stroke, _ref; stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; this.search_field_scale(); switch (stroke) { case 8: if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) { return this.keydown_backstroke(); } else if (!this.pending_backstroke) { this.result_clear_highlight(); return this.results_search(); } break; case 13: evt.preventDefault(); if (this.results_showing) { if (!this.is_multiple || this.result_highlight) { return this.result_select(evt); } $(this.form_field).append(''<option>'' + $(evt.target).val() + ''</option>''); $(this.form_field).trigger(''liszt:updated''); this.result_highlight = this.search_results.find(''li.active-result'').last(); return this.result_select(evt); } break; case 27: if (this.results_showing) this.results_hide(); return true; case 9: case 38: case 40: case 16: case 91: case 17: break; default: return this.results_search(); } };


Una actualización de la respuesta de leogdion que funciona con versiones posteriores de elegidos:

var dropDown = $(''#select_chosen''); // Make the chosen drop-down dynamic. If a given option is not in the list, the user can still add it dropDown.parent().find(''.chosen-container .search-field input[type=text]'').keydown( function (evt) { var stroke, _ref, target, list; // get keycode stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; // If enter or tab key if (stroke === 9 || stroke === 13) { target = $(evt.target); // get the list of current options chosenList = target.parents(''.chosen-container'').find(''.chosen-choices li.search-choice > span'').map(function () { return $(this).text(); }).get(); // get the list of matches from the existing drop-down matchList = target.parents(''.chosen-container'').find(''.chosen-results li'').map(function () { return $(this).text(); }).get(); // highlighted option highlightedList = target.parents(''.chosen-container'').find(''.chosen-results li.highlighted'').map(function () { return $(this).text(); }).get(); // Get the value which the user has typed in var newString = $.trim(target.val()); // if the option does not exists, and the text doesn''t exactly match an existing option, and there is not an option highlighted in the list if ($.inArray(newString,matchList) < 0 && $.inArray(newString,chosenList) < 0 && highlightedList.length == 0) { // Create a new option and add it to the list (but don''t make it selected) var newOption = ''<option value="'' + newString + ''">'' + newString + ''</option>''; $("#select").prepend(newOption); // trigger the update event $("#select").trigger("chosen:updated"); // tell chosen to close the list box $("#select").trigger("chosen:close"); return true; } // otherwise, just let the event bubble up return true; } } )