We've been hosting most of the big powerhouse Javascript libraries and so far it's been a huge success. However, without YUI!, our collection has been incomplete. Well, I'm not saying that now we're complete and won't add more libraries, just that we're less incomplete than we were... you know what I mean.
Anyways, after getting legal approval (people actually read those licenses), we pushed it live. We are equally as excited about this as Yahoo! and the Javascript community. So let's take a look at how you use it:
<head> <script src="http://www.google.com/jsapi" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> google.load('yui', '2.6.0'); function init() { var loader = new YAHOO.util.YUILoader({ require: ["button", "calendar"], base: "http://ajax.googleapis.com/ajax/libs/yui/2.6.0/build/", onSuccess: function() { // start playing with buttons and calendars! } }); loader.insert(); } google.setOnLoadCallback(init); </script> </head> <body> <div id="calContainer"></div> </body>
That code will load the YUI loader which then loads the button and calendar widgets (combined as one script) and calls onSuccess when they are loaded. If lazy loading scripts isn't your thing, then you can use the dependency configurator to configure the perfect script URL. In my case, to achieve the same results as above, I would use:
We're pleased to announce the addition of local search for China. For users already using the AJAX Search API for local search, you should now be able to search for businesses in China without having to make any changes. Try typing "hotels in Beijing" in your site or app which uses the Google AJAX Search API. You should see some results:
To take advantage of local search functionality, take a look at the AJAX Search API. The samples here are also particularly useful.
If you have any feedback or comments, please drop by our Google Group or new IRC channel (irc details can be found at the bottom of this post).
If you're a Flash nut then you probably know about the SWFObject Javascript library. I'm not, so I didn't. However, since I promised myself I would play with Flex soon I am very happy that a "Flasher" suggested that we add it to our AJAX Libraries API. I took a look at it and found out that it's a great little must-have library!
See, embedding a Flash video on a page is actually more complicated than it should be. You can't just throw a tag on the page with some attributes and expect it to work. In fact, to embed a Flash file there are different methods for different browsers such as using an <embed> vs. <object> as well as setting the parameters for the file.
The SWFObject library simplifies the process so that all you need to worry about is including their Javascript library and using a single method to embed your Flash on the page in a safe, cross-browser manner. It also has a few extra utility functions, such as setting a load event for the Flash object and detecting the user's Flash version.
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...
MooTools v1.2.1 recently got released and we have received the thumbs up from the maintainers to host it, so the bits have been flipped and the pipes are ready to MOOve it over to you guys.
But wait!! Before you get started with 1.2.1, please note that the previous version we are hosting (1.11) and the new version (1.2.1) are incompatible. So as not to break anyone out of the blue (and put them in a bad MOOd) we have frozen the version "1" alias to 1.11. Here's what the aliases look like for MooTools: google.load('mootools', '1') // gives you version 1.11 google.load('mootools', '1.11') // gives you version 1.11 google.load('mootools', '1.2.1') // gives you version 1.2.1 ... you get the picture.
If you have some extra time, stop by the group and show us what you've been up to with MooTools. Happy grazing!
We are pleased to announce two enhancements to our AJAX Language API.
Thanks to the great efforts of the Google Translate team, the API is now able to support 11 additional languages for translation:
Catalan (ca)
Filipino (tl)
Hebrew (iw)
Indonesian (id)
Latvian (lv)
Lithuanian (lt)
Serbian (sr)
Slovak (sk)
Slovenian (sl)
Ukrainian (uk)
Vietnamese (vi)
Also, we'd like to introduce the new POST interface. Among other things, this can be used to send longer URLs by implementing a JavaScript bridge to, for example, Flash or Java using the RESTful interface. For additional information, take a look around our Google Group.
If you have not already done so, please take a moment to familiarize yourself with the AJAX Language API terms.
As the AJAX APIs have undergone tremendous growth and adoption, developers have used these APIs in many new and exciting ways. When things move fast, sometimes details get left behind, and our Terms of Service has not been keeping up with the rapid rate of change. We want to make it clear that you can use these APIs in the context of websites, gadgets, mobile apps, desktop client apps, etc. In response to your feedback, we've dusted off and updated the AJAX Search API terms and the AJAX Language API terms. The primary change was replacing "website" with "Property" that's defined as a "website, application, or other product".
As always, thank you for the feedback. Keep your comments and suggestions coming! We look forward to all of your amazing creations using the Google AJAX APIs.
by Gokul Nath Babu and Anupama Dutta, Software Engineers
We're excited to announce a new addition to the AJAX Language API - the Transliteration API. Transliteration is the process of phonetically converting a word written in one script into another. We launched transliteration on India Labs a year ago to make it easier to type in Indian languages using an English keyboard. Since then, we've integrated this into a number of Google properties, such as orkut scraps, Blogger and search.
Now we'd like to make this functionality available to all websites through our API, which will make it easier for you to add transliteration capabilities to textfields on your webpages. Using this customizable API, you can enable users of your website to type in Hindi, Tamil, Telugu, Kannada and Malayalam. If you're looking for a finer level of control on your web pages, also check out the low-level interface to transliteration, and the font rendering support APIs that we have released.
Please try these out and let us know what you think and how you're using it. We'll also be discussing this API in detail during the Google Developer Day in Bangalore on October 18th. Please register to learn more.
Have you ever gone to a site, looked at the page and wondered, "how did they do that?" Since we launched our 2008 U.S. Election site I am getting lots of questions about that nifty little "page element" sitting in the center of the page. Everyone wants to know, "how did you guys do that? how did you pack so much valuable and tightly scoped information in such a small amount of space?" Take a look at the page element below, play around with it a little bit and when you are ready, continue reading.
If you know how to use Firebug, then you can see that behind each tab (Election News, YouTube, etc.), there is a simple AJAX APIs JSON-P request. For some tabs the base operation is a Google Web Search or Custom Search, for others a Google News Search, and for others, a simple YouTube Search. The AJAX APIs work really well in this mode where the page author determines both the query and search options, as well controlling the end-to-end UI and resulting user experience.
But back to the tabs, and to answer the questions, "How'd they do that?", I will walk through each tab and show you the AJAX API requests that are used to generate the results for this page element:
First, the Election News tab. For this tab, we simply target News Search with the name of the candidate and a query addition of unitedstates_uselections. Something like this:
Next, the YouTube tab. For this tab, we use the Video Search system to directly target each candidate's YouTube Channel (e.g.,ytchannel:barackobamadotcom), render the results with a simple fade in effect, and then bind each result click to a dynamically created player. Very simple stuff. Check out the url we use to grab the results:
Next, the Blog Posts tab. For this tab, we built a little Custom Search Engine, populating it with several of the top political blogs. The search then becomes the name of the candidate plus a &cx= argument to indicate the Custom Search Engine to use for the search:
See what I mean? Take the queries above, slap on a little UI, and any application can take Google News, Custom Search, Web Search, YouTube, etc. and create a very tight little customized search experience...
The Quotes tab is very cool. Instead of just searching for News articles, this tab searches for news articles that contain quotes spoken by one of the candidates. Again, a simple News search with a &qsid= argument to scope to quotes for a particular candidate and we have what we need:
Finally, the News by State tab. This one has two things going on. First there is the state selector control. We use the just launched google.loader.ClientLocation property to determine the user's current location. Then, we simply use this location to form a geo scoped query for the candidate's name in the politics category, scoped with a geo restrict using &geo=. Something like this:
So there you have it. Take the above collection of page author defined queries, mix in a few hours of coding, throw in some product managers, a handful of lawyers, a few PR folks, and you have a clever little page element that delivers tons of very focused information.
To learn more about the APIs used in this page element, visit the AJAX Search API and AJAX Feed API documentation. To learn more about Custom Search Engines, check out the recently updated developer guide. To discuss the APIs with us and the community, visit us on our developer forum.
p.s. - If you really like that page element and have to have it on your site, you can iframe it in, or just include our JavaScript directly:
Have you ever written an app and wanted to do something simple like center a map on your user's location? Consider a simple little map gadget. Wouldn't it be nice to be able to center that map on your user's home country, state, or city, instead of just arbitrarily centering on San Francisco or Australia?
Take a look at our new "API". Actually, it's not really an API, more like a simple object property called google.loader.ClientLocation.
After loading any one of our AJAX APIs, the system will attempt to geo-locate the client based on the client's IP address. If we have a valid mapping for the IP address, the google.loader.ClientLocation property is populated with coarse grained coordinates, the user's country, region, and city. The mapping isn't perfect, but it's pretty good, and is definitely usable as a way of setting smart defaults or adding a small amount of location awareness to your app.
Here is a little code sample that demonstrates the use of google.loader.ClientLocation:
/** * Set the currentState_ and currentCountry_ properties based on the client's * current location (when available and in the US), or to the defaults. */ InTheNews.prototype.setDefaultLocation_ = function() { this.currentState_ = this.options_.startingState; if (google.loader.ClientLocation && google.loader.ClientLocation.address.country_code == "US" && google.loader.ClientLocation.address.region) {
// geo locate was successful and user is in the states. range check // the region so that we can safely use it when selecting a state // level polygon overlay var state = google.loader.ClientLocation.address.region.toUpperCase(); if (InTheNews.stateNames[[]state]) { this.currentState_ = state; } } this.currentCountry_ = "US"; }
To witness this code in action, check out our 2008 U.S. Election page. If you click on the "News by State" tab, you will either see political news, for the current candidate, scoped to your state, OR if we don't have a mapping for your IP address, you will see the same thing only scoped to the state of California.
Now for the good stuff... If you like this simple IP to location mechanism, wait until you see what the Gears Team announced. They have a killer version of this functionality that is able to pinpoint a user's location using IP, cell-ID, GPS, and coming soon, WiFi. This is definitely a step up in terms of both functionality and accuracy.
As always, feel free to leave us feedback, ask questions, or vote for some new features by visiting our developer forum.