Jquery UI Select Box
So a couple of weeks ago I was working on a project for a customer and decided I needed to use JQuery UI since I was going to have some popup boxes and wanted some pretty buttons. So I applied JQuery UI no problem, but forgot that it does not have a select box. Yeah I could work around it using Autocomplete or just try and style the select menu up a little with some css, but that would’t be very cross browser consistent.
And then I thought how hard could it be? I mean all I need to do is change the css and put an overlay to hide the drop down arrow. And then I could simply trigger the drop down to show. Something like this…
Basically I would just inspect the jquery css styles and apply some of the classes to the html to make a jquery styles selct box overlay. So if the HTML would look something like this…
<span class=”ui-spinner ui-widget ui-widget-content ui-corner-all”>
<select style=”border:none;” >
<a class=”ui-spinner-button ui-spinner-down ui-state-default ui-corner-right”>
<span class=”ui-button-text”><span class=”ui-icon ui-icon-triangle-1-s”></span></span>
I figured it would be pretty simple to then bind a click event to my <a> tag. Which is a custom drop down arrow using jquery styles.
//bind event to <a> tag
//trigger the select menu click event
Simple enough right? Well in actually there is a huge difference in programmatically triggering an event versus a user’s mouse triggered event. This is probably due to security concerns.
Possible Work Around
So in my searching I came across this entry in stack overflow. One of the recommendations is to change the size of the select menu. This would work if you absolutely position the element and use the wrapper description I gave above.
//trigger the select menu click event
var select = $(this).parent().find(‘select’).first();
Now, this is a very reasonable work around but it has its downsides.
- The drop down list will not look like other JQuery UI elements when the drop down happens. Some css styling might make this work alright though.
- The size attribute can be a little tricky to get right.
- If your select list has 2 elements, making it a size of 2 will give a lot of white space.
- Positioning is tricky
- The <a> tag has to be in-front of the default drop down arrow, but the wrapper which creates the border has to be below the select menu so the default actions work on the select menu. Getting this position correct on all browsers will be tricky, but not impossible.
- The scroll bar is default and cannot be removed (might be able to apply styleing, but this wont be corss 100% browsers).
- In the end, it just doesn’t look quite right. And this is just in Chrome. Figuring out how to tweak styles to be good in all browsers will be a serious pain.
Download the above example here. Please keep in mind, this was only for Chrome and looks bad in some other browsers. You will need to spend some time playing with the css, but in the end you should be able to get this working fairly nice. Also might be a great lightweight solution.
So the above solution is pretty good and super simple. You are using the native select menu with a little bit of a hack. This is great, because all your events for the select menu make sense. But the down side is it has some issues looking polished and the drop down doesn’t really follow the other Jquery UI.
So I needed to resolve these problems. My solution was to combine the css styling used above coupled with Jquery UI AutoComplete Widget.
How will this work…
- Use above css to make something that used JQuery UI css to look nice.
- Use jquery fn to create our own selector function
- Basically we will parse select elements, hide them and create our new css to make things look nice.
- Apply AutoComplete Widget to our styled drop down menu to give the illusion of a select menu.
Why did I go this route?
- Cross browser functionality
- Cross browser looks
- Maintain Jquery UI consistancy in my own widget
- Use Jquery UI widget to hadle the heavy lifting of the select menu. I just need to write an API wrapper for AutoComplete widget to make it do a little more.
In the end this was very simple to implament. About 100 lines of code and very straight forward. The real issues arose in event handling. The AutoComplete Widget API is ok, but frankly a little lacking. So working around its limitation and forcing it into my own needs took a little fiddling.
If you have any questions let me know. The code should be pretty simple to step through on your own, but I would be happy to explain what I can.