it-swarm.com.de

Wie kann ich eine bearbeitbare Dropdown-Liste in HTML erstellen?

Ich möchte ein Textfeld mit einer Dropdown-Liste erstellen, in der der Benutzer einige vordefinierte Werte auswählen kann. Der Benutzer sollte auch in der Lage sein, einen neuen Wert einzugeben oder einen vordefinierten Wert aus einer Dropdown-Liste auszuwählen. Ich weiß, dass ich dafür zwei Widgets verwenden kann, aber in meiner App wäre es ergonomischer, wenn es in einem Widget vereint wäre.

Gibt es ein Standard-Widget oder muss ich ein Javascript eines Drittanbieters verwenden?

Wie wäre es mit Browser-Portabilität?

44
Łukasz Bownik

Der beste Weg, dies zu tun, ist wahrscheinlich die Verwendung einer Bibliothek eines Drittanbieters.

Es gibt eine Implementierung dessen, wonach Sie suchen in jQuery UI und in dojo . jQuery ist populärer, aber mit dojo können Sie Widgets deklarativ in HTML definieren, was eher nach dem klingt, wonach Sie suchen.

Welche Sie verwenden, hängt von Ihrem Stil ab, beide sind jedoch für die browserübergreifende Arbeit entwickelt und werden häufiger aktualisiert als Code kopieren und einfügen.

15
Dan Monego

Sie können dies erreichen, indem Sie das <datalist> Tag in 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>

Wenn Sie im Browser auf den eingegebenen Text doppelklicken, erscheint eine Liste mit der definierten Option.

94

Dies kann mit Hilfe von einfachem HTML, CSS und JQuery erreicht werden. Ich habe eine Beispielseite erstellt:

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

Das <select> tag erlaubt nur die Verwendung von vordefinierten Einträgen. Die typische Lösung für Ihr Problem besteht darin, einen Eintrag mit der Bezeichnung "Andere" und ein deaktiviertes Bearbeitungsfeld (<input type="text"). Fügen Sie JavaScript hinzu, um das Bearbeitungsfeld nur zu aktivieren, wenn "Andere" ausgewählt ist.

Es ist vielleicht möglich, ein Dropdown-Menü zu erstellen, das eine direkte Bearbeitung ermöglicht, aber IMO ist den Aufwand nicht wert. Wenn es so wäre, würden es Amazon, Google oder Microsoft tun. Es ist so schneller (Ihr Chef mag das) und normalerweise einfacher zu warten (das mag Ihnen gefallen).

8
Treb

Sehr einfache Implementierung (nur Basisfunktionalität) basierend auf CSS und einer Zeile JS-Code

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

Bitte beachten Sie: es wird previousElementSibling verwendet, das nicht unterstützt wird in älteren Browsern (unter 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);
}

Hier ist es auf JSFiddle

7
Max

ComboBox mit TextBox (Für vordefinierte Werte sowie benutzerdefinierte Werte.)

ComboBox mit TextBox (hier klicken)

3

Ein bisschen CSS und du bist fertig Geige

<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

Ich bin nicht sicher, ob es eine Möglichkeit gibt, dies automatisch ohne Javascript zu tun.

Was Sie brauchen, ist etwas, das auf der Browserseite ausgeführt wird, um Ihr Formular an den Server zurückzusenden, wenn der Benutzer eine Auswahl trifft - daher Javascript.

Stellen Sie außerdem sicher, dass Sie eine alternative Möglichkeit (d. H. Eine Senden-Schaltfläche) für Personen haben, bei denen Javascript deaktiviert ist.

Ein gutes Beispiel: Combo-Box Viewer

Ich hatte gestern sogar eine ausgefeiltere Combo-Box, mit dieser dhtmlxCombo , die Ajax verwendet, um relevante Werte aus einer großen Datenmenge abzurufen.

1
VonC

Eine Combobox wurde leider in den HTML-Spezifikationen nicht berücksichtigt.

Die einzige Möglichkeit, dies zu handhaben, besteht leider darin, Ihr eigenes zu würfeln oder ein vorgefertigtes zu verwenden. Dieser sieht ganz einfach aus. Ich benutze dieses für eine Open-Source-App, obwohl Sie leider für die kommerzielle Nutzung bezahlen müssen.

1
user7094

HTML hat keine eingebaute bearbeitbare Dropdown-Liste oder Combobox, aber ich habe in ein Artikel eine Lösung implementiert, die hauptsächlich aus CSS besteht.

Sie können eine vollständige Demo sehen hier aber zusammenfassend schreiben Sie HTML wie folgt:

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

Verwenden Sie CSS wie folgt, um es zu formatieren (dies gilt sowohl für Kombinationsfelder mit einem Abwärtspfeil ▾ als auch für Dropdown-Menüs, die beim Klicken geöffnet werden und möglicherweise unterschiedlich formatiert sind):

/* ------------------------------------------ */
/* ----- 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; 
}

Sie benötigen auch JavaScript, um die Liste mit dem Textfeld zu synchronisieren:

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