December 25th in Articles by Schalk .

jQueryDocs Documentation Search Chrome Extension Released

A day or so ago I wrote a post about the extensions for developers already available for those running the developer or beta channel versions of Chrome. In  this post I also mentioned the extension that allows you to search the PHP docs. From the time I new about the extensions I wanted to write an extension and seeing the PHP one I thoughts, heck, why not write one for searching the jQuery docs as this is something I do very often. I took the comments on the PHP extension to heart and tried to expand on the functionality of the PHP extension. Today I will be releasing my first extension for Chrome and below is the process I followed to create the extension.

First off, if you are thinking of writing an extension, reading the overview on extensions is worth your time. As mine is not page specific I went the browser action root. Whichever way you choose to go, the first step is to write your Manifest file which is in the form of a .json file and hence a JSON style syntax:

{
  "name": "jQuery Docs",
  "version": "1.0",
  "description": "Simple extension that allows you to search the jQuery docs.",
  "permissions": ["http://docs.jquery.com/"],
  "browser_action": {
    "default_title": "jQuery Docs Search",
    "default_icon": "images/icon.png",
    "popup": "jquery_search.html"
  }
}

So in the manifest file we are providing Chrome with the required information it needs to know about our extension. There is the obvious name of your extension, the version. The version is actually very important as Chrome will use this version number to determine whether a newer version of the plugin is available and then do a silent auto update if the currently installed version number is older then the version on the extension ‘gallery’. Next we have the description which explains to prospective users what your extension aims to do.

I next have a permissions entry which I do not really think I need for my specific extension but I left it in there for good measure. You can read more about what this is used for on the extensions developer docs. As I mentioned earlier I developed this extension as a browser action and as such have the browser action entry. In here you provide the default title, which will be the tooltip that will be displayed when someone hovers over the extensions icon, this icon itself, which is a 19x19px image, and then the HTML document to open when the icon is clicked on. With that we are ready to develop the functionality of our extension.

Before I start looking at the code I must admit that this is the first very beta version of the extension ;) There are some bugs and some improvements I want to make to the functionality as well as to the way the code is organized. With that out the way, let’s look at the HTML file. We start off with a very bare bones HTML file:

<html>
    <head>
    </head>
    <body>
    </body>
</html>

Next we add the code for our starting HTML interface inside the body tags:

<div id="wrapper">
        	<p><img src="images/jquery_logo.png" width="188" height="54" alt="jQuery logo" /></p>
            <form name="docssearch" id="docssearch" method="get" action="http://docs.jquery.com/Special:Search">
                <fieldset>
                    <legend>
                        Enter Searh Query
                    </legend>
                    <label for="query">
                        Query:
                    </label<input type="text" name="query" id="query" />
                    <button type="submit" name="go" id="jq-searchGoButton">
                        <span>Go</span>
                    </button>
                </fieldset>
            </form>
</div>

With this we have our jQuery logo at the top followed by our form that will accept the query string the user wants to search the docs with. Next we add some CSS to make the default layout look better. Inside the head of the HTML page add the following:

<style>
body {
    margin:0 auto;
    min-width:357px;
    height:70px;
    overflow-x:hidden;
}
#wrapper {
    padding:5px;
}
#docssearch
{
	margin-bottom:7px;
}
#docssearch legend {
    display: none;
}

#docssearch button {
    background: url(images/icon_searchglass.png) 0 0 no-repeat;
    _background-image: url(images/icon_searchglass.gif);
    position: relative;
    width: 35px;
    height: 35px;
    position: absolute;
    left: 190px;
    top: 67px;
    border: 0;
    cursor: pointer;
    font-size: 1.1em;
}

#docssearch button span {
    position: absolute;
    left: -9999999px;
}

#docssearch button:hover {
    background-position: 0 -36px;
}

img {
    margin: 5px;
    vertical-align: middle;
}

That is a lot of CSS, but in general it get’s the initial view set-up with the jQuery logo and then the search field. On the search field I lent some of the styles from the jQuery website, as I did in other places, to make the extension seem like a natural extension from the jQuery website (I hope John and them are fine with it). I also include the jQuery CSS reset script to ensure the jQuery styles work as expected:

