views:

291

answers:

3

I have a page that contains numerous <select> elements. What I'm trying to achieve is to ensure that if a <select>'s selected <option> has a class called italic, then the <select> then has the italic class added (i.e. jQuery.addClass('italic')). If it doesn't, then the italic class is removed from the <select> to ensure other <option> elements are displayed correctly (i.e. jQuery.removeClass('italic')).

What I'm noticing with most of my attempts is that either all the <select> have the italic class or that the italic class isn't being removed accordingly.

Since I'm unsure my choice in selectors and callback logic are particularly sound or good practice in this instance (as I've been frustratingly trying to make it work) I've decided not to include the code I used in previous attempts. Instead, refer to this small HTML & CSS example:

.italic {
    font-style: italic;
}

<select id="foo" name="foo" size="1">
  <option value="NA" selected="selected"> - Select - </option>
  <option value="1">Bar</option>
  <option value="2">Fu</option>
  <option value="3">Baz</option>
</select>

Also, I am aware that not all browsers support CSS styling of <select> and <option>. The related J2EE web application will only ever be accessed via Firefox under a controlled environment.

A: 

The best you can do is something like this:

$("select").change(function() {
    if ($("select option:selected").hasClass('italic')) {
        $("select").addClass('italic');
    }
    else {
        $("select").removeClass('italic');
    }
});

$("select").mousedown(function() {
    $("select").removeClass('italic');
});

As you've said applying the class to the select applies it the whole control and not just to the text box. There is nothing you can do about this. What I suggest is to capture the mousedown event and remove the styling. This way when you look at the options, your styles will appear. This has two disadvantages:

  • While selecting the text box will not appear with italic fonts
  • If you use the keyboard to select, this won't work. You need to process more event for this.

If this is too important to you, I recommend that you use a custom made select control (implemented using jQuery and an unordered list or a table for example) over which you could control the whole appearance.

kgiannakakis
Your solution will not work if there are two or more select boxes available on the page. If one of the select boxes has italic option selected all other will get class italic! Moreover, it's a big overkill to use everywhere selectors instead of DOM instances.
nemisj
The jQuery selector was just an example. Change it with something (a class or an id) that suits you.
kgiannakakis
@kgiannakakis:Isn't it, too much changes (6 lines of code) only to make solution work ? What about code abstraction?
nemisj
+2  A: 

In case user changes option in your select "foo", function will apply or remove italic based on the selected option.

$("select").change(function(e) {
    var select = e.target;
    var option = select.options[select.selectedIndex];
    if ($(option).hasClass('italic')) {
        $(select).addClass('italic');
    } esle {
        $(select).removeClass('italic');
    }
});
nemisj
I'm attempting to avoid individually adding a change event for each different <select> element as this is to be implimented in to a very large J2EE web application that I have created, consisting of a large number of these cases. Using the *id* attribute as the selector in this situation does not seem to be the best solution. However, I'm interested in the API of *e*. Do you have a link for such a thing?The main problem is that almost all of the <select> elements I use have an "instruction" as the first <option>, so I need it to be controlled.Thanks.
Alasdair
Nevermind, I found the API and it doesn't appear to offer any obvious oppertunities that I haven't already tried.
Alasdair
@Alasdair:There is not way to avoid change events if you want your page to work dynamically and interactively for the user.
nemisj
Sorry, you misunderstood me. I'm looking to avoid manually setting a change event for each <select> element's *id* attribute. This is my dilema. A single selector would be perfect, if I can work out the logic in the callback function.
Alasdair
A: 

nemisj's answer handles the behaviour perfectly (except for the typo 'esle' instead of 'else') - you just need some better CSS to finish it:

select.italic {
    font-style:italic;
}

select option {
    font-style:normal;
}    

select option.italic {
  font-style:italic;
}

The issue with the styling is that options will take on the styling on their parent select, unless otherwise specified. So, specifically overriding the default option with font-style:normal; then restyling option.italic with font-style:italic; will do the trick.

Here's a test page showing it working with multiple selects: http://www.spookandpuff.com/examples/selectStyles.html

Beejamin
As an aside, using a non-visual class such as 'highlighted' or 'featured' would be a better choice than 'italic'.
Beejamin