HTML带有输入选项的组合框

107

我原以为除了选择下拉列表中的值,还可以在组合框中输入文本。然而,我找不到如何实现此功能的信息。是否需要添加某些属性才能允许输入文本?


5
不行,你不能在没有 JavaScript 或其他“魔法”的情况下完成这个。单独的 <select> 元素无法做到那样。 - j08691
谢谢。也许我会寻找一个jQuery控件。 - birdus
如果您认为HTML5的list属性可以胜任工作,请考虑更改接受的答案。 - laggingreflex
我知道这是几年前的事情了,但我仍然感到困惑。你当时使用的是哪种代码来创建一个所谓的组合框? - Stewart
@Stewart - 推测:OP的措辞表明了“下拉菜单”和“组合框”的概念模糊。可能使用了<select><option>,并且开始时选择了一个空白选项。这个列表有一些值,并且“看起来像是一个组合框”;只是缺少在文本区域中输入的能力。 - ToolmakerSteve
11个回答

139

在使用datalist之前(见下面的注意事项),您需要提供一个额外的input元素,以便让用户输入他们自己的选项。

<select name="example">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="-">Other</option>
</select>

<input type="text" name="other">

这种机制在所有浏览器中均可运行,无需 JavaScript。

您可以使用一些 JavaScript 来巧妙地仅在选择“其他”选项时显示 input

datalist 元素

datalist 元素旨在提供更好的机制。在某些浏览器中(例如 iOS Safari < 12.2),不支持此元素或实现存在问题。 可以查看 Can I Use 页面 以查看当前 datalist 支持情况。

<input type="text" name="example" list="exampleList">
<datalist id="exampleList">
  <option value="A">  
  <option value="B">
</datalist>


1
老派但实用。 - maqs
22
请注意,一旦用户开始在文本框中输入,该文本将成为下拉菜单中显示的项目的筛选器。一个不可接受的意外:一旦选择了一个项目,该选择就变成了筛选器!在代码片段中选择“A”。现在再次打开下拉菜单:只有“ A”被显示为选项!!这不是组合框的工作原理;它本身并没有用处。据我所知,修复这个问题需要使用JS来清除打开下拉菜单时文本区域中的文本。(据我所知,这里所有其他的“datalist”答案都存在相同的致命缺陷。) - ToolmakerSteve
如果不清楚的话,我是在评论第二个基于“数据列表”的解决方案。 - ToolmakerSteve

67

在HTML中,您需要这样做:

首先定义一个文本输入框:

<input type="text" list="browsers" />

并将一个数据列表附加到它上面(请注意输入元素的list属性)。

<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist> 

10
Safari 不支持此功能。 - trpt4him
你说得没错,不过我认为它很快就会得到支持,因为它是HTML5标准的一部分(目前是候选状态)。http://www.w3.org/TR/2012/CR-html5-20121217/ - Kristóf Szalay
2
根据Can I Use,Safari 8将不支持datalist。MDN也是这样说的。 - Darren Griffith
2
Safari 9也不支持。苹果怎么了? - Sam Washburn
3
在Safari浏览器中,这个功能会受到什么影响? - William Entriken
似乎自2019年4月起就受到支持了。 - Kristóf Szalay

26

这个链接可以帮助您: http://www.scriptol.com/html5/combobox.php

您将看到两个例子。一个是HTML4,另一个是HTML5。

HTML5

<input type="text" list="browsers"/>
 <datalist id="browsers">
    <option>Google</option>
    <option>IE9</option>
 </datalist>

HTML4

 <input type="text" id="theinput" name="theinput" />
 <select name="thelist" onChange="combo(this, 'theinput')">
   <option>one</option>
   <option>two</option>
   <option>three</option>
 </select>
 function combo(thelist, theinput) {
     theinput = document.getElementById(theinput);
     var idx = thelist.selectedIndex;
     var content = thelist.options[idx].innerHTML;
     theinput.value = content;
 }

