Подтвердить что ты не робот

Как создать редактируемый выпадающий список в HTML?

Я хотел бы создать текстовое поле с выпадающим списком, который позволяет пользователю выбирать некоторые предопределенные значения. Пользователь также должен иметь возможность ввести новое значение или выбрать предопределенный из раскрывающегося списка. Я знаю, что для этого я могу использовать два виджета, но в моем приложении это было бы более эргономичным, если бы оно было унифицировано в одном виджете.

Есть ли стандартный виджет или мне нужно использовать сторонний javascript?

Как о переносимости браузера?

4b9b3361

Ответ 1

Лучший способ сделать это, вероятно, использовать стороннюю библиотеку.

Есть реализация того, что вы ищете, в jQuery UI jQueryUI и в dojo dojo. jQuery более популярен, но dojo позволяет декларативно определять виджеты в HTML, что больше похоже на то, что вы ищете.

Какой из них вы используете, будет зависеть от вашего стиля, но оба они разработаны для кросс-браузерной работы, и оба будут обновляться чаще, чем копировать и вставлять код.

Ответ 2

Вы можете выполнить это, используя тег <datalist> в HTML5.

<input type="text" name="product" list="productName"/>
<datalist id="productName">
    <option value="Pen">Pen</option>
    <option value="Pencil">Pencil</option>
    <option value="Paper">Paper</option>
</datalist>

Если вы дважды щелкните текст ввода в браузере, появится список с указанным параметром.

Ответ 3

Это может быть достигнуто с помощью простых HTML, CSS и JQuery. Я создал образец страницы:

$(document).ready(function(){
   
    $(".editableBox").change(function(){         
        $(".timeTextBox").val($(".editableBox option:selected").html());
    });
});
.editableBox {
    width: 75px;
    height: 30px;
}

.timeTextBox {
    width: 54px;
    margin-left: -78px;
    height: 25px;
    border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
    <select class="editableBox">        
        <option value="1">01:00</option>
        <option value="2">02:00</option>
        <option value="3">03:00</option>
        <option value="4">04:00</option>
        <option value="5">05:00</option>
        <option value="6">06:00</option>
        <option value="7">07:00</option>
        <option value="8">08:00</option>
        <option value="9">09:00</option>
        <option value="10">10:00</option>
        <option value="11">11:00</option>
        <option value="12">12:00</option>
        <option value="13">13:00</option>
        <option value="14">14:00</option>
        <option value="15">15:00</option>
        <option value="16">16:00</option>
        <option value="17">17:00</option>
        <option value="18">18:00</option>
        <option value="19">19:00</option>
        <option value="20">20:00</option>
        <option value="21">21:00</option>
        <option value="22">22:00</option>
        <option value="23">23:00</option>
        <option value="24">24:00</option>
    </select>
    <input class="timeTextBox" name="timebox" maxlength="5"/>
</div>

Ответ 4

Тег <select> позволяет использовать только предопределенные записи. Типичным решением вашей проблемы является наличие одной записи с надписью "Другое" и отключенного поля редактирования (<input type="text"). Добавьте JavaScript, чтобы включить поле редактирования, только если выбрано "Другое".

Возможно, каким-то образом можно создать раскрывающийся список, который позволяет прямое редактирование, но IMO, которое не стоит усилий. Если бы это было так, Amazon, Google или Microsoft сделали бы это;-) Просто выполните работу с наименее сложным решением. Это быстрее (вашему боссу это может понравиться) и обычно легче поддерживать (вам это может понравиться).

Ответ 5

Очень простая реализация (только базовые функции) на основе CSS и одна строка JS-кода

<div class="dropdown">
    <input type="text" />
    <select  onchange="this.previousElementSibling.value=this.value; this.previousElementSibling.focus()">
        <option>This is option 1</option>
        <option>Option 2</option>
    </select>
</div>

Обратите внимание: использует предыдущий элемент, который не поддерживается в старых браузерах (ниже IE9)

.dropdown {
    position: relative;
    width: 200px;
}
.dropdown select
{
    width: 100%;
}
.dropdown > * {
    box-sizing: border-box;
    height: 1.5em;
}
.dropdown select {
}
.dropdown input {
    position: absolute;
    width: calc(100% - 20px);
}

