如何在 HTML 中创建可编辑的下拉列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/264640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 22:40:34  来源:igfitidea点击:

How can I create an editable dropdownlist in HTML?

htmlcomboboxhtml-select

提问by ?ukasz Bownik

I'd like to create a text field with a dropdown list that lets the user choose some predefined values. The user should also be able to type a new value or select a predefined one from a dropdown list. I know that I can use two widgets for that but in my app it would be more ergonomnic if it was unified in a one widget.

我想创建一个带有下拉列表的文本字段,让用户选择一些预定义的值。用户还应该能够输入一个新值或从下拉列表中选择一个预定义的值。我知道我可以为此使用两个小部件,但在我的应用程序中,如果将它统一在一个小部件中会更加符合人体工程学。

Is there a standard widget or do I have to use a third party javascript?

是否有标准小部件或我必须使用第三方 javascript?

How about browser portability?

浏览器的便携性怎么样?

采纳答案by Dan Monego

The best way to do this is probably to use a third party library.

最好的方法可能是使用第三方库。

There's an implementation of what you're looking for in jQuery UIjQuery UIand in dojodojo. jQuery is more popular, but dojo allows you to declaratively define widgets in HTML, which sounds more like what you're looking for.

jQuery UIjQuery UIdojodojo中有您正在寻找的实现。jQuery 更受欢迎,但 dojo 允许您在 HTML 中声明性地定义小部件,这听起来更像您正在寻找的。

Which one you use will depend on your style, but both are developed for cross browser work, and both will be updated more often than copy and paste code.

您使用哪一个取决于您的风格,但两者都是为跨浏览器工作而开发的,并且两者的更新频率都比复制和粘贴代码要高。

回答by Alexandru Boerescu

You can accomplish this by using the <datalist>tag in HTML5.

您可以通过使用<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>

If you double click on the input text in the browser a list with the defined option will appear.

如果您双击浏览器中的输入文本,将出现一个包含已定义选项的列表。

回答by Natraj

This can be achieved with the help of plain HTML, CSS and JQuery. I have created a sample page:

这可以在纯 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>

回答by Max

Very simple implementation (only basic functionality) based on CSS and one line of JavaScript code.

基于 CSS 和一行 JavaScript 代码的非常简单的实现(只有基本功能)。



HTML

HTML

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

Please note:it uses previousElementSibling()which is not supported in older browsers(below IE9)

请注意:它使用previousElementSibling()无法在旧版浏览器支持(以下IE9)

CSS

CSS

.dropdown {
    position: relative;
    width: 200px;
}

.dropdown select {
    width: 100%;
}

.dropdown > * {
    box-sizing: border-box;
    height: 1.5em;
}

.dropdown input {
    position: absolute;
    width: calc(100% - 20px);
}

Here it is on JSFiddle.

这是在JSFiddle 上

回答by Treb

The <select>tag only allows the use of predefined entries. The typical solution to your problem is to have one entry labeled 'Other' and a disabled edit field (<input type="text"). Add some JavaScript to enable the edit field only when 'Other' is selected.

<select>标签只允许使用预定义的条目。您的问题的典型解决方案是将一个条目标记为“其他”并禁用编辑字段 ( <input type="text")。添加一些 JavaScript 以仅在选择“其他”时启用编辑字段。

It may be possible to somehow create a dropdown that allows direct editing, but IMO that is not worth the effort. If it was, Amazon, Google or Microsoft would be doing it ;-) Just get the job done with the least complicated solution. It as faster (your boss may like that) and usually easier to maintain (you may like that).

以某种方式创建一个允许直接编辑的下拉菜单是可能的,但 IMO 不值得付出努力。如果是这样,亚马逊、谷歌或微软会这样做;-) 只需用最简单的解决方案来完成工作。它更快(您的老板可能会喜欢)并且通常更易于维护(您可能会喜欢)。

回答by Lakshmana Kumar D

ComboBox with TextBox (For Pre-defined Values as well as User-defined Values.)

带文本框的组合框(用于预定义值和用户定义值。)

ComboBox with TextBox (Click Here)

带文本框的组合框(单击此处)

回答by atom217

A little CSS and you are done fiddle

一点 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>

回答by atom217

A combobox is unfortunately something that was left out of the HTML specifications.

不幸的是,组合框被排除在 HTML 规范之外。

The only way to manage it, rather unfortunately, is to roll your own or use a pre-built one. This onelooks quite simple. I use this onefor an open-source app although unfortunately you have to pay for commercial usage.

不幸的是,管理它的唯一方法是自己动手或使用预​​先构建的方法。这个看起来很简单。我将这个用于开源应用程序,但不幸的是您必须为商业用途付费。

回答by VonC

I am not sure there is a way to do it automatically without javascript.

我不确定有没有办法在没有 javascript 的情况下自动完成。

What you need is something which runs on the browser side to submit your form back to the server when they user makes a selection - hence, javascript.

您需要的是在浏览器端运行的东西,以便在用户进行选择时将您的表单提交回服务器 - 因此,javascript。

Also, ensure you have an alternate means (i.e. a submit button) for those who have javascript turned off.

另外,请确保您有其他方法(即提交按钮)供关闭 javascript 的人使用。

A good example: Combo-Box Viewer

一个很好的例子:组合框查看器

I had even a more sophisticated combo-box yesterday, with this dhtmlxCombo , using ajax to retrieve pertinent values amongst large quantity of data.

昨天我有一个更复杂的组合框,使用这个dhtmlxCombo,使用 ajax 在大量数据中检索相关值。

回答by Qwertie

HTML doesn't have a built-in editable dropdown list or combobox, but I implemented a mostly-CSS solution in an article.

HTML 没有内置的可编辑下拉列表或组合框,但我在一篇文章中实现了一个主要是 CSS 的解决方案。

You can see a full demo herebut in summary, write HTML like this:

你可以在这里看到一个完整的演示但总而言之,像这样编写 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>

And use CSS like this to style it (this is designed for both comboboxes, which have a down-arrow ? button, and dropdown menus which open when clicked and may be styled differently):

并使用这样的 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; 
}

You also need some JavaScript to synchronize the list with the textbox:

您还需要一些 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
});