19

I need a drop down menu with multiple columns. I googled and found a solution:

<select name="timezones">
    <option value="1">
        <column>Pacific/Auckland</column>
        <column>+12:00</column>
    </option>
    <option value="2">
        <column>Australia/Brisbane</column>
        <column>+10:00</column>
    </option>
</select>

However, the columns are not adjusted under each other.

How it looks:

Pacific/Auckland +12:00
Australia/Brisbane +10:00

How I want it looks like:

Pacific/Auckland    +12:00
Australia/Brisbane  +10:00
gerrnar
  • 407
  • 1
  • 6
  • 15

4 Answers4

16

inside of a select isn't valid HTML as far as I know, however this isn't hard to solve with jquery (http://jsfiddle.net/upgradellc/ASR2K/2):

html:

<select name="timezones" id="timezones">
    <option value="1">Pacific/Auckland +12:00 </option>
    <option value="2">Australia/Brisbane +10:00 </option>
     <option value="3">Aust +10:00 </option>
    <option value="3">A +10:00 </option>
</select>

javascript:

var spacesToAdd = 5;
var biggestLength = 0;
$("#timezones option").each(function(){
var len = $(this).text().length;
    if(len > biggestLength){
        biggestLength = len;
    }
});
var padLength = biggestLength + spacesToAdd;
$("#timezones option").each(function(){
    var parts = $(this).text().split('+');
    var strLength = parts[0].length;
    for(var x=0; x<(padLength-strLength); x++){
        parts[0] = parts[0]+' '; 
    }
    $(this).text(parts[0].replace(/ /g, '\u00a0')+'+'+parts[1]).text;
});

css, to make sure the fonts line up:

select{
    font-family:"Courier New", Courier, monospace
}
Max
  • 2,082
  • 19
  • 25
  • What's the character mismatch? – Max Jun 18 '13 at 07:38
  • @Max I think your code have flaw, if I add an option with 13 character, it fails. Try this `` add this to your html and check – Praveen Jun 18 '13 at 07:40
  • @user1671639 you're correct- the flaw isn't with my code though, it's with the font- updated answer with fix! – Max Jun 18 '13 at 07:52
  • @Max yes, you are right. the mismatch was font related. My internet was out of service for some minutes. now that I have come, you have already mentioned the font. – gerrnar Jun 18 '13 at 07:57
  • 1
    This seems to have stopped working with Chrome at some point. I'm on version 64.0.3282.140 and it definitely doesn't work. – Dan Sandberg Feb 18 '18 at 16:18
  • 1
    The columns are not aligned in Firefox. – faintsignal Nov 22 '18 at 15:39
5

I came here looking for a solution. Nothing met my needs so I rolled my own:

<style>
    .selectedOrder {
        height: 30px; 
        display:none; 
    }

    /* class applies to select element itself, not a wrapper element */
    .select-css {
        font-size: 12px;
        font-family: sans-serif;
        font-weight: 700;
        color: #444;
        line-height: 1.3;
        padding: .6em 1.4em .5em .8em;
        /* width: 100%; */
        max-width: 100%; /* useful when width is set to anything other than 100% */
        box-sizing: border-box;
        margin: 0;
        border: 1px solid #aaa;
        box-shadow: 0 1px 0 1px rgba(0,0,0,.04);
        border-radius: .5em;
        -moz-appearance: none;
        -webkit-appearance: none;
        appearance: none;
        background-color: #fff;
        /* note: bg image below uses 2 urls. The first is an svg data uri for the arrow icon, and the second is the gradient. 
            for the icon, if you want to change the color, be sure to use `%23` instead of `#`, since it's a url. You can also swap in a different svg icon or an external image reference
            
        */
        background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
          linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%);
        background-repeat: no-repeat, repeat;
        /* arrow icon position (1em from the right, 50% vertical) , then gradient position*/
        background-position: right .7em top 50%, 0 0;
        /* icon size, then gradient */
        background-size: .65em auto, 100%;
    }
    /* Hide arrow icon in IE browsers */
    .select-css::-ms-expand {
        display: none;
    }
    /* Hover style */
    .select-css:hover {
        border-color: #888;
    }
    /* Focus style */
    .select-css:focus {
        border-color: #aaa;
        /* It'd be nice to use -webkit-focus-ring-color here but it doesn't work on box-shadow */
        box-shadow: 0 0 1px 3px rgba(59, 153, 252, .7);
        box-shadow: 0 0 0 3px -moz-mac-focusring;
        color: #222; 
        outline: none;
    }

    /* Set options to normal weight */
    .select-css option {
        font-weight:normal;
    }

    /* Support for rtl text, explicit support for Arabic and Hebrew */
    *[dir="rtl"] .select-css, :root:lang(ar) .select-css, :root:lang(iw) .select-css {
        background-position: left .7em top 50%, 0 0;
        padding: .6em .8em .5em 1.4em;
    }

    /* Disabled styles */
    .select-css:disabled, .select-css[aria-disabled=true] {
        color: graytext;
        background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22graytext%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
          linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%);
    }

    .select-css:disabled:hover, .select-css[aria-disabled=true] {
        border-color: #aaa;
    }
