How to convert <select> dropdown into an unordered list using jquery?

How do I convert a dropdown in this format:

<select id="yearfilter" name="yearfilter">
<option value="">All years</option>
<option value="2011">2011</option>
<option value="2010">2010</option>
<option value="2009">2009</option>
</select>

into an unordered list in this format:

<ul id="yearfilter" name="yearfilter">
<li value="">All years</li>
<li value="2011">2011</li>
<li value="2010">2010</li>
<li value="2009">2009</li>
</ul>

using jquery??


Solution 1:

$('#yearfilter').parent().append('<ul id="newyearfilter" name="yearfilter"></ul>');
$('#yearfilter option').each(function(){
  $('#newyearfilter').append('<li value="' + $(this).val() + '">'+$(this).text()+'</li>');
});
$('#yearfilter').remove();
$('#newyearfilter').attr('id', 'yearfilter');

this is how I would do it.

Solution 2:

I am so going to get some hate for this solution but what about this?

var rep = $("select")
          .clone()
          .wrap("<div></div>")
          .parent().html()
          .replace(/select/g,"ul")
          .replace(/option/g,"li");

$("select").replaceWith(rep);

Edit:

And almost five years later; yes, I hate myself for this answer.

There are a few problems here. What if you have an option in the list that goes like this: <option value="5">With optional engraving</option>. You'll get <li value="5">Withlialengraving</li>. Here's an alternative in vanilla javascript (because jQuery doesn't really support this).

var parent = document.querySelector('select'),
    docFrag = document.createDocumentFragment(),
    list = document.createElement('ul');

// build list items
while(parent.firstChild) {
  // we simultaniously remove and store the node
  var option = parent.removeChild(parent.firstChild);

  // not interested in text nodes at this point
  if(option.nodeType !== 1) continue;

  // lets build a list item
  var listItem = document.createElement('li');

  // we loop through the properties of the node and
  // apply only the ones that also exist as atributes
  for(var i in option) {
    if(option.hasAttribute(i)) listItem.setAttribute(i, option.getAttribute(i));
  }

  // loop through the select children to append to the
  // list item.  We want text nodes this time.
  while(option.firstChild) {
    listItem.appendChild(option.firstChild);
  }

  // append them to the document fragment for easier
  // appending later
  docFrag.appendChild(listItem);
}

// build wrapping ul.  Same as above
for(var i in parent) {
  if(parent.hasAttribute(i)) list.setAttribute(i, parent.getAttribute(i));
}

// add the list items to the list
list.appendChild(docFrag);

// lastly replace the select node with the list
parent.parentNode.replaceChild(list, parent);
<select id="yearfilter" name="yearfilter">
<option value="">All years</option>
<option value="2011">2011</option>
<option value="2010">2010</option>
<option value="2009">2009</option>
</select>