Change dropdown selected text without changing the option text
I have an indented dropdownlist, where I have some root options and their children, like below:
Food
Market
Restaurants
Grossery
Clothes
Home
TV
If I select Market, for example, the text in the dropdownlist still indented. Then I did a jQuery function to remove the spaces before the text. It looks like this:
$(function () {
$("select").change(function () {
var str = jQuery.trim($("select option:selected").text());
$("select option:selected").text(str);
})
});
It works. But, if I try to select other option after selected Market, for example, The list looks like this:
Food
Market
Restaurants
Grossery
Clothes
Home
TV
Market lost its indentation. I would like a way to remove the spaces but only in开发者_开发知识库 the selected text shown in the dropdown, but not in the option.
What should I do?
Bit late to the party here...
First of all I've amended your HTML to include a class on each option element to indicate the level to which it should be indented.
<select class="select">
<option value="1" class="level-0">Item 1</option>
<option value="2" class="level-1">Item 1.1</option>
<option value="3" class="level-2">Item 1.1.1</option>
<option value="4" class="level-1">Item 1.2</option>
</select>
I have also written the jQuery to add the required indentation on load, using a string of non-breaking spaces. While this is hardly an elegant solution, it's the only one that will work across all browsers - as you've obviously discovered, OPTION elements are a land CSS forgot. It also includes the logic for the change event to remove/add the padding to the selected items.
While it's not the prettiest code, and I'm sure there are a lot of performance improvements which could be made (hey, it's late here and this was a brain dump as I was intrigued by the question), it works.
var levelClassPrefix = "level-";
var indentationString = " ";
$(".select").each(function() {
padOptions(this);
});
function padOptions(elem) {
$("OPTION", elem).each(function() {
var level = $(this).attr("class").replace(levelClassPrefix, "");
var currentText = $(this).html();
var regex = new RegExp(indentationString , "g");
$(this).html(padText(currentText.replace(regex, ""), level))
});
}
function padText(value, level) {
var output = "";
for (var i = 1; i <= level; i++) {
output = output + indentationString;
}
return output + value;
}
$(".select").change(function() {
padOptions(this);
var selectedOption = $("option:selected", this);
var currentText = selectedOption .html();
var regex = new RegExp(indentationString , "g");
selectedOption.text(currentText.replace(regex, ""));
});
Here is a fiddle to prove the theory
Why not style the indivudual options instead?
Something along these lines:
HTML:
<select>
<option>Food</option>
<option class='sub'>Market</option>
<option class='sub'>Restaurants</option>
<option class='sub'>Grossery</option>
<option>Clothes</option>
<option>Home</option>
<option class='sub'>TV</option>
</select>
CSS:
option.sub { text-indent: 2em; }
Why trim the string? I would add a css class similar to this
select .level0 {}
select.level1 {
text-indent: -1.5em; /* you have to calculate your indentation value */
}
select.level2 {
text-indent: -3em; /* you have to calculate your indentation value */
}
Forge html accordingly
<select>
<option class='level0'>Food</option>
<option class='level1'>Market</option>
<option class='level1'>Restaurants</option>
<option class='level1'>Grossery</option>
<option class='level0'>Clothes</option>
<option class='level0'>Home</option>
<option class='level1'>TV</option>
</select>
and apply the class accordingly. Maybe, I don't know jquery, you have to
$(function () {
$("select").change(function () {
var theclass = $("select option:selected").class();
$("select option:selected").set(class, theClass); // <-- is this jquery??
})
});
精彩评论