it-swarm.com.ru

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

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

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

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

44
Łukasz Bownik

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

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

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

15
Dan Monego

Вы можете сделать это с помощью <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>

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

94
Alexandru Boerescu

Это может быть достигнуто с помощью простого 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>
22
Natraj

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

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

8
Treb

Очень простая реализация (только базовая функциональность) на основе 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>

Обратите внимание: он использует previousElementSibling, который не поддерживается в старых браузерах (ниже 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
Max

ComboBox с TextBox (для предварительно определенных значений, а также для пользовательских значений.)

ComboBox с TextBox (нажмите здесь)

3
Lakshmana Kumar D

Немного CSS, и все готово скрипка

<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>
1
atom217

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

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

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

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

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

1
VonC

К сожалению, комбинированный список - это то, что было исключено из спецификаций HTML.

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

1
user7094

В 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's <select>, slightly lighter than FireFox's */
  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:...}` doesn't 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 doesn't 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
});
0
Qwertie