As already said, the option
is an element that does not accept images. I have developed a jQuery code with CSS where you can replace the select
by an HTML list that will simulate select.
The code hides the select and creates instead the HTML with the list simulating the options, where you can place an image next to the text.
It works as follows:
Add in select the class .fake-sel
:
<select class="fake-sel">
<option>Prima</option>
<option>Piana</option>
<option>Legno1 foo foo</option>
</select>
Javascript will identify select by this class and build HTML instead. The code I developed can be used in more than one select, just add the class in the selects you want to customize with images in the options.
You will see in the code an array this way:
var imgs_ = [
[
'https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg',
'https://oc2.ocstatic.com/images/logo_small.png',
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg'
]
];
Note that this array imgs_
has another array where at each position has a path to the images. You only need to put in each position the path of the images relative to that option. For example, if you use more than one select, it would look like this:
<select class="fake-sel">
<option>Prima</option>
<option>Piana</option>
<option>Legno1 foo foo</option>
</select>
<select class="fake-sel">
<option>Opção 1</option>
<option>Opção 2</option>
</select>
And the array like this:
var imgs_ = [
[
'https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg',
'https://oc2.ocstatic.com/images/logo_small.png',
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg'
],
[
'https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg',
'https://oc2.ocstatic.com/images/logo_small.png'
]
];
Note that the array has two sub-arrays, each of which refers to a select in the order, and the second select has two options, so the second array will have two items with the image paths.
In short, just add the class .fake-sel
in select you want to change and adjust the array imgs_
as explained above, and add the script below:
<script>
$(function(){
var sels = $(".fake-sel");
var imgs_ = [
[
'https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg',
'https://oc2.ocstatic.com/images/logo_small.png',
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg'
]
];
sels.each(function(x){
var $t = $(this);
var opts_ = '', first;
$t.find("option").each(function(i){
if(i == 0){
first = "<li><img src='"+ imgs_[x][i] +"'>"+ $(this).text() +"</li>";
}
opts_ += "<li"+ (i == 0 ? " class='ativo'" : '') +"><img src='"+ imgs_[x][i] +"'>"+ $(this).text() +"</li>";
});
$t
.wrap("<div class='fake-sel-wrap'></div>")
.hide()
.parent()
.css("width", $t.outerWidth()+60)
.append("<ul>"+ first+opts_ +"</ul>")
.find("ul")
.on("click", function(e){
e.stopPropagation();
$(this).toggleClass("ativo");
})
.find("li:not(:first)")
.on("click", function(){
$(this)
.addClass("ativo")
.siblings()
.removeClass("ativo")
.parent()
.find("li:first")
.html($(this).html());
$t.val($(this).text());
});
});
$(document).on("click", function(){
$(".fake-sel-wrap ul").removeClass("ativo");
});
});
</script>
Regarding the size of the images and other changes (colors etc.) I will explain further below. For now see code working with only 1 select:
$(function(){
var sels = $(".fake-sel");
var imgs_ = [
[
'https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg',
'https://oc2.ocstatic.com/images/logo_small.png',
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg'
]
];
sels.each(function(x){
var $t = $(this);
var opts_ = '', first;
$t.find("option").each(function(i){
if(i == 0){
first = "<li><img src='"+ imgs_[x][i] +"'>"+ $(this).text() +"</li>";
}
opts_ += "<li"+ (i == 0 ? " class='ativo'" : '') +"><img src='"+ imgs_[x][i] +"'>"+ $(this).text() +"</li>";
});
$t
.wrap("<div class='fake-sel-wrap'></div>")
.parent()
.css("width", $t.outerWidth()+60)
.append("<ul>"+ first+opts_ +"</ul>")
.find("ul")
.on("click", function(e){
e.stopPropagation();
$(".fake-sel-wrap ul")
.not(this)
.removeClass("ativo");
$(this).toggleClass("ativo");
})
.find("li:not(:first)")
.on("click", function(){
$(this)
.addClass("ativo")
.siblings()
.removeClass("ativo")
.parent()
.find("li:first")
.html($(this).html());
$t.val($(this).text());
});
});
$(document).on("click", function(){
$(".fake-sel-wrap ul").removeClass("ativo");
});
});
.fake-sel{
display: none;
}
.fake-sel-wrap{
display: inline-block;
position: relative;
height: 46px;
}
.fake-sel-wrap ul{
margin: 0;
padding: 0;
list-style: none;
border: 1px solid #ddd;
position: absolute;
top: 0;
left: 0;
font-family: Arial;
font-size: 14px;
width: 100%;
height: 100%;
overflow: hidden;
cursor: default;
background-color: white;
}
.fake-sel-wrap ul li{
padding: 3px;
line-height: 1em;
display: flex;
align-items: center;
}
.fake-sel-wrap ul li:nth-child(1){
border-bottom: 1px solid #ddd;
}
.fake-sel-wrap ul li.ativo{
background-color: blue;
color: white;
}
.fake-sel-wrap ul li:not(:nth-child(1)):not(.ativo):hover{
background-color: #ddd;
}
.fake-sel-wrap ul.ativo{
overflow: auto;
height: auto;
}
.fake-sel-wrap ul li img{
width: 40px;
height: 40px;
margin-right: 10px;
}
/* ESTE É O CSS DA SETINHA */
.fake-sel-wrap ul li:nth-child(1)::after{
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 6px 5px 0 5px;
border-color: #000000 transparent transparent transparent;
margin-left: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="fake-sel">
<option>Prima</option>
<option>Piana</option>
<option>Legno1 foo foo</option>
</select>
When you click on an option, the hidden select is also changed according to the option clicked, so you can send by form quietly, just put a name
:
<select class="fake-sel" name="coloque um nome">
<option>Prima</option>
<option>Piana</option>
<option>Legno1 foo foo</option>
</select>
Regarding the size of the images, see that I put a square size of 40x40 pixels. You can use the size you want, just make some adjustments to the CSS and a part of the script.
In the CSS:
.fake-sel-wrap{
display: inline-block;
position: relative;
height: 46px;
}
Where has height: 46px;
above, is the sum of the image height +6 pixels referring to the padding of 3px above below the <li>
. If you are going to use a 20px image height, for example, change the 46px
for 26px
.
Here the image dimensions are defined:
.fake-sel-wrap ul li img{
width: 40px;
height: 40px;
margin-right: 10px;
}
If you want another size, just change the width
and the height
(without forgetting to adjust the height
class .fake-sel-wrap
as explained above).
In the JS:
In the script, you will only adjust a value according to the size of the image you set in CSS, in this part:
.css("width", $t.outerWidth()+60)
Where has 60
, refers to the image width +20 pixels, ie if you are going to use an image of 20px
, just change the 60
for 40
.
See an example now with 2 selects:
$(function(){
var sels = $(".fake-sel");
var imgs_ = [
[
'https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg',
'https://oc2.ocstatic.com/images/logo_small.png',
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg'
],
[
'https://oc2.ocstatic.com/images/logo_small.png',
'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg'
]
];
sels.each(function(x){
var $t = $(this);
var opts_ = '', first;
$t.find("option").each(function(i){
if(i == 0){
first = "<li><img src='"+ imgs_[x][i] +"'>"+ $(this).text() +"</li>";
}
opts_ += "<li"+ (i == 0 ? " class='ativo'" : '') +"><img src='"+ imgs_[x][i] +"'>"+ $(this).text() +"</li>";
});
$t
.wrap("<div class='fake-sel-wrap'></div>")
.parent()
.css("width", $t.outerWidth()+60)
.append("<ul>"+ first+opts_ +"</ul>")
.find("ul")
.on("click", function(e){
e.stopPropagation();
$(".fake-sel-wrap ul")
.not(this)
.removeClass("ativo");
$(this).toggleClass("ativo");
})
.find("li:not(:first)")
.on("click", function(){
$(this)
.addClass("ativo")
.siblings()
.removeClass("ativo")
.parent()
.find("li:first")
.html($(this).html());
$t.val($(this).text());
});
});
$(document).on("click", function(){
$(".fake-sel-wrap ul").removeClass("ativo");
});
});
.fake-sel{
display: none;
}
.fake-sel-wrap{
display: inline-block;
position: relative;
height: 46px;
}
.fake-sel-wrap ul{
margin: 0;
padding: 0;
list-style: none;
border: 1px solid #ddd;
position: absolute;
top: 0;
left: 0;
font-family: Arial;
font-size: 14px;
width: 100%;
height: 100%;
overflow: hidden;
cursor: default;
background-color: white;
}
.fake-sel-wrap ul li{
padding: 3px;
line-height: 1em;
display: flex;
align-items: center;
}
.fake-sel-wrap ul li:nth-child(1){
border-bottom: 1px solid #ddd;
}
.fake-sel-wrap ul li.ativo{
background-color: blue;
color: white;
}
.fake-sel-wrap ul li:not(:nth-child(1)):not(.ativo):hover{
background-color: #ddd;
}
.fake-sel-wrap ul.ativo{
overflow: auto;
height: auto;
}
.fake-sel-wrap ul li img{
width: 40px;
height: 40px;
margin-right: 10px;
}
/* ESTE É O CSS DA SETINHA */
.fake-sel-wrap ul li:nth-child(1)::after{
content: '';
width: 0;
height: 0;
border-style: solid;
border-width: 6px 5px 0 5px;
border-color: #000000 transparent transparent transparent;
margin-left: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="fake-sel">
<option>Prima</option>
<option>Piana</option>
<option>Legno1 foo foo</option>
</select>
<select class="fake-sel">
<option>Piana</option>
<option>Legno1 foo foo</option>
</select>
What this image would look like was missing: an icon on the left and a text on the right, a background covering the whole option, etc...
– Sam
Really missed, I added now, would be an icon even left.
– Dorathoto