</style>

<div id="orderSelectContainer">
    <div id="selectedOrder" class="selectedOrder select-css" style="width: 533px; display: block;">
        <div class="currentSelectedOrder" data-value="45536" style="float: left;">
                <span style="float:left; min-width:200px;">Store 1</span>
                <span style="float:left; min-width:50px"> 55628</span>
                <span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
                <span style="float:left; min-width:100px">  </span>
    </div>
    </div>
    <div id="orderSelect" class="select-css" style="position: absolute; z-index: 1000; background-image: none; display: none;">
        <div class="orderContainer">
            <div class="order" data-value="45628" style="float: left; background: white;">
                <span style="float:left; min-width:200px;">Store 1</span>
                <span style="float:left; min-width:50px"> 55628</span>
                <span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
                <span style="float:left; min-width:100px">  </span>
            </div>
        </div>
        <div class="orderContainer">
            <div class="order" data-value="45536" style="float: left; background: lightblue;">
                <span style="float:left; min-width:200px;">Store 2</span>
                <span style="float:left; min-width:50px"> 55536</span>
                <span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
                <span style="float:left; min-width:100px"> Bad UPCs</span>
            </div>
        </div>
        <div class="orderContainer">
            <div class="order" data-value="45682" style="float: left; background: white;">
                <span style="float:left; min-width:200px;">Store 3</span><span style="float:left; min-width:50px"> 55682</span>
                <span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
                <span style="float:left; min-width:100px"> Bad UPCs</span>
            </div>
        </div>
        <div class="orderContainer">
            <div class="order" data-value="45625" style="float: left; background: white;">
                <span style="float:left; min-width:200px;">Store 4</span>
                <span style="float:left; min-width:50px"> 55625</span>
                <span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
                <span style="float:left; min-width:100px">  </span>
            </div>
        </div>
        <div class="orderContainer">
            <div class="order" data-value="45556" style="float: left; background: white;">
                <span style="float:left; min-width:200px;">Store 5</span>
                <span style="float:left; min-width:50px"> 55556</span>
                <span style="float:left; min-width: 150px;"> Quantity Discrepancy</span>
                <span style="float:left; min-width:100px"> Bad UPCs</span>
            </div>
        </div>
    </div>
    <br style="clear:both"><br>
</div>

