How to convert unordered list into nicely styled <select> dropdown using jquery? (ok)

https://stackoverflow.com/questions/1897129/how-to-convert-unordered-list-into-nicely-styled-select-dropdown-using-jquery

Ask QuestionAsked 10 years, 6 months agoActive 3 years, 3 months agoViewed 44k times1817

How do I convert an unordered list in this format

<ul class="selectdropdown">
    <li><a href="one.html" target="_blank">one</a></li>
    <li><a href="two.html" target="_blank">two</a></li>
    <li><a href="three.html" target="_blank">three</a></li>
    <li><a href="four.html" target="_blank">four</a></li>
    <li><a href="five.html" target="_blank">five</a></li>
    <li><a href="six.html" target="_blank">six</a></li>
    <li><a href="seven.html" target="_blank">seven</a></li>
</ul>

into a dropdown in this format

<select>
    <option value="one.html" target="_blank">one</option>
    <option value="two.html" target="_blank">two</option>
    <option value="three.html" target="_blank">three</option>
    <option value="four.html" target="_blank">four</option>
    <option value="five.html" target="_blank">five</option>
    <option value="six.html" target="_blank">six</option>
    <option value="seven.html" target="_blank">seven</option>
</select>

using jQuery?

Edit: When selecting an entry from the select/dropdown the link should open in a new window or tab automatically. I also want to able to style it like: http://www.dfc-e.com/metiers/multimedia/opensource/jqtransform/javascript jquery css xhtmlshare improve this question follow edited Mar 24 '14 at 14:13lorem monkey3,63233 gold badges3030 silver badges4545 bronze badgesasked Dec 13 '09 at 17:36Jitendra Vyas127k211211 gold badges529529 silver badges810810 bronze badges

add a comment

5 Answers

ActiveOldestVotes15

$('ul.selectdropdown').each(function() {
    var select = $(document.createElement('select')).insertBefore($(this).hide());
    $('>li a', this).each(function() {
        var a = $(this).click(function() {
            if ($(this).attr('target')==='_blank') {
                window.open(this.href);
            }
            else {
                window.location.href = this.href;
            }
        }),
        option = $(document.createElement('option')).appendTo(select).val(this.href).html($(this).html()).click(function() {
            a.click();
        });
    });
});

In reply to your last comment, I modified it a little bit but haven't tested it. Let me know.

$('ul.selectdropdown').each(function() {
    var list = $(this), select = $(document.createElement('select')).insertBefore($(this).hide());

    $('>li a', this).each(function() {
        var target = $(this).attr('target'),
        option = $(document.createElement('option'))
            .appendTo(select)
            .val(this.href)
            .html($(this).html())
            .click(function(){
                if(target==='_blank') {
                    window.open($(this).val());
                }
                else {
                    window.location.href = $(this).val();
                }
            });
    });
    list.remove();
});

share improve this answer follow edited Mar 24 '14 at 14:19lorem monkey3,63233 gold badges3030 silver badges4545 bronze badgesanswered Dec 13 '09 at 19:32czarchaic5,8302323 silver badges2121 bronze badges

show 4 more comments21

$(function() {
    $('ul.selectdropdown').each(function() {
        var $select = $('<select />');

        $(this).find('a').each(function() {
            var $option = $('<option />');
            $option.attr('value', $(this).attr('href')).html($(this).html());
            $select.append($option);
        });

        $(this).replaceWith($select);
    });
});

EDIT

As with any jQuery code you want to run on page load, you have to wrap it inside $(document).ready(function() { ... }); block, or inside it's shorter version $(function() { ... });. I updated the function to show this.

EDIT

There was a bug in my code also, tried to take href from the li element.share improve this answer follow edited Dec 13 '09 at 18:19answered Dec 13 '09 at 17:50Tatu Ulmanen110k3131 gold badges171171 silver badges179179 bronze badges

show 1 more comment2

This solution is working also in IE and working with selected item (in anchor tag).

$('ul.selectdropdown').each(function(){
var list=$(this),
    select=$(document.createElement('select')).insertBefore($(this).hide()).change(function(){
  window.location.href=$(this).val();
});
$('>li a', this).each(function(){
  var option=$(document.createElement('option'))
   .appendTo(select)
   .val(this.href)
   .html($(this).html());
  if($(this).attr('class') === 'selected'){
    option.attr('selected','selected');
  }
});
list.remove();
});

share improve this answer follow answered Jul 20 '11 at 10:31Radim2111 bronze badge

add a comment0

Thank you all for posting the codes. My scenario is similar but my situation is for Responsiveness that for x-size it would switch to a dropdown list, then if not x-size, using csswatch to check for the "display" properties of an element that has certain amount of width set to it (eg: 740px). Thought I share this solution for anyone who is interested. This is what I have combined with Tatu' codes. Instead of replacing the html, I created then hide the new html then only add them when necessary:

var $list = $('ul.list');
(listFunc = function(display){

    //Less than x-size turns it into a dropdown list
    if(display == 'block'){
        $list.hide();
        if($('.sels').length){
            $('.sels').show();
        } else {
            var $select = $('<select class="sels" />');

            $list.find('a').each(function() {
                var $option = $('<option />');
                $option.attr('value', $(this).attr('href')).html($(this).html());
                $select.append($option);
            });

            $select.insertAfter($list);

            $('.sels').on('change', function(){
                window.location = this.value;
            });
        }
    } else {
        $('.sels').hide();
        $list.show();
    }
})(element.css('display'));
element.csswatch({
    props: 'display'
}).on('css-change', function (event, change) {
    return listFunc(change.display);
});

share improve this answer follow edited Oct 4 '13 at 22:05answered Oct 4 '13 at 18:04Mon1122 bronze badgesadd a comment0

I have recently created a solution where the ul transformed, mimics nearly completely the select.

It has in adition a search for the options of the select and supports the active state. Just add a class with name active and that option will be selected.

It handles the keyboard navigation.

Take a look at the code here: GitHub Code

And a live example here: Code Example

The unordered list must be in the form:

<ul id="...">
  <li><a href="...">...</a></li>
  <li><a href="...">...</a></li>
  <li><a class="active" href="...">...</a></li>
  ...
</ul>

To convert the ul to select just call:

$(window).on("load resize", function() {
  ulToSelect($("ul#id"), 767);
});

Where #id is an id for the unordered list and 767 is the minimum width of the window for the convertion to take place. This is very useful if you want the convertion to take place only for mobile or tablet.share improve this answer follow edited Apr 1 '17 at 15:20answered Apr 1 '17 at 15:02quAnton60666 silver badges99 bronze badgesadd a comment

Last updated