Reputation: 571
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??
Upvotes: 8
Views: 70418
Reputation: 78520
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);
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">With
lial
engraving</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>
Upvotes: 13
Reputation: 262919
You can use map() to build the <li>
elements from the <option>
elements, and replaceAll() to replace the <select>
element:
var $yearFilter = $("#yearfilter");
$yearFilter.find("option").map(function() {
var $this = $(this);
return $("<li>").attr("value", $this.attr("value")).text($this.text()).get();
}).appendTo($("<ul>").attr({
id: $yearFilter.attr("id"),
name: $yearFilter.attr("name")
})).parent().replaceAll($yearFilter);
You can see the results in this fiddle.
Upvotes: 2
Reputation: 92893
There is no reason to add name
attributes to ul
, nor value
attributes to li
tags.
Try this: http://jsfiddle.net/vfjFK/2/
$(function(){
var id = "yearfilter";
$('#'+id).after("<ul id='temp' />")
.children("option").each(function() {
$("#temp").append("<li>"+$(this).text()+"</li>");
})
.end().remove();
$('#temp').attr("id",id);
});
If you really need the useless attributes, though, try this: http://jsfiddle.net/vfjFK/3/
$(function(){
var id = "yearfilter";
$('#'+id).after("<ul id='temp' />")
.children("option").each(function() {
$("#temp").append('<li value="'+$(this).val()+'">'+$(this).text()+"</li>");
})
.end().remove();
$('#temp').attr({"id":id,"name":id});
});
Upvotes: 1
Reputation: 13756
$('#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.
Upvotes: 14
Reputation: 41236
You would simply replace the tags with their counterpart:
var select = $('#yearFilter');
var ul = $('<ul/>');
ul.attr({ id: select.attr('id'), name: select.attr('name') });
select.find('option').each(function()
{
var item = $('<li/>');
item.text(this.Text).val(this.val());
ul.append(item);
});
$('#yearFilter').replaceWith(ul);
Upvotes: 0
Reputation: 23132
Here is one way to do it:
var $select = $('#yourSelectElement'),
$ul = $('<ul></ul>').attr('id', $select.attr('id'))
.attr('name', $select.attr('name'));
$select.children().each(function() {
var $option = $(this);
$('<li></li>').val($option.val())
.text($option.text())
.appendTo($ul);
});
$select.replaceWith($ul);
Upvotes: 0