Archive for the 'Javascript' Category

AJAX.Search Wordpress Plugin

I use the Spotlight feature in OS X an awful lot. While some people would rather use things like Quicksilver, I like just hitting command+space and typing in what I’m looking for, be it a document or even an application I want to open.

That’s the inspiration for AJAX.search, a search system built on Prototype’s AJAX framework. It will make a call to a URL you specify and display the results under your search box like Spotlight (and now, like the search at Apple.com). From there you can hit the up or down arrow keys to select a result and then hit the enter key to visit the link.

I also built a Wordpress plugin that uses AJAX.search in the default search box, and in fact you can test it out on this site’s search box right now. By default the plugin will search all your posts and display them in the results grouped by category.

If you want to try it out on your Wordpress install, you can download the plugin here. There are still features I still want to implement, and it may not work on all Wordpress versions (I’ve only tested on version 2.2.1). Eventually there will be a configuration page in the admin to allow you to change a few settings, such as number of results to display and whether to show categories in the results.

Download the AJAX.search Wordpress Plugin version 0.1

If you’re using K2: make sure you turn off Advanced Navigation in the K2 options, since K2 has an AJAX search function that will collide with this one. If you want to keep Advanced Navigation on, you’ll have to comment out the Javascript in the K2 header file that sets up the K2 AJAX search.

Whois on your iPhone

I finished a quick app for the iPhone that allows you to do a whois lookup on a domain to see if it’s available or not. I’m always out and about and think of a domain name, and want to know if it’s taken.

Why don’t you just use whois.net or something, you ask? Well first of all that site is packed full of bloat and junk that makes it a pain to look something up. Secondly, I have a sneaking suspicion that sites like whois.net harvest requests and register those domains if no one else does. And no, my app does not record lookups!

I built the app using a small PHP script and IUI. Check out the app at http://whois.onmyiphone.net

Why I love developing for the iPhone

Before the iPhone came out there was the announcement: the official SDK to make applications on the iPhone was HTML and Javascript, displayed in a web browser. I read a lot of comments complaining about that, programmers that wanted real hooks into the iPhone system. For instance, you can’t access the phone’s address book, voice mail, or photos with a web browser.

But I think Apple made a smart move. Making a web browser the official software platform allowed many more applications to be developed in a really short amount of time, since a lot more people can make web apps than can create native applications for OS X. And since a web browser is already the defacto communications conductor on the Internet, integrating the phone with information on the Internet is already done.

Why do I love developing for the iPhone?

  • I get a fixed screen size. It’s almost like designing for print again. I get 320×480 to work with on my web app, and I can bet that won’t change for quite a long time. No more designing to work within a range of resolutions, I know my app will fit in the screen as I intended. It also forces me to be creative with the space I have, which is a refreshing coming from developing for desktop browsers.
  • I only have to code for one browser. Actually, the best part is I don’t have to code for Internet Explorer. I know my site will render exactly as I wanted it to when I originally made it. The CSS will render predictably, and the Javascript will work like I planned. Also, Safari on the iPhone is a full-fledged browser that can do just about everything a desktop browser can do, not some crippled smartphone browser.
  • It makes me think differently about user interfaces. The only time I’ve developed for a touch screen was for a small kiosk project that lived in a museum. Most people don’t have the opportunity to develop a site that will be used with your fingers. It changes your perspective on designing web applications when you don’t have the typical mouse and keyboard setup. It gave me ideas and inspiration to take with me back to the desktop world.
  • It opens up a whole new range of applications. Ideas that were pretty good on the desktop are now more useful than ever. Location-based searching and apps like to-do lists and mileage logs make a lot more sense when the user can have it with them all the time, and not tied down to a desktop.

I have a feeling Apple will eventually open up the iPhone to allow developers to create native applications, but the web browser based SDK will probably stay the most popular. If I could develop iPhone web apps exclusively, I would. It would be so much more fun.

Large Hit State Menus with Javascript and CSS

A growing trend I have been noticing while developing web sites is the need (or want) to create areas on the page that are clickable. Generally these are areas that contain a headline and a snippet of text, and sometimes an image. I really like the idea of having areas of that page that are clickable because I believe it encourages users to click through right away, and can make those worn out ‘click here’ links obsolete.