<link rel="stylesheet" href="http://static.jquery.com/files/rocker/css/reset.css" />

The most important aspects to look at is the JavaScript. First stop is to include jQuery:

<script src="jquery.min.js" type="text/javascript">

Next is the script:

$(document).ready(function(){

$("#docssearch").submit(function(){
var searchQuery = $(":input").val();
$.get("http://docs.jquery.com/Special:Search?ns0=1&search=" + searchQuery + "&go=", addData);
return false;
});

});

var addData = function(data) {
$("#results").html(data);
clickListener();
}

var clickListener = function(){
$("a").bind("click", function(){
var targetLocation = $(this).attr("href");
loadNextPage(targetLocation);
return false;
});
}

var loadNextPage = function(targetLocation) {
$.get("http://docs.jquery.com" + targetLocation, addData);
}

With the way content is loaded I had to think carefully when to call certain functions and ended up with the above. Once the document is loaded everything is ready and we wait for the user to enter the search query and submit. On submit, we intercept the default behavior and handle the for submission with the following:

$("#docssearch").submit(function(){
var searchQuery = $(":input").val();
$.get("http://docs.jquery.com/Special:Search?ns0=1&search=" + searchQuery + "&go=", addData);
return false;

With the above we store the search query in a variable and then include it in our GET request to the jQuery website. We also register a callback that will use the data once the call has completed:

var addData = function(data) {
	$("#results").html(data);
	clickListener();
}

All the addData call will do is populate our ‘results’ div with the content returned from the call and then call the clickListener method. This method is actually very important as clicking on links in the resulting page goes nowhere and we therefore have to bind a click event on al anchor links and handle the clicks ourself. Before we look at clickListener, just a quick note about the data returned from the jQuery website and how that data is handled inside the extension window.

The content returned from the jQuery website is the entire HTML page as one would see it when searching but, for the extension I do not want to display all of this so, with a little CSS magic we get rid of the content we do not want to show:

#powersearch, #jq-interiorNavigation, #jq-header, #jq-primarySearchForm, #jump-to-nav, #jq-footer {
      display: none;
}

Next let’s look at the clickListener method:

var clickListener = function(){
    $("a").bind("click", function(){
        var targetLocation = $(this).attr("href");
        loadNextPage(targetLocation);
        return false;
    });
}

There is nothing funny in this script but, as mentioned earlier, without this, the extension would not be of much use. Once we know that all the data has been added to the document we can bind the click event on all anchor links in the page. Once a click then happens, we use $(this) to get access to the link that triggered the event and then read it’s href attribute. The href attributes are by default relative links and do therefore not include the domain which, on the actual website, is no problem but, for the extension, it does pose a problem so in the loadNextPage function we have to remedy this by appending the domain to the front of the href attribute we read:

var loadNextPage = function(targetLocation) {
	$.get("http://docs.jquery.com" + targetLocation, addData);
}

And that is it for our JavaScript. We are now basically in a ‘loop’ that will ensure that our data and that the links work effectively. The loop consists of the user submitting a query, getting the input and sending it of to jQuery, calling addData as the call back, adding the data to the page and then calling the clickListener. Once a link is clicked on, we call loadNextPage, which will request our data and again register addData as our call back and the whole process starts again.

And that then is that, there are some extra CSS but, it is basically just CSS I used from the jQuery website and mentioned before to keep a consistent look and feel. There are surely some bugs in the current version and I do have some ideas of how to enhance the current version but, if you are running a developer or beta channel version of Chrome and want to try jQueryDocs Search out, you can go hear and install it. All the code is also available on Github and you are more then welcome to either fork it and create a search extension for your favorite language or framework or, jump in and help improve jQueryDocs Search. I look forward to reading everyone’s comments and seeing how this extension evolves.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • HackerNews
  • Identi.ca
  • muti
  • Reddit
  • Slashdot

7 Comments

  • dehuc
    January 7, 2010
  • Scooter uitlaten
    January 8, 2010
  • Kiana Corsey
    January 9, 2010
  • National lottery syndicate
    January 13, 2010
  • Aurelio Kessel
    January 16, 2010
  • Freda Mcgarr
    January 21, 2010
  • Neven
    February 3, 2010

Leave A Comment.