Cuadro combinado HTML con opción para escribir una entrada

82

Tenía la impresión de que podía escribir en un cuadro combinado además de seleccionar cualquier valor que ya estuviera en la lista. Sin embargo, parece que no puedo encontrar información sobre cómo hacer esto. ¿Hay alguna propiedad que deba agregar para permitir escribir texto?

pájaro
fuente
4
No, no puedes hacer esto sin algún tipo de JavaScript u otra magia. Por sí solo, el <select>elemento no puede hacer eso.
j08691
Gracias. Tal vez busque un control jQuery entonces.
birdus
Considere cambiar la respuesta aceptada si cree que el listatributo HTML5 hace el trabajo.
laggingreflex
Me doy cuenta de que esto fue hace años, pero aún estoy desconcertado. ¿Qué código estaba usando para crear algo que supuestamente es un cuadro combinado?
Stewart
@Stewart - Especulando: la redacción de OP sugiere difuminar el concepto dropdowncon combo box. Presumiblemente usado <select>con <option>, y comenzó con una opción en blanco seleccionada. Tiene una lista de valores y "parece un cuadro combinado"; simplemente carece de la capacidad de escribir en el área de texto.
ToolmakerSteve

Respuestas:

113

Antes datalist(consulte la nota a continuación), proporcionaría un inputelemento adicional para que las personas escribieran su propia opción.

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

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

Este mecanismo funciona en todos los navegadores y no requiere JavaScript .

Puede usar un poco de JavaScript para ser inteligente y mostrar solo el input si se selecciona la opción "Otro".

elemento de lista de datos

El datalistelemento está destinado a proporcionar un mejor mecanismo para este concepto. En algunos navegadores, por ejemplo, iOS Safari <12.2, esto no fue compatible o la implementación tuvo problemas. Consulte la página ¿Puedo usar para ver el soporte actual de la lista de datos ?

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

Fenton
fuente
Vieja escuela pero práctica.
maqs
1
(Chrome en Windows, versión actual) Tenga en cuenta que una vez que el usuario comienza a escribir en el cuadro de texto, ese texto se convierte en un filtro sobre los elementos que se muestran en el menú desplegable. Un error inaceptable: una vez que se ha seleccionado un elemento, ¡esa selección se convierte en el filtro! En el fragmento de código, seleccione "A". Ahora abra el menú desplegable nuevamente: ¡¡SÓLO "A" se muestra como una opción !! No es así como funciona un cuadro combinado; no es útil tal como está. AFAIK, arreglar esto requiere que JS BORRE el área de texto cuando abre el menú desplegable. (Todas las otras respuestas "datalistas" aquí tienen el mismo defecto fatal, AFAIK.)
ToolmakerSteve
... en caso de que no esté claro, estoy comentando la segunda solución, basada en datalist.
ToolmakerSteve
59

en HTML, lo hace al revés: define una entrada de texto:

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

y adjuntarle un datalist. (tenga en cuenta el atributo de lista de la entrada).

<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist> 
Kristóf Szalay
fuente
10
Esto no es compatible con Safari.
trpt4him
Tienes razón, sin embargo, creo que será compatible en un futuro próximo, ya que es parte del estándar HTML5 (candidato por ahora). w3.org/TR/2012/CR-html5-20121217
Kristóf Szalay
2
De acuerdo con Can I Use , Safari 8 no admitirá la lista de datos. MDN dice lo mismo.
Darren Griffith
2
Y tampoco Safari 9. ¿Qué pasa con Apple?
Sam Washburn
3
¿Cómo se degrada esto con Safari?
William Entriken
22

Este enlace puede ayudarlo: http://www.scriptol.com/html5/combobox.php

Tienes dos ejemplos. Uno en html4 y otro en 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;
 }
Celso Soares
fuente
6
Si bien este enlace puede responder la pregunta, es mejor incluir aquí las partes esenciales de la respuesta y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden dejar de ser válidas si cambia la página enlazada.
Joel
6

El dojoejemplo aquí no funciona cuando se aplica al código existente en la mayoría de los casos. Por lo tanto, tuve que encontrar una alternativa, que se encuentra aquí: hxxp: //technologymantrablog.com/how-to-create-a-combo-box-with-text-input-jquery-autocomplete/ (ahora apunta a un sitio de spam o peor )

archive.org (no muy útil)

Aquí está el jsfiddle - https://jsfiddle.net/ze7fgby7/

Jugo de limon
fuente
1
Esto funciona con Safari, a diferencia de casi todo lo demás.
Atte Juvonen
1
¡Esto es malditamente increíble, hombre! .. Le daría 10 votos a favor si pudiera .. Maneja todo tan perfectamente ..
Abhishek Jebaraj
1
Desafortunadamente, el enlace ya no funciona (¿conoce un enlace nuevo?), Pero jsfiddle es muy útil.
Andre
@Andre: Lo siento, no tengo idea del nuevo enlace. Espero que JSFiddle haga el truco por usted.
Jugo de limón
4

