Setting the style of the items shown by the AutoCompleteBehavior
The AutoCompleteBehavior is not as good as it could be…at least, not in the July CTP version. Many have already asked for a way to change the style of the generated elements which are shown by the list. Most guys try to help by saying that you have to write a new behavior or change the current one so that the items have the desired styles applied to it. Though these solutions do work, you really don’t have to go that far to get the desired results.
First, we need to understand what happens when we use that behavior. The AutoCompleteBehavior is a complex behavior which reuses the PopupBehavior to show the results returned by the web service method used to make the call. By default, it creates a div control which serves as a container (I’ll call it top element to distinguish from the other ones used by the control). As you might expect, the PopupBehavior is attached to this control. Each of the strings returned from the web service method is placed inside a div and then are added to the child nodes collection of the top element control. It’s also important to understand that the several style properties of all the divs are set to some default values (which are adequate to most situations).
What most guys still haven’t seen is that you can specify a control which is used as the top element. To achieve that, you must resort to the completionList property. What are the advantages of specifying your own top element? Well, based on what I’ve told you before, you can surely understand that by explicitly indicating that element you can specify a css rule which might just be enough to get the expected results. To illustrate this, let’s start by saying that I’ve added a div to the page and set its ID to test (btw, you should note that if you’re using the AutoCompleteExtender, this element must have the runat=”server”). You can set it as the top element container by setting the completeList property of the behavior to text (or the DropDownPanelID property, if you’re using the AutoCompleteExtender).
Now I’ve just decided that each element presented by the list should be underlined. I can achieve this by writing the following CSS rule:
<style type="text/css">
#test div
{
text-decoration: underline;
}
</style>
What the previous rules says is that the text of all the DIV child nodes of the element whose ID is set to test should be underlined. This will work because the AutoCompletebehavior will use the test element as its top element container where all the items returned from the web service will be shown.
Unfortunately, this doesn’t work in all the situations because the AutoCompleteBehavior initializes several style properties of the DIV elements which are used to present all the items returned by the web service. For instance, let’s say that I want the text to be right aligned (something that might be necessary in some cultures). You can try setting the property with another simple rule, but it’ll be overridden by the Javascript code used to create the element that is going to be shown to the user. The easiest way to get the desired results is to make sure that the CSS rule prevails over the style assignment performed through Javascript code. To achieve this, you add the !important special value in front of your rule. Though you should use this value carefully, it really is applicable in this case. So, if you want to have each item underlined in blue and right aligned, then this should do it:
<style type="text/css">
#test div
{
text-decoration: underline;
text-align: right !important;
color: blue !important;
}
</style>
I’ve tested this with IE7 and Firefox. Since I don’t have IE6, I can’t really say that it doesn’t work there. Let’s assume that it doesn’t (at least, that’s what I expect)…well, there’s still a solution for you: handle the non-compliant onresize event of the top element container (which is only fired by IE) and go through all the child nodes and set the correct style properties. Here’s the code:
<div id="test" runat="server" class="test" onresize="updateStyle(this);"></div>
function updateStyle(obj)
{
for( var i = 0; i < obj.childNodes.length; i++ )
{
obj.childNodes
.style.color = "blue";
obj.childNodes
.style.textAlign = "right";
}
}
Hope this helps.