Typically these large hit state links are created using images. This is both good and bad. Since it’s an image, we can control how the area looks very easily. But the bad thing is it doesn’t do you any good for accessibility and search engine visibility.

Good hit states should:

  • Allow a user to click anywhere in the area to follow the link;
  • Visibly cue the person that the area is a link;
  • Degrade gracefully to users without CSS or Javascript enabled; and finally
  • Integrate semantically into the document to make sense in the structure.

In this example we’re going to create a navigation menu for a web site. Our customer wants to have menu items that have a title and a small description. The designer wants the whole thing to be a link. Here’s how we pull it off.

Step One: Set up the menu

Typically while creating navigation menus using CSS, I tend to use unordered lists. For this example, it won’t work very well because there will be elements in each menu item that won’t work inside a li tag. To keep the document semantically correct, I want to use something like an h4 element for the title and paragraph tag for the description. Embedding these in a li element is technically valid HTML, but it’s a bad way to structure a document. I would even go so far as to say it’s similar to embedding structure inside nested tables. So we’re going to create a menu items out of div elements containing a headline and a paragraph element.

  <div class="menu_item">
  <h4><a href="index.html">Home</a></h4>
  <p>Go to the home page</p>
  </div>
  <div class="menu_item">
  <h4><a href="about.html">About</a></h4>
  <p>Read about how rad we are</p>
  </div>
  <div class="menu_item">
  <h4><a href="http://www.myfriendssite.com" rel="external">My Friend</a></h4>
  <p>My Friend's Site</p>
  </div>

That was simple, clean and valid HTML. Using h4 tags denotes importance, but not enough importance on the page to overrule your headlines. We have a short description in there with a paragraph tag. Notice we add a menu_item class to each div element. This is how we’ll work the magic later with Javascript.

Step Two: Set up the CSS

Now we’ll write some basic CSS to style the menu. Of course you’ll want to style it differently, so I’ll keep it super simple.

  div.menu_item {
    border: 1px solid #CCC;
    padding: 10px;
    width: 100px;
  }

Each menu item will be 180 pixels with a border and 10 pixels padding. Now let’s add a class for a hover state of the menu item. We’ll turn the background a slight gray and make the border darker. Then we’ll change the cursor to the pointer icon to make it appear to be a link.

  div.hover {
    background: #CCC;
    border: 1px solid #999;
    cursor: pointer;
  }

If Internet Explorer 6 played nice we’d add a :hover pseudo-class to the menu item in the CSS and be done. However, it doesn’t support CSS hover states on anything but links. Internet Explorer 7 in strict standards compliant mode does, but it’s currently a smaller subset of browser share. So we’ll need a little help from Javascript.

Step Three: Set up the Javascript

As with most of my Javascript snippets, you’ll need Prototype included in your page. For those just wanting to copy and paste the snippet and be done, I’ll throw it out now:

  function init_menu() {
    var items = document.getElementsByClassName('menu_item');
    items.each(function(item) {
      Event.observe(item,'mouseover',function() {
        Element.addClassName(this,'hover');
      }.bind(item));
      Event.observe(item,'mouseout',function() {
        Element.removeClassName(this,'hover');
      }.bind(item));
      Event.observe(item,'click',function() {
        var link = this.getElementsByTagName('a')[0];
        if (link.getAttribute('rel') == 'external') {
          window.open(link.href);
        } else {
          window.location = link.href;
        }
      }.bind(item));
    });
  }
  Event.observe(window,'load',init_menu);

For those who are still reading and want to know how it works, let’s go through it a few lines at a time.

How it works

First we get all the items in the document with the class name menu_item.

  var items = document.getElementsByClassName('menu_item');