7
虽然这个链接可能回答了问题,但最好在此处包含答案的关键部分并提供链接以供参考。仅有链接的答案如果链接页面发生更改可能会变得无效。 - Joel

6
这里的 dojo 示例在大多数情况下不能应用于现有代码。因此,我不得不寻找替代方案,发现这里 - hxxp://technologymantrablog.com/how-to-create-a-combo-box-with-text-input-jquery-autocomplete/ (现在指向垃圾邮件网站或更糟的内容)。 archive.org(没有太大用处)
这是 jsfiddle 示例 - https://jsfiddle.net/ze7fgby7/

1
这个可以在Safari上运行,而不像其他大部分东西那样。 - Atte Juvonen
1
这太棒了!如果可以的话,我会给它10个赞。完美地处理了一切。 - Abhishek J
1
链接不起作用了(你知道有新链接吗?),但 jsfiddle 非常有用。 - Andre
@Andre:抱歉,我不知道新链接。希望JSFiddle能为您解决问题。 - PeakGen

4

现在已经是2016年,仍然没有一种简单的方法来实现组合框...虽然我们有datalist,但由于没有Safari/iOS支持,它实际上并不可用。至少我们有ES6...下面是一种尝试将div或span包装为组合框的组合类,它将输入框放在选择框上方,并绑定相关事件。

请在https://github.com/kofifus/Combo查看代码。

