web-dev-qa-db-ja.com

HTMLで編集可能なドロップダウンリストを作成するにはどうすればよいですか?

ユーザーが事前定義された値を選択できるドロップダウンリスト付きのテキストフィールドを作成したいと思います。ユーザーは、新しい値を入力するか、ドロップダウンリストから定義済みの値を選択することもできます。私はそのために2つのウィジェットを使用できることを知っていますが、私のアプリでは、1つのウィジェットに統合された場合、より人間工学的になります。

標準のウィジェットはありますか、サードパーティのjavascriptを使用する必要がありますか?

ブラウザの移植性はどうですか?

44
Łukasz Bownik

これを行う最良の方法は、おそらくサードパーティのライブラリを使用することです。

jQuery UI および dojo には、探しているものの実装があります。 jQueryはより一般的ですが、dojoを使用すると、HTMLでウィジェットを宣言的に定義できます。これは、探しているもののように聞こえます。

どちらを使用するかはスタイルによって異なりますが、どちらもクロスブラウザーの作業用に開発されており、コードをコピーして貼り付けるよりも頻繁に更新されます。

15
Dan Monego

これを実現するには、HTML5で<datalist>タグを使用します。

<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

これは、プレーン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>タグは、事前定義されたエントリの使用のみを許可します。問題の典型的な解決策は、「その他」とラベル付けされた1つのエントリと無効な編集フィールド(<input type="text")。 JavaScriptを追加して、「その他」が選択されている場合にのみ編集フィールドを有効にします。

何らかの方法で直接編集できるドロップダウンを作成することは可能かもしれませんが、IMOは努力する価値はありません。もしそうなら、Amazon、Google、またはMicrosoftがそれをやるだろう;-)もっとも単純なソリューションで仕事を終わらせてください。それはより速く(上司はそれを好むかもしれません)、通常は保守しやすいです(あなたはそれを好むかもしれません)。

8
Treb

CSSと1行の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

TextBoxを備えたComboBox(事前定義値およびユーザー定義値用)

ComboBox with TextBox(ここをクリック)

3

ちょっとしたCSSで完了です fiddle

<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仕様から除外されたものです。

残念ながら、それを管理する唯一の方法は、自分でロールバックするか、事前に作成されたものを使用することです。 これ は非常に単純に見えます。私は this one をオープンソースアプリに使用しますが、残念ながらあなたは商用利用に対して支払いをしなければなりません。

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