Tuesday, November 4, 2008

Styling the SearchControl Guest Post

So, the other day, I was asked by the AJAX APIs dev team if I'd like to write a guest blog post, but they didn't tell me what to write about. I thought about telling you how the AJAX APIs revolutionized how I think about life, design websites, and slice bread, but then I realized that I buy my bread pre-sliced. So I started going back through the group looking for common questions or themes to threads, and I realized that a huge portion of the questions asked can be summed up like this: "How do I style the google.search.SearchControl?" For instance, how would one make it so that only a result's title and URL appear (i.e., the description is not visible), or even just the URL? What if you want to change some of the default colors? What if you, being the stylish computer geek that you are, want to make your SearchControl into a 24th century Starfleet console to fit in with that first-season spandex Star Trek: The Next Generation uniform you're wearing right now?

Well, you're in luck! Using Mozilla Firefox with the Firebug add-on installed (an absolute must-have for any web developer, by the way), you can do all this and more simply by inspecting the structure of the default search control and taking advantage of the fact that almost every one of its individual elements is given at least one className that can be used with Cascading Style Sheets to apply different style rules. We've put together a spectacular video to provide a very brief overview of using Firefox and Firebug to inspect the structure (and tinker with) the structure of the control.


For even more information on how you can do more with Firefox and Firebug, you'll want to check out Ben Lisbakken's excellent tutorial, which includes even more video! And for good measure, we've included the control's structure (complete with a few of my own comments) below:

<div class="gsc-control">
<!-- FYI: This form is the same as the google.search.SearchForm -->
<form class="gsc-search-box">
<table class="gsc-search-box">
<tbody>
<tr>
<td class="gsc-input">
<!-- This next input is the search box itself -->
<input class="gsc-input/>
</td>
<td class="gsc-search-button">
<!-- This next input is the search button itself -->
<input class="gsc-search-button"/>
</td>
<td class="gsc-clear-button">
<!-- This next div is the clear button (i.e., the little x) -->
<div class="gsc-clear-button"/>
</td>
</tr>
</tbody>
</table>
<table class="gsc-branding">
<tbody>
<tr>
<td class="gsc-branding-user-defined"/>
<td class="gsc-branding-text">
<div class="gsc-branding-text">powered by</div>
</td>
<td class="gsc-branding-img">
<img class="gsc-branding-img"/>
</td>
</tr>
</tbody>
</table>
</form>
<!-- In tabbed mode, this is where the tabs will appear; in stacked mode, this will be absent! -->
<div class="gsc-tabsArea">
<!-- The following div would be the active tab -->
<div class="gsc-tabHeader gsc-tabhActive"/>
<!-- These spacer divs will appear AFTER every tab to do exactly what their className would imply -->
<div class="gs-spacer"/>
<!-- And this one would be an inactive tab -->
<div class="gsc-tabHeader gsc-tabhInactive"/>
<div class="gs-spacer"/>
</div>
<div class="gsc-resultsBox-visible">
<!-- The next divs contain the actual results. The classes in square brackets are ONLY present in TABBED mode -->
<!-- This would be the active tab -->
<div class="gsc-resultsRoot [gsc-tabData gsc-tabdActive]">
<table class="gsc-resultsHeader">
<tbody>
<tr>
<td class="gsc-twiddleRegionCell gsc-twiddleRegion-opened">
<div class="gsc-twiddle">
<!-- This next div will contain your searcher's title or label (e.g., Local), but it won't be visible in tabbed mode -->
<div class="gsc-title"/>
</div>
<!-- This next div will contain your search's estimated result count, but it's invisible in tabbed mode, too! -->
<div class="gsc-stats">
<!-- This is the selector that chooses 1, 4, or 8 visible results. Please note that only ONE of the options in square brackets will be visible -->
<div class="gsc-results-selector [gsc-one-result-active OR gsc-more-results-active OR gsc-all-results-active]">
<div class="gsc-result-selector gsc-one-result"/>
<div class="gsc-result-selector gsc-more-results"/>
<div class="gsc-result-selector gsc-all-results"/>
</div>
</td>
<td class="gsc-configLabelCell">
<!-- This next span will only be present if the searcher has configuration options -->
<!-- Also, it will only have ONE of the options in square brackets, depending on whether or not the configuration form is visible or not -->
<span class="gsc-configLabel [gsc-twiddle-closed OR gsc-twiddle-opened]"/>
</td>
</tr>
</tbody>
</table>
<!-- This next div is the configuration form for a searcher. It is only present if the searcher has configuration options -->
<!-- The exact className of the config form will depend on the type of searcher. So you'll only have ONE of the options below. You can probably figure out which one your searcher will have -->
<!-- By the way, I have no idea why it's gsc-locationConfig instead of gsc-localConfig :) -->
<div class="gsc-config [gsc-locationConfig OR gsc-videoConfig OR gsc-blogConfig OR gsc-newsConfig OR gsc-patentConfig]">
<!-- The exact content of the config div will vary depending on your searcher's options -->
<!-- Use Firefox with Firebug to explore the possibilities here! -->
</div>
<div class="gsc-results [gsc-localResult OR gsc-webResult OR gsc-blogResult OR gsc-newsResult OR gsc-imageResult OR gsc-bookResult OR gsc-patentResult OR gsc-videoResult]">
<!-- This is your FIRST actual search result. All results will follow this pattern -->
<!-- Please note, again, that only ONE of the classNames in the square brackets will apply, depending on the searcher -->
<div class="gsc-result [gsc-localResult OR gsc-webResult OR gsc-blogResult OR gsc-newsResult OR gsc-imageResult OR gsc-bookResult OR gsc-patentResult OR gsc-videoResult]">
<!-- The contents of this div will be the same as outlined in the documentation for your searcher's results -->
</div>
<div class="gsc-expansionArea">
<!-- This is where the REST of your search results show up, again following the same pattern as above -->
</div>
</div>
</div>
<!-- And the inactive one -->
<div class="gsc-resultsRoot [gsc-tabData gsc-tabdInactive]">
<!-- All the rest of the structure of this is the same as above -->
</div>
</div>


So, thanks to Firefox and Firebug, we have access to the SearchControl's structure. Now we can get to work making our control look like one of those 24th-century consoles that we see every day on the starship Enterprise! To get this done, we're going to start with the stock "Hello, world" example for the AJAX Search API. Then we're going to remove the style element that comes with it and plug in a new external stylesheet below the inline script that initializes the whole thing.

Once that's done, we need to (a) change a bunch of colors; (b) rework a number of background images; and (c) open a small hole in the space-time continuum to get ourselves a starship console to put it all on. Okay, so that last one isn't exactly possible, but we can do all the rest with a little CSS. And the whole thing, put together, looks like this.

Now, you will notice that a number of those rules have complex selectors (e.g., .gsc-resultsHeader td.gsc-twiddle-opened...). This is because Google's default CSS is rather specific in places. And it's also why Firefox with Firebug is so very important. It really makes the whole process almost painless.

So there you have it: style. Well, for your SearchControl, at least. Next time, we'll talk about why the Starfleet quartermaster abandoned spandex.

Until then, happy styling!

Jeremy R. Geerdes
Generally Cool Guy
jrgeerdes@gmail.com

p.s. What cool custom designs have you come up with? Share them in the Google Group! Ben Lisbakken has promised some Google schwag for interesting designs...

Link - from Google AJAX Search API Blog
Related From Google Blogs:
How the US has voted since 1980
Create and embed presentations in your LinkedIn profile
Interesting ways to use Docs in the Classroom
Almost new in Labs: SMS Text Messaging for chat

No comments: