Implementing jQuery UI in a Web Application

A lot of people thought I was crazy for wanting to develop my own PHP framework, and 1400 hours of discovery and development later, they may have a point. At the end of the day, though, I have an extremely powerful and flexible framework for making database-driven web applications. Where even I drew the line, however, was with javascript. I made the decision to use jQuery because its design philosophy seems similar to my own.

My plan is to integrate jQuery into my PHP framework, but I need to learn a lot more about how jQuery works and refactor some of my core structural components to accommodate it. In the meantime, I can start to implement jQuery in individual applications.

Downloading jQuery

To enable jQuery requires only one javascript file, available from jquery.com. I chose to copy down the latest minimized version (jquery.min.js) to my web server to have as a local file. Almost everything is driven through events.

To have all the interface elements available, both javascript and stylesheets are required, available as themes from http://jqueryui.com/themeroller. I again downloaded the relevant files to my web server: When you select a theme from the gallery, there is an option to download the package (and you can fine tune which parts of a theme you want or need). Themes are also customizable.

When you download a theme, there a number of directories and files, but there are only two important ones: the theme folder (which contains the base stylesheet and all the supporting images) and jquery-ui javascript file.

Making jQuery Available

Now, you need only reference the downloaded javascript and stylesheets. In the applications I build, I tend to use abstract application modules that handle the common tasks (like loading libraries and content necessary for most of the modules in the application).

Partial Listing: rsrc/master/ApplicationModule

abstract class ApplicationModule extends IWModule
{
   ...
   
   function pageDidLoad($page)
   {
      $page->addJavascript('js/jquery.min.js');
      $page->addJavascript('js/jquery-ui-1.8.14.custom.min.js');
      $page->addStylesheet('css/smoothness/jquery-ui-1.8.14.custom.css');
   }
   
   ...
}

The rendered page for any ApplicationModule subclass has a header block with the appropriate references.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/pod/lib/css/public.css" />
<link rel="stylesheet" type="text/css" href="/pod/lib/css/editor.css" />
<link rel="stylesheet" type="text/css" 
   href="/pod/lib/css/smoothness/jquery-ui-1.8.14.custom.css" />
<script src="/pod/lib/js/jquery.min.js"
    type="text/javascript" charset="utf-8"></script>
<script src="/pod/lib/js/jquery-ui-1.8.14.custom.min.js"
    type="text/javascript" charset="utf-8"></script>
</head>
<body>

...

</body>
</html>

Now, my application is ready for some jQuery UI goodness (to be presented in later articles).

Javascript Field Placeholders

One standard feature on most blogs (and lots of other places, of course) is a search widget. I wanted to make sure that its functionality was obvious without having to resort to a label sitting on top of it (or next to it). So, I experimented with a little Javascript to create some placeholder text to make clear what purpose the field served. Once the user clicks in the field, I also want the placeholder text to go away (and then return when the user leaves the field if it is empty).

HTML

The simple search text field, of course, needs to be wrapped in a form, and in order for the effects to take place that we want, we need to do some things when the page loads.

Listing: index.html

<html>
<head>
<script src="lib/js/search.js"></script>
<link rel="stylesheet" type="text/css" href="lib/public.css" />
</head>
<body>

<form id="blog_search" name="blog_search" method="get" action="/iw/blog">
<input id="search_input" name="s" type="text" size="25" maxlength="40" 
       onfocus="javascript:remove_placeholder(this);" 
       onkeyup="javascript:use_typing_color(this);" 
        onblur="javascript:set_placeholder(this);" />    
<a href="javascript:submit_search();" class="search_go">
   <img src="/iw/img/icon/go-gray.png" alt="Do Search" />
</a>
</form>

<script type="text/javascript">
bring_focus_to_search();
</script>

</body>
</html>

Javascript

To make our placeholder work, we need two javascript functions, set_placeholder() and remove_placeholder(). Rather than use an ordinary submit button, we'll use graphics and style sheets to make it look spiffy, and a javascript function to make it work.

Listing: lib/js/search.js

function bring_focus_to_search() {
   document.blog_search.s.focus();
   set_placeholder(document.blog_search.s);
   document.blog_search.s.select();
}

function set_placeholder(field) {
   if (field.value) return;
   
   field.value = 'Search the Developer Blog';
   field.style.color = '#999';
}

function remove_placeholder(field) {
   if (field.value != 'Search the Developer Blog') return;
   
   field.value = '';
   field.style.color = '#333';
}

function use_typing_color(field) {
   field.style.color = '#333';
}

function submit_search() {
   document.blog_search.submit();
}

Cascading Syle Sheets (CSS)

A couple simple styles help the input field and search button line up properly.

Partial Listing: lib/css/blog.css

#search input {
   margin-top: 10px;
   display: block;
   float: left;
}