<script>
    $(document).on(`click`, `.order`, function() {
        if ($(this).data(`value`) !== $(`#selectedOrder >.currentSelectedOrder`).data(`value`)) {
            $(`#orderContainer`).html(``);
        }
        $(`#selectedOrder`).html($(this).prop(`outerHTML`)).find(`.order`).removeClass(`order`).css(`background`, ``).addClass(`currentSelectedOrder`);
        $(`.order`).css(`background`, `white`);
        $(this).css(`background`, `lightblue`);
        $(`#selectedOrder`).show();
        $(`#orderSelect`).hide();
    });

    $(document).on(`click`, `#selectedOrder`, function() {
        //$(`#selectedOrder`).hide();
        $(`#orderSelect`).toggle();
    });

    $(document).on(`mouseenter`, `.order`, function() {
        $(`.order`).css(`background`, `white`);
        $(this).css(`background`, `lightblue`);
    });

    $(document).on(`mouseexit`, `.order`, function() {
        $(this).css(`background`, `white`);
    });
<script>

It looks like a select and it works like a select;

https://jsfiddle.net/schmidtc63/xu8zgpc9/

Chris
  • 650
  • 7
  • 20
4

This solution does not expect specific font, it measures your text with your font.

There is a "magic number" to shrink the spaces between both columns the bigger this number the closer the columns are but if it is too big the function won’t work (I use 60 with my font Verdana 12px).

Add css with your font

.measuring {
    font-size: 12px;
    font-family: Verdana,Arial,sans-serif;
    display:none;
}

Add span in your page

<span id="measuring" class="measuring"></span>

Use the function twoColumnDropDown().

function twoColumnDropDown(dd, separatorChars, magicNumber) {
    var biggestLength = 0;
    $(dd).find('option').each(function () {
        $("#measuring").text($(this).text().replace(separatorChars, ''));
        if ($("#measuring").width() > biggestLength) {
            biggestLength = $("#measuring").width();
        }
    });
    biggestLength = biggestLength - magicNumber;
    $(dd).find('option').each(function () {
        if ($(this).text() != "") {
            var parts = $(this).text().split(separatorChars);
            $("#measuring").text(parts[0]);
            $(this).text(parts[0] + String.fromCharCode(8202).repeat(biggestLength - $("#measuring").width()) + parts[1]);

        }
    });
}

Explanation:

  • dd = select element
  • separatorChars = usually "-"
  • magicNumber = explained earlier
Honza Zidek
  • 9,204
  • 4
  • 72
  • 118
-3

This can be solved with div, css and jquery(http://jsfiddle.net/5hvd6k83/68/).

HTML:

<textarea id="textarea" style="width:250px;height:100px;"></textarea>
<div class="dropdown">
  <div id="myDropdown" class="dropdown-content">
    <a>
      <div class="container">
        <div class="block word">con</div>
        <div class="block prob">20%</div>
        </div>
    </a>
    <a>
      <div class="container">
        <div class="block word">constant</div>
        <div class="block prob">20%</div>
        </div>
    </a>
  </div>
</div>

CSS:

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  vertical-align: middle;
}

.block {
  width: 60px;
  height: auto;
  margin: 3px;
  overflow: hidden;
}



.word {
  text-align: left;
}

.prob {
  text-align: right;
}


.dropdown-content {
  display: none;
  background-color: #f1f1f1;
  width: 300px;
  height: auto;
  overflow: auto;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.5);
  z-index: 1;
}

.dropdown-content a {
  color: black;
  display: block;
}

// .dropdown a:hover { background-color: #ddd; }
.show { display: block; }

Javascript:

const items = document.querySelectorAll("#myDropdown > a");

var preItem, currItem;

var tabCnt = 0;
const itemLen = items.length;

document.getElementById("myDropdown").classList.toggle("show");


$(document).delegate('#textarea', 'keydown', function(e) {
    var keyCode = e.keyCode || e.which;
  if (keyCode == 9) {
    e.preventDefault();
    currItem = items[tabCnt % itemLen];
    currItem.style.backgroundColor = 'lightblue';
    tabCnt += 1;
    if (preItem) {
        preItem.style.backgroundColor = '';
    }
    var word = $(currItem).find('.word');
    $('#textarea').text($(word).text());
    preItem = currItem;
  }
});

Result: Result

Wenmin Wu
  • 1,808
  • 12
  • 24