Reputation: 4204
I am trying to create a custom dropdown select style by converting a standard form select into a <li>
list, however I need to add a few -data
attributes to each <option>
which then need to be copied over to the <li>
.
The problem is that I do not always know what those data attributes will be called and therefore I would like a way of just copying any data attributes from the <option>
tag onto the <li>
tag.
My current code is as follows:
Original <option>
tag...
<option data-somedata="something" data-else="something else" value="some value">Hello</option>
And the jQuery...
jQuery('.fancy-select .field option').each(function(){
jQuery(this).parents('.fancy-select').find('ul').append('<li><a href="">' + jQuery(this).text() + '</a></li>')
});
Is there a way of copying all data attributes from my option tag to the <li>
tags without specifying them by name?
Upvotes: 0
Views: 1284
Reputation: 1
Try this (pattern)
html (e.g.)
<ul class="selections">
<select>
<option data-somedata="something" data-else="something else" value="some value">abc</option>
<option data-somedata="something other" data-else="something else other" value="some value">def</option>
</select>
</ul>
js
function optdata(selector, container, el) {
$.each($(selector), function (index, value) {
$(container).append(
$(el).html("<a href=''>" + $(value).html() + "</a>")
.data($(value).data())
);
return (index != $(value).size())
});
};
optdata($("option"), $(".selections"), "<li>");
jsfiddle http://jsfiddle.net/guest271314/9NvJm/
Upvotes: 1
Reputation: 11498
Just clone the node:
jQuery('.fancy-select .field option').each(function(){
this.parentNode.appendChild(this.cloneNode());
});
Since this is vanilla, and DOM manipulation instead of string manipulation, it will be much faster. And it's nice and simple too.
But you want it to be an <li>
, not an <option>
? You could change the outerHTML, but a faster way is:
jQuery('.fancy-select .field option').each(function() {
var newNode = document.createElement('li');
for (var i = this.attributes.length - 1; i--;) {
newNode.attributes.setNamedItem(this.attributes[i].cloneNode());
}
this.parentNode.parentNode.appendChild(newNode);
});
Instead of cloning the entire node, then doing an expensive outerHTML replacement, it just copies attributes one by one!
Upvotes: 1
Reputation: 1026
It's been a while since I've used jQuery, but my first thought would be to look through the attributes looking for the "data-" ones.
Something like:
jQuery('.fancy-select .field option').each(function(){
var $li = jQuery( '<li><a href="">' + jQuery(this).text() + '</a></li>' );
jQuery.each( this.attributes, function ( item ) {
if ( item.name.substring(0,6) === "data-" ) {
$li.attr( item.name, item.value );
}
} );
jQuery(this).parents('.fancy-select').find('ul').append( $li );
});
A quick Google reveals that data() might make this code much simplier if you are using a newer version of jQuery - https://api.jquery.com/jQuery.data/
jQuery('.fancy-select .field option').each(function(){
var $li = jQuery( '<li><a href="">' + jQuery(this).text() + '</a></li>' );
jQuery.each( jQuery(this).data(), function ( key, value ) {
$li.data( key, value );
} );
jQuery(this).parents('.fancy-select').find('ul').append( $li );
});
Upvotes: 3