Здесь он находится на JSFiddle

Ответ 7

Я не уверен, что есть способ сделать это автоматически без javascript.

Что вам нужно - это то, что работает на стороне браузера, чтобы отправить вашу форму на сервер, когда пользователь делает выбор - следовательно, javascript.

Кроме того, убедитесь, что у вас есть альтернативное средство (т.е. кнопка отправки) для тех, у кого отключен JavaScript.

Хороший пример: Combo-Box Viewer

У меня была еще более сложная комбо-ящик вчера, с этим dhtmlxCombo, используя ajax для получения соответствующих значений среди большого количества данных.

Ответ 8

Комбобокс - это, к сожалению, что-то, что не учитывалось в спецификациях HTML.

Единственный способ справиться с этим, скорее всего, состоит в том, чтобы сворачивать свой собственный или использовать предварительно построенный. Этот выглядит довольно просто. Я использую этот для приложения с открытым исходным кодом, хотя, к сожалению, вам приходится платить за коммерческое использование.

Ответ 9

Маленький CSS, и все готово fiddle

<div style="position: absolute;top: 32px; left: 430px;" id="outerFilterDiv">
<input name="filterTextField" type="text" id="filterTextField" tabindex="2"  style="width: 140px;
    position: absolute; top: 1px; left: 1px; z-index: 2;border:none;" />
        <div style="position: absolute;" id="filterDropdownDiv">
<select name="filterDropDown" id="filterDropDown" tabindex="1000"
    onchange="DropDownTextToBox(this,'filterTextField');" style="position: absolute;
    top: 0px; left: 0px; z-index: 1; width: 165px;">
    <option value="-1" selected="selected" disabled="disabled">-- Select Column Name --</option>
</select>

      

Ответ 10

В HTML нет встроенного редактируемого выпадающего списка или комбинированного списка, но я реализовал решение в основном с помощью CSS в статье.

Вы можете увидеть полную демонстрацию здесь, но вкратце напишите HTML так:

<span class="combobox withtextlist">
  <input value="Fruit">
  <span tabindex="-1" class="downarrow"></span>
  <select size="10" class="sticky">
    <option>Apple</option>
    <option>Banana</option>
    <option>Cherry</option>
    <option>Dewberry</option>
  </select>
</span>

И используйте CSS для стилизации (это предназначено как для комбинированных списков, которые имеют кнопку со стрелкой вниз, так и для раскрывающихся меню, которые открываются при нажатии и могут иметь разные стили):

/* ------------------------------------------ */
/* ----- combobox / dropdown list styling     */
/* ------------------------------------------ */
.combobox {
  /* Border slightly darker than Chrome <select>, slightly lighter than FireFox */
  border: 1px solid #999;
  padding-right: 1.25em; /* leave room for ▾ */
}
.dropdown, .combobox { 
  /* "relative" and "inline-block" (or just "block") are needed
     here so that "absolute" works correctly in children */
  position: relative;
  display: inline-block;
}
.combobox > .downarrow, .dropdown > .downarrow {
  /* ▾ Outside normal flow, relative to container */
  display: inline-block;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 1.25em;

  cursor: default;
  nav-index: -1; /* nonfunctional in most browsers */

  border-width: 0px;          /* disable by default */
  border-style: inherit; /* copy parent border */
  border-color: inherit; /* copy parent border */
}
/* Add a divider before the ▾ down arrow in non-dropdown comboboxes */
.combobox:not(.dropdown) > .downarrow {
  border-left-width: 1px;
}
/* Auto-down-arrow if one is not provided */
.downarrow:empty::before {
  content: '▾';
}
.downarrow::before, .downarrow > *:only-child {
  text-align: center;

  /* vertical centering trick */
  position: relative;
  top: 50%;
  display: block; /* transform requires block/inline-block */
  transform: translateY(-50%);
}
.combobox > input {
  border: 0
}
.dropdown > *:last-child,
.combobox > *:last-child {
  /* Using 'display:block' here has two desirable effects:
     (1) Accessibility: it lets input widgets in the dropdown to
         be selected with the tab key when the dropdown is closed. 
     (2) It lets the opacity transition work.
     But it also makes the contents visible, which is undesirable 
     before the list drops down. To compensate, use 'opacity: 0'
     and disable mouse pointer events. Another side effect is that
     the user can select and copy the contents of the hidden list,
     but don't worry, the selected content is invisible. */
  display: block;
  opacity: 0;
  pointer-events: none;

  transition: 0.4s; /* fade out */
  position: absolute;
  left: 0;
  top: 100%;
  border: 1px solid #888;
  background-color: #fff;
  box-shadow: 1px 2px 4px 1px #666;
  box-shadow: 1px 2px 4px 1px #4448;
  z-index: 9999;
  min-width: 100%;
  box-sizing: border-box;
}
/* List of situations in which to show the dropdown list.
   - Focus dropdown or non-last child of it => show last-child
   - Focus .downarrow of combobox => show last-child
   - Stay open for focus in last child, unless .less-sticky
   - .sticky last child stays open on hover
   - .less-sticky stays open on hover, ignores focus in last-child */
