Introducing XUL – The ‘Net’s Biggest Secret: Part 2

Last time, we got to know our way around browsing with XUL. Now, let’s look at searching and navigation…

… and don’t forget to download the code archive for this series, if you haven’t already!

Desperately Seeking

As the last example demonstrated, using XUL, you can give your site’s visitors a unique experience by modifying the browser to make navigation faster and easier. And, when you start throwing JavaScript into this mix, all sorts of powerful new opportunities arise. Here’s a simple example, which displays a search box that’s always visible. It also demonstrates the potential for building forms with XUL.

<?php 
header ( 'Content-type:  
application/vnd.mozilla.xul+xml' );
?>
<?xml version="1.0"?>
<!-- example2.xul -->
<?xml-stylesheet href="example2.css" type="text/css"?>
<window
    title="Searching Sitepoint"
    xmlns:html="http://www.w3.org/1999/xhtml"
    xmlns="http://www.mozilla.org/keymaster/
gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="example2.js"/>
<hbox id="searchPane">
  <description><html:div id="title">This  
is HTML</html:div></description>
  <grid flex="1">
    <columns>
      <column/>
      <column/>
    </columns>
    <rows>
      <row align="end">
        <textbox id="searchField"/>
        <button id="searchButton" label="Search  
Sitepoint" oncommand="search();"/>
      </row>
    </rows>
  </grid>
</hbox>
<xbox flex="1">
 <browser id="sitepointBrowser" flex="1" src="
http://www.sitepoint.com/"/>
</xbox>
</window>

To see this in action, browse example2.xul from the code archive, and try entering "PHP" in the box top right.

The first thing to notice is that I’ve included some JavaScript:

<script type="application/x-javascript" src="example2.js"/>

We’ll look at the script in a moment.

Next, I’ve used two <xbox /> elements. Boxes are containers in which we can put other XUL elements – they make it easy to lay out your application. I’ve assigned an id to the first, so I identify it in my CSS document. The alternative to hbox is vbox, which is used to create divisions up the Y axis, rather than the X axis.

I’ve used the description element, which is a general container for text, just to prove you can put HTML in an XUL document; note that I have to specify the namespace prefix for HTML. Be aware that not all XUL elements can be used to display HTML — the rule of thumb seems to be that if the element could contain text, it should be able to display HTML.

Within the first hbox, I’ve used a grid, which acts much like a table in HTML, and which I’ve used to help position the elements correctly. This should be familiar to anyone with ASP.NET experience.

I’ve then used two "form" elements, textbox and button. I’ve assigned each an "id" attribute, for assigning CSS, and to locate the textbox with DOM. The "oncommand" attribute specifies the JavaScript function that’s called when the button is clicked, much like the "onClick" attribute in HTML.

Finally, note the id of the browser element in the second hbox; I’ll be using this in a moment with JavaScript.

The CSS document I’ve used here looks like this:

window 
{
 background-color: navy;
}
#searchPane
{
 background-color: silver;
}
#searchField
{
 width: 300px;
 height: 25px;
 font-family: verdana;
 font-size: 12px;
 font-weight: bold;
 color: purple;
}
#searchButton
{
 font-family: verdana;
 font-size: 12px;
 font-weight: bold;
 color: navy;
}
/* This style is for the HTML div element */
#title
{
 font-family: verdana;
 font-size: 14px;
 font-weight: bold;
 color: #ff4500;
 text-indent: 10px;  
}

Note that the CSS document is applied to both XUL and HTML.

And now, that JavaScript:

// For searching sitepoint 
function search () {
 var searchField=document.getElementById('searchField');
 var sitepointBrowser=document.getElementById('sitepointBrowser');
 sitepointBrowser.setAttribute('src',

   'http://www.sitepoint.com/search/search.php?q='
   +searchField.value+'&submit=Search');
}

I’ve used DOM to fetch the value of the searchField. I’ve also fetched the browser element, using its id attribute. In the third line, I modify the value of the src attribute in the browser element, to point it at SitePoint’s search URL.

No problem!

Takeaway Menu

If you’ve ever tried implementing a menu with JavaScript, you’ll know that what should be fairly easy is, in practice, very difficult. Implement anything more than a fairly simple menu, and you’ve got an uphill battle to fight. With XUL, it’s a different story.

Using the menubar element, here’s how you could put a menu on your site:

<?php  
header ( 'Content-type: application/vnd.mozilla.xul+xml' );  
?>  
<?xml version="1.0"?>  
<!-- example3.xul -->  
<?xml-stylesheet href="example3.css" type="text/css"?>  
<window  
    title="Searching Sitepoint"  
    xmlns:html="http://www.w3.org/1999/xhtml"  
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/  
there.is.only.xul">  
<script type="application/x-javascript" src="example3.js"/>  
<hbox id="menuPane">  
  <menubar id="sitepointMenubar" grippyhidden="true">  
    <menu id="clientside-menu" label="Client Side">  
      <menupopup id="clientside-popup">  
        <menuitem label="Client Side Home"  
           oncommand="goTo('http://www.sitepoint.com/cat/81')"/>  
        <menuseparator/>  
        <menuitem label="HTML and XHTML"  
           oncommand="goTo('http://www.sitepoint.com/subcat/88')"/>  
        <menuitem label="JavaScript and DHTML"  
           oncommand="goTo('http://www.sitepoint.com/subcat/89')"/>  
        <menuitem label="CSS"  
           oncommand="goTo('http://www.sitepoint.com/subcat/90')"/>  
        <menuitem label="XML"  
           oncommand="goTo('http://www.sitepoint.com/subcat/91')"/>  
      </menupopup>  
    </menu>  
    <menu id="serverside-menu" label="Server Side">  
      <menupopup id="serverside-popup">  
        <menuitem label="Server Side Home"  
           oncommand="goTo('http://www.sitepoint.com/subcat/82')"/>  
        <menuseparator/>  
        <menuitem label="ASP and .NET"  
           oncommand="goTo('http://www.sitepoint.com/subcat/92')"/>  
        <menuitem label="Perl and CGI"  
           oncommand="goTo('http://www.sitepoint.com/subcat/93')"/>  
        <menuitem label="Java and J2EE"  
           oncommand="goTo('http://www.sitepoint.com/subcat/94')"/>  
        <menu id="phpmysql-menu" label="PHP and MySQL">  
          <menupopup id="phpmysql-popup">  
            <menuitem label="PHP and MySQL Interviews"  
               oncommand="goTo('http://www.sitepoint.com/subcat/97')"/>  
            <menuitem label="PHP and MySQL Tutorials"  
               oncommand="goTo('http://www.sitepoint.com/subcat/98')"/>  
            <menuitem label="PHP and MySQL Reviews"  
               oncommand="goTo('http://www.sitepoint.com/subcat/99')"/>  
          </menupopup>  
        </menu>  
      </menupopup>  
    </menu>  
  </menubar>  
</hbox>  
<hbox flex="1">  
 <browser id="sitepointBrowser" flex="1" src="  
http://www.sitepoint.com/"/>  
</hbox>  
</window>

The script’s a bit bigger than those you’ve seen so far. Let’s take a closer look.

The root element for the menu is the menubar. I’ve switched of the "grippy" which is that "thing" you can click on in Mozilla to hide menus and toolbars.

Below the menubar is a menu element, which I’ve assigned a label for visitors to read. Each menu element below a menubar defines a new drop down menu.

With the menu, we have a menupopup, which is the "panel" that displays when you click on the menu.

Inside the menupopup is where we place the menuitems, where the label specifies the text that appears for the menu item, and the oncommand attribute is used to trigger a JavaScript function (which we’ll see in a moment).

The menuspacer that appears under both menupopup elements is used to place a horizontal line across the menu.

Notice the PHP menu? I’ve created a sub menu here, so that each of the PHP-related categories of SitePoint can appear under one menu.

The JavaScript is very simple:

// Directs browser element to a different src  
function goTo (url) {  
 var sitepointBrowser=document.getElementById('sitepointBrowser');  
 sitepointBrowser.setAttribute('src',url);  
}

And the CSS:

window  
{  
 background-color: navy;  
}  
menu  
{  
 background-color: white;  
 font-family: verdana;  
 font-weight: bold;  
 font-size: 12px;  
 color: gray;  
}  
menupopup  
{  
 background-color: silver;  
}  
menuitem  
{  
 font-family: verdana;  
 font-weight: bold;  
 font-size: 12px;  
 color: navy;  
}

In other words, building menus has never been so easy!

There’s so much you can do with XUL, I could go on showing you demos forever. All those things you’ve struggled to build into your site, such as tree menus, "tool tips", scroll bars, progress meters and so on, are a snap with XUL.

For anyone with experience in building GUIs, you’ll find Mozilla has even implemented "broadcasters" and "observers" as XUL elements, along with a "commandset" element, which can be used to fire off multiple responses to events. Oh and did I mention Overlays, Templates and RDF data sources yet? And what about XBL, for when you want to change the behaviour of XUL widgets? Perhaps next week, in the final installment for this series…

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

No Reader comments

Comments on this post are closed.