Next we loop through each item found and apply event listeners to each one. Instead of the typical for (var i = 0; i < items.length; i++) pattern, we use Prototype’s each iterator, which cleans things up a lot in our code.

  items.each(function(item) {

The first thing we want to do to our menu item is apply a mouseover and mouseout state to it. We’ll add event listeners for the element to apply the hover CSS class to change the appearance. Since Prototype comes with a built in addClassName and removeClassName functionality, as well as event listeners using Event.observe, we don’t have to worry about supporting how it works across multiple browsers. Prototype handles that for us.

  Event.observe(item,'mouseover',function() {
    Element.addClassName(this,'hover');
  }.bind(item));
  Event.observe(item,'mouseout',function() {
      Element.removeClassName(this,'hover');
  }.bind(item));

Notice the bind call at the end of each even listener we set up. This allows us to reference the item as this inside the function block we pass into the event listener call. Otherwise it wouldn’t know what item you were referring to.

Now you might be thinking ‘how do you turn to the whole thing into a link when the link is only in the headline?’. Here’s how we do it: we parse the menu item and find the first link, then make the menu item listen for a click. When it’s clicked, it will open the link as though the real link inside the menu item had been clicked.

  Event.observe(item,'click',function() {
    var link = this.getElementsByTagName('a')[0];
    if (link.getAttribute('rel') == 'external') {
      window.open(link.href);
    } else {
      window.location = link.href;
    }
  }.bind(item));

It’s even set up to check for the rel="external" attribute of a link (covered in my previous post) and will open it in a new window if it’s present.

Finally we’ll set up an event listener to call the function after the page is loaded:

  Event.observe(window,'load',init_menu);

Stick this in an external Javascript file on your page or into the head of your document, and your menu items that can contain anything you want, and still appear as one large link. You can also apply it to more than than just menu items: use it on special callouts on your pages, such as download links, lists of previous blog posts, or product ads.

Users without Javascript enabled will still be able to view and click on links inside the menu items, they just won’t be as stylized as when Javascript is enabled. Search engines will also love your h4 headlines and description for each link, so your site could possibly rank for more relevant searches. What’s not to like?

I’ve uploaded a very basic example so you can see it in action. If you found this useful and applied it to your site, leave a comment and link to where you used it.

Unobtrusive Javascript pop-up links

One of the things I dislike the most about writing HTML is creating links that open in new windows. Since I try to make all my HTML standards-compliant, I can’t use the target="_blank" attribute in my links anymore, since it’s been deprecated in XHTML. Many have followed the new standard of making an inline onclick attribute of the link open the window, including myself. But what a pain it is to type it all out and remember the exact code to do it. Instead of this:

  <a href="http://www.example.com" onclick="window.open(this.href); return false;">External Link</a>

Wouldn’t it be easier to type this?

  <a href="http://www.example.com" rel="external">External Link</a>

I’m sure you’ll agree it’s much cleaner, easier to type, easier to remember, and to top it off, it’s (kind of) symantically correct. While the possible attribute values of rel do not include external, using it as a keyword to denote the relationship between an external page and your link makes sense. Best of all it validates with the W3C validator with flying colors.

How to Make it Happen

So how do we make the magic happen? The answer is with our good old friend Javascript. Basically we’re going to make a function that will crawl the document after the page loads and check for links that have rel="external" in it, then attach an Event.observe to each link that will cause it to open in a new window (note that you’ll need Prototype.js for this to work).

Here’s the code:

  function external_link(link) {
    var el = Event.element(link);
    if (el.tagName == 'IMG') {
      if (el.parentNode.tagName == 'A') {
        var el = el.parentNode;
      } else {
        return false;
      }
    }
    window.open(el.href);
    Event.stop(event);
    return false;
  }
  function init() {
    var links = $A(document.getElementsByTagName('a'));
    links.each(function(link) {
      if (link.getAttribute('rel') == 'external') {
        Event.observe(link,'click',function(e){ external_link(e); },false);
      }
    });
  }
  Event.observe(window,'load',init);

Note in the external_link function it checks if the item clicked was an image tag. If it is, then it will look up one node in the DOM tree to see if the image was enclosed in an anchor tag, and attach the event to that instead (since it contains the href it needs to open). If it doesn’t find anything, it will exit quietly.

Load this in your document header and off you go. You should be able to add rel="external" to any link on your page and it will open in a new window. Remember you need a copy of Prototype loaded as well. Leave a comment if have any questions or improvements.