Reputation:
I went really long way trying to rewrite select to ul li and style it accordingly. But I'm getting really annoyed with the weight of code and minor annoyances on the way.
So I'm thinking to ditch the idea completely, and just use normal ul li menu and some kind of javascript to make it function like select (for form submission etc).
So is this possible? any example code you can give me?
My concerns is Cross browser compatibility.
Upvotes: 4
Views: 28848
Reputation: 2961
To completely do it as list and with javascript is not the best idea because everyone that has no javascript cannot use this functionality.
Here is a jQuery implementation that has the regular form select fallback (In fact it maps a existing select). You just need to change the first selector and style the list ... the script does the rest.
jQuery( '.woocommerce-ordering select' ).each( function() {
var target = jQuery( this );
var selected = target.find( 'option:selected' ).text();
var map = jQuery( '<div class="selectmap"><span>' + selected + '</span><ul class="selectmap"></ul></div>' ).insertAfter( target );
target.hide();
target.find( 'option' ).each( function() {
var c = jQuery( this );
var u = map.find( 'ul' );
console.log( u );
console.log( c.text() );
jQuery( '<li data-value="' + c.attr( 'value' ) + '">' + c.text() + '</li>' ).appendTo( u );
} );
map.find( 'li' ).click( function() {
map.find( 'span' ).text( jQuery( this ).text() );
target.val( jQuery( this ).attr( 'data-value' ) ).trigger( 'change' );
} );
} );
Upvotes: 1
Reputation: 78981
Lovely idea. I just made one in the fiddle check it out here.
HTML
<ul>
<li class="init">[SELECT]</li>
<li data-value="value 1">Option 1</li>
<li data-value="value 2">Option 2</li>
<li data-value="value 3">Option 3</li>
</ul>
JAVASCRIPT
$("ul").on("click", ".init", function() {
$(this).closest("ul").children('li:not(.init)').toggle();
});
var allOptions = $("ul").children('li:not(.init)');
$("ul").on("click", "li:not(.init)", function() {
allOptions.removeClass('selected');
$(this).addClass('selected');
$("ul").children('.init').html($(this).html());
allOptions.toggle();
});
CSS
ul {
height: 30px;
width: 150px;
border: 1px #000 solid;
}
ul li { padding: 5px 10px; z-index: 2; }
ul li:not(.init) { float: left; width: 130px; display: none; background: #ddd; }
ul li:not(.init):hover, ul li.selected:not(.init) { background: #09f; }
li.init { cursor: pointer; }
a#submit { z-index: 1; }
Upvotes: 19
Reputation: 94101
The basic idea for select replacemenet is this. It generates the basic html and event binding and then you can just style it with css. Check it out. http://jsfiddle.net/elclanrs/H63MU/
var ulSelect = function($select) {
// $select.hide(); <-- Uncomment in production
var $opts = $select.find('option');
return (function() {
var items = '',
html = '';
$opts.each(function() {
items += '<li><a href="#" class="item">'+ $(this).text() +'</a></li>';
});
html =
'<ul class="menu">'+
'<li class="sub">'+
'<a class="sel" href="#">'+ $opts.filter(':selected').text() +'</a>' +
'<ul>' + items + '</ul>'+
'</li>'+
'</ul>';
$(html)
.find('.sub a')
.click(function(e) { // You can attach more events...
e.preventDefault();
var $this = $(this);
$this.parents('.menu').find('.sel').text($this.text());
$opts.eq($this.parent().index()).prop('selected', true);
}).end().insertAfter($select);
}());
};
ulSelect($('#select'));
Upvotes: 0