.dropdown:focus > *:last-child,
.dropdown > *:focus ~ *:last-child,
.combobox > .downarrow:focus ~ *:last-child,
.combobox > .sticky:last-child:hover,
.dropdown > .sticky:last-child:hover,
.combobox > .less-sticky:last-child:hover,
.dropdown > .less-sticky:last-child:hover,
.combobox > *:last-child:focus:not(.less-sticky),
.dropdown > *:last-child:focus:not(.less-sticky) {
  display: block;
  opacity: 1;
  transition: 0.15s;
  pointer-events: auto;
}
/* focus-within not supported by Edge/IE. Unsupported selectors cause 
   the entire block to be ignored, so we must repeat all styles for 
   focus-within separately. */
.combobox > *:last-child:focus-within:not(.less-sticky),
.dropdown > *:last-child:focus-within:not(.less-sticky) {
  display: block;
  opacity: 1;
  transition: 0.15s;
  pointer-events: auto;
}
/* detect Edge/IE and behave if though less-sticky is on for all
   dropdowns (otherwise links won't be clickable) */
@supports (-ms-ime-align:auto) {
  .dropdown > *:last-child:hover {
    display: block;
    opacity: 1;
    pointer-events: auto;
  }
}
/* detect IE and do the same thing. */
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
  .dropdown > *:last-child:hover {
    display: block;
    opacity: 1;
    pointer-events: auto;
  }
}
.dropdown:not(.sticky) > *:not(:last-child):focus,
.downarrow:focus, .dropdown:focus {
  pointer-events: none; /* Causes second click to close */
}
.downarrow:focus {
  outline: 2px solid #8BF; /* Edge/IE can't do outline transparency */
  outline: 2px solid #48F8;
}

/* ---------------------------------------------- */
/* Optional extra styling for combobox / dropdown */
/* ---------------------------------------------- */
*, *:before, *:after {
  /* See https://css-tricks.com/international-box-sizing-awareness-day/ */
  box-sizing: border-box; 
}
.combobox > *:first-child {
  display: inline-block;
  width: 100%;
  box-sizing: border-box; /* so 100% includes border & padding */
}
/* '.combobox:focus-within { outline:...}' does not work properly 
   in Firefox because the focus box is expanded to include the 
   (possibly hidden) drop list. As a workaround, put focus box on 
   the focused child. It is barely-visible so that it does not look
   TOO ugly if the child isn't the same size as the parent. It
   may be uglier if the first child is not styled as width:100% */
.combobox > *:not(:last-child):focus {
  outline: 2px solid #48F8;
}
.combobox {
  margin: 5px; 
}

Вам также нужно немного JavaScript для синхронизации списка с текстовым полем:

function parentComboBox(el) {
    for (el = el.parentNode; el != null && Array.prototype.indexOf.call(el.classList, "combobox") <= -1;)
        el = el.parentNode;
    return el;
}
// Uses jQuery
$(".combobox.withtextlist > select").change(function() { 
  var textbox = parentComboBox(this).firstElementChild;
  textbox.value = this[this.selectedIndex].text;
});
$(".combobox.withtextlist > select").keypress(function(e) {
  if (e.keyCode == 13) // Enter pressed
    parentComboBox(this).firstElementChild.focus(); // Closes the popup
});