Я действительно решил проблему, очень похожую на эту, и закончил тем, что написал плагин jQuery ( jQuery.otherDropdown ), чтобы собрать «другой» ответ для выпадающего списка. Это на GitHub и npm . Я сломаю свой подход, чтобы вы могли реализовать его по-своему.
На мой взгляд, эта идея - идеальный вариант использования jQuery.
Основные компоненты
Слушайте, когда ваши «другие» опции отключены
Добавить привязку события .change()
к выбранному входу.
$('select').change( function() {
if(this.value === 'other') {
// Your logic here to for when/how to prompt for user input
}
});
Прослушивание ввода пользователя
Если вы выбираете ввод текста вместо приглашения (что может быть удобнее для пользователя), прослушайте событие размытия
// listen to a text area
$('input').blur( function() {
if(this.value !== '') {
// Logic to add the new option to the select
}
});
// or bring up a prompt dialog
var value=prompt("Please indicate 'other' value:");
if(this.value !== '') {
// Logic to add the new option to the select
}
Добавить новую опцию
Независимо от того, как вы решите запросить у пользователя значение, добавить его так же просто, как создать элемент с помощью jQuery и добавить его. Наконец, вы, вероятно, захотите сфокусировать значение, что можно сделать с помощью .val()
var $option = $('<option value="' + value + '">' + value + '</option>');
$('select').append($option);
$('select').val(value);
Пример
Все эти идеи обернуты в этот плагин и могут послужить хорошим примером, с которым вы можете поиграть и использовать повторно, чтобы работать так, как вам нужно. Вы можете видеть это работает здесь
/**
* @name jquery.otherdropdown
* @description A small jQuery plugin to support a text area when selecting an 'Other' option in a dropdown
* @version 1.0.2
* @author Jonathan Stassen <jstassen.com>
* @see https://github.com/TheBox193/jquery.otherdropdown
*/
$.fn.otherDropdown = function(options) {
var $this = this;
// Allow a different name/value to trigger, default to 'other'
var opts = $.extend({}, {value: 'other'}, options);
opts.name_lower = opts.value.toLowerCase();
opts.name_upper = opts.value.charAt(0).toUpperCase() + opts.value.slice(1);
opts.placeholder = opts.placeholder || opts.name_upper;
// Bind to all change events
$this.change( function(ev){
// Swap in the text area if our 'other' option was chosen
if (this.value === opts.name_lower || this.value === opts.name_upper) {
$this.hide().after( $textInput );
$textInput.focus();
}
});
// Prepare our text input
var $textInput = $('<input type="text" class="otherdropdown" placeholder="' + opts.placeholder + '" />');
// Allow custom classes on the text input
if (opts.classes) {
$textInput.addClass(opts.classes);
}
// Bind to blur to swap back to select dropdown
$textInput.blur( function(ev) {
var value = this.value;
this.value = '';
this.remove();
$this.show();
if (value === '' || value === opts.name_lower || value === opts.name_upper) {
return;
}
// If something was typed, create a new option with that value
var $searchedOption = $this.children('[value="' + value + '"]');
// If value doesn't exist, added it.
if ( $searchedOption.length < 1 ) {
var $option = $('<option value="' + value + '">' + value + '</option>');
$this.append($option);
}
// Focus the value
$this.val( value );
});
};