Bueno, es 2016 y todavía no hay una manera fácil de hacer un combo ... seguro que tenemos una lista de datos, pero sin el soporte de safari / ios no es realmente utilizable. Al menos tenemos ES6 ... a continuación hay un intento de una clase combinada que envuelve un div o span, convirtiéndolo en un combo colocando un cuadro de entrada encima de select y vinculando los eventos relevantes.

ver el código en: https://github.com/kofifus/Combo

(el código se basa en el patrón de clase de https://github.com/kofifus/New )

¡Crear un combo es fácil! simplemente pase un div a su constructor:

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>

kofifus
fuente
Hola, su snipper de código no se ejecuta en iOS o Edge a través de StackOverflow.
Jugo de limón
3

Mi solución es muy simple, se ve exactamente como un cuadro combinado editable nativo y, sin embargo, funciona incluso en IE6 (algunas respuestas aquí requieren mucho código o bibliotecas externas y el resultado es así, por ejemplo, el texto en el cuadro de texto va detrás del ícono desplegable de la parte del cuadro combinado o no parece un cuadro combinado editable en absoluto).

El punto es recortar el cuadro combinado solo el icono desplegable para que sea visible encima del cuadro de texto. Y el cuadro de texto es un poco ancho debajo de la parte del cuadro combinado, por lo que no ve su extremo derecho; visualmente continúa con el cuadro combinado: 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>

(Usado originalmente, por ejemplo, aquí, pero no envíe el formulario: old.dlubal.com/WishedFeatures.aspx)

EDITAR: Los estilos deben ser un poco diferentes para macOS: Ch ​​está bien, para FF, aumente la altura del cuadro combinado, Safari y Opera ignoran la altura del cuadro combinado, así que aumente su tamaño de fuente (tiene un límite superior, entonces disminuya el cuadro de texto) altura un poco): https://i.stack.imgur.com/efQ9i.png

Ladislav Zima
fuente
Esto funcionó muy bien para mí al no tener que preocuparme por las diferencias del navegador
cycle4passion
1

Dado que la etiqueta de lista de datos HTML todavía no es totalmente compatible, un enfoque alternativo que utilicé es el Dojo Toolkit ComboBox . Fue más fácil de implementar y mejor documentado que otras opciones que he explorado. También funciona muy bien con los marcos existentes. En mi caso, agregué este cuadro combinado a un sitio web existente que se basa en Codeigniter y Bootstrap sin problemas. Solo debe asegurarse de aplicar el tema Dojo (por ejemplo, class = "claro") al elemento principal del combo en lugar de la etiqueta del cuerpo para evitar conflictos de estilo.

Primero, incluya el CSS para uno de los temas de Dojo (como 'Claro'). Es importante que el archivo CSS se incluya antes que los archivos JS a continuación.

<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.9.6/dijit/themes/claro/claro.css" />

A continuación, incluya jQuery y Dojo Toolkit a través de CDN

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

A continuación, puede seguir el código de muestra de Dojo o usar la muestra a continuación para obtener un cuadro combinado que funcione.

<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>
Flareman2020
fuente
-2
    <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>

Haga clic para ver la pantalla de salida

Gracias...:)

Bhanu Pratap
fuente
1
Siempre es una buena idea incluir algún detalle o explicación de por qué funciona su respuesta.
Charlie Fish
1
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y es posible que esas personas no conozcan los motivos de su sugerencia de código. Por favor, trate también de no llenar su código con comentarios explicativos, ya que esto reduce la legibilidad tanto del código como de las explicaciones.
Adiós StackExchange
-2

Ninguna de las otras respuestas fue satisfactoria, en gran parte porque la interfaz de usuario todavía se ve mal. Encontré esto , que se ve bien y está muy cerca de ser perfecto y personalizable.

Aquí puede encontrar una lista completa de ejemplos y opciones , pero aquí hay una demostración básica:

$('#editable-select').editableSelect();
<link href="https://cdn.jsdelivr.net/npm/[email protected]/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/[email protected]/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>

Andrés
fuente
@maqs Miré mucho a mi alrededor cuando encontré esta biblioteca, y ninguna de las otras bibliotecas o soluciones que existían eran soluciones completas que funcionaban bien y tenían el mismo aspecto independientemente de la plataforma. En algunas plataformas comunes, muchas soluciones parecían absolutamente terribles.
Andrew
@maqs La razón por la que no es una tarea tan simple es porque HTML no lo admite de inmediato y, por lo tanto, todos los aspectos, desde el aspecto hasta la funcionalidad, el manejo de eventos y la configuración, deben piratearse juntos para que funcionen. en torno a las limitaciones de HTML.
Andrew