(该代码依赖于https://github.com/kofifus/New中的类模式)

创建一个组合框很容易!只需将一个div传递给其构造函数即可:

let mycombo=Combo.New(document.getElementById('myCombo'));
mycombo.options(['first', 'second', 'third']);

mycombo.onchange=function(e, combo) {
  let val=combo.value;
  // let val=this.value; // same as above
  alert(val);
 }
<script src="https://rawgit.com/kofifus/New/master/new.min.js"></script>
<script src="https://rawgit.com/kofifus/Combo/master/combo.min.js"></script>

<div id="myCombo" style="width:100px;height:20px;"></div>


嗨,您的代码片段在通过StackOverflow在iOS或Edge上无法运行。 - PeakGen

3

3
我的解决方案非常简单,看起来就像本地可编辑的组合框,甚至在IE6中也可以工作(这里的一些答案需要大量的代码或外部库,而结果就是这样,例如,文本框中的文本会出现在组合框的下拉图标后面,或者根本不像可编辑的组合框)。
重点是将组合框剪切为仅下拉图标可见于文本框上方。文本框在组合框的下方略微宽一点,所以您看不到其右端 - 在视觉上与组合框相连:https://jsfiddle.net/dLsx0c5y/2/
select#programmoduleselect
{
    clip: rect(auto auto auto 331px);
    width: 351px;
    height: 23px;
    z-index: 101; 
    position: absolute;
}

input#programmodule
{
    width: 328px;
    height: 17px;
}

<table><tr>
<th>Programm / Modul:</th>
<td>
    <select id="programmoduleselect"
        onchange="var textbox = document.getElementById('programmodule'); textbox.value = (this.selectedIndex == -1 ? '' : this.options[this.selectedIndex].value); textbox.select(); fireEvent2(textbox, 'change');"
        onclick="this.selectedIndex = -1;">
        <option value=RFEM>RFEM</option>
        <option value=RSTAB>RSTAB</option>
        <option value=STAHL>STAHL</option>
        <option value=BETON>BETON</option>
        <option value=BGDK>BGDK</option>
    </select>
    <input name="programmodule" id="programmodule" value="" autocomplete="off"
        onkeypress="if (event.keyCode == 13) return false;" />
</td>
</tr></table>

(最初在此处使用,但不要发送表单:old.dlubal.com/WishedFeatures.aspx)

编辑:对于macOS,样式需要有所不同:Ch是可以的,对于FF增加组合框的高度,Safari和Opera忽略组合框的高度,因此增加它们的字体大小(有一个上限,然后稍微减小文本框的高度):https://istack.dev59.com/efQ9i.webp


这对我来说非常有效,不必担心浏览器差异。 - cycle4passion

1
考虑到 HTML datalist 标签仍未完全支持,我使用了一种备选方法Dojo Toolkit ComboBox。这种方法比我探索的其他选项更容易实现且文档更为详细。它还能与现有框架很好地配合使用。在我的情况下,我将这个组合框添加到了一个基于 Codeigniter 和 Bootstrap 的现有网站中,没有出现任何问题。您只需要确保将 Dojo 主题(例如 class="claro")应用于组合框的父元素而不是 body 标签,以避免样式冲突。
首先,要包含一个 Dojo 主题的 CSS(如 'Claro')。重要的是,在下面的 JS 文件之前包括 CSS 文件。
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.9.6/dijit/themes/claro/claro.css" />

下一步,通过CDN引入jQuery和Dojo Toolkit。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js"></script>

接下来,你可以直接按照Dojo示例代码进行操作,或者使用下面的示例来获取一个可用的组合框。

<body>
    <!-- Dojo Dijit ComboBox with 'Claro' theme -->
    <div class="claro"><input id="item_name_1" class=""/></div>

    <script type="text/javascript">
        $(document).ready(function () {
            //In this example, dataStore is simply an array of JSON-encoded id/name pairs
            dataStore = [{"id":"43","name":"Domain Name Renewal"},{"id":"42","name":"Hosting Renewal"}];

            require(
                [ "dojo/store/Memory", "dijit/form/ComboBox", "dojo/domReady!"], 
                function (Memory, ComboBox) {
                    var stateStore = new Memory({
                        data: dataStore
                    });

                    var combo = new ComboBox({
                        id: "item_name_1",
                        name: "desc_1",
                        store: stateStore,
                        searchAttr: "name"},                        
                        "item_name_1"
                        ).startup();

                });

        });

    </script>
</body>

1

其他的答案都不令人满意,主要是因为用户界面看起来很糟糕。我发现了this,它看起来很好,非常接近完美,而且可以自定义。

这里可以找到完整的示例、选项等列表here,但这是一个基本演示:

$('#editable-select').editableSelect();
<link href="https://cdn.jsdelivr.net/npm/jquery-editable-select@2.2.5/dist/jquery-editable-select.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-editable-select@2.2.5/dist/jquery-editable-select.min.js"></script>

<select id="editable-select">
 <option>Alfa Romeo</option>
 <option>Audi</option>
 <option>BMW</option>
 <option>Citroen</option>
</select>


@maqs 当我发现这个库时,我搜索了很多,但是其他的库或解决方案都不是完整的解决方案,无论在哪个平台上都能良好运行并且看起来相同。在一些常见的平台上,许多解决方案看起来非常糟糕。 - Andrew
@maqs 任务不太简单的原因是HTML本身并不支持此功能,因此从外观到功能再到事件处理和配置的每个方面都必须进行一定的“黑客式”拼凑以绕过HTML的限制。 - Andrew

-1
    <html>
<head>
    <title></title>
    <script src="jquery-3.1.0.js"></script>
    <script>
        $(function () {
            $('#selectnumber').change(function(){
                alert('.val() = ' + $('#selectnumber').val() + '  AND  html() = ' + $('#selectnumber option:selected').html() + '  AND .text() = ' + $('#selectnumber option:selected').text());
            })
        });
    </script>
</head>
<body>
       <div>
        <select id="selectnumber">
            <option value="1">one</option>
            <option value="2">two</option>
            <option value="3">three</option>
            <option value="4">four</option>
        </select>

    </div>
   </body>
</html>

Click to see OutPut Screen

Thanks...:)


3
在回答问题时,加入一些细节或解释为什么你的答案可行总是一个好主意。 - Charlie Fish
2
虽然这段代码片段可能解决了问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议原因。同时,请尽量不要在代码中添加过多的解释性注释,因为这会降低代码和解释的可读性! - Blue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接