How can I create an editable dropdownlist in HTML?

前端 未结 11 1023
终归单人心
终归单人心 2020-11-29 01:51

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 predefin

相关标签:
11条回答
  • 2020-11-29 02:17

    You can accomplish this by using the <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>

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

    0 讨论(0)
  • 2020-11-29 02:18

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

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

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

    /* ------------------------------------------ */
    /* ----- 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:

    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 讨论(0)
  • 2020-11-29 02:20

    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 UI jQuery UI and in dojo dojo. jQuery is more popular, but dojo allows you to declaratively define widgets in HTML, which sounds more like what you're looking for.

    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.

    0 讨论(0)
  • 2020-11-29 02:26

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

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

    0 讨论(0)
  • 2020-11-29 02:28

    I am not sure there is a way to do it automatically without 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.

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

    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.

    0 讨论(0)
  • 2020-11-29 02:29

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

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

    0 讨论(0)
提交回复
热议问题