Yay! Programmer art!
Yay! Programmer art!

Example of adding client side filtering to an XML File

The question recently came up about possible ways to filter data in a browser client where the source was an XML file. There are, of course, many different ways this could be done, but I decided to use XSL to create a list of the data in XHTML and to include JavaScript in the XSL file which will actually handle the filtering. It is a very simple example but I thought someone might find it useful.

Link to the working example

searchxml.xml


<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="searchxml.xsl" type="text/xsl" ?>
<jobs>
  <job>
    <name>Shoe Sales</name>
    <desc>Selling shoes</desc>
    <coast>East</coast>
  </job>
  <job>
    <name>Food Taster</name>
    <desc>Taste food</desc>
    <coast>East</coast>
  </job>
  <job>
    <name>Computer Programmer</name>
    <desc>Program computers</desc>
    <coast>West</coast>
  </job>
  <job>
    <name>Teacher</name>
    <desc>Teach students</desc>
    <coast>East</coast>
  </job>
  <job>
    <name>Kite Flyer</name>
    <desc>Fly kites</desc>
    <coast>West</coast>
  </job>
</jobs>

searchxml.xsl


<?xml version="1.0" encoding="UTF-8" ?>
 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" omit-xml-declaration="yes" indent="yes" />
  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>
 
  <xsl:template match="jobs">
    <html>
      <head>
        <title>Search Jobs</title>
        <script type="text/javascript">
          //<![CDATA[
            
            function doSearch() {
              var rb = document.getElementsByName("whichCoast");
              var v;
 
              for (var i = 0; i < rb.length; i++) {
                if (rb[i].checked) {
                  v = rb[i].value;
                  break;
                }
              }
 
              var jobs = document.getElementsByTagName("li");
              for (var j = 0; j < jobs.length; j++) {
                if (jobs[j].className == "job") {
                  var li = jobs[j].getElementsByTagName("li");
                  for (var k = 0; k < li.length; k++) {
                    if (li[k].className == "coast") {
                      if (v == "Either" || li[k].firstChild.nodeValue.match(v)) {
                        jobs[j].style.display = "";
                      } else {
                        jobs[j].style.display = "none";
                      }
                    }
                  }
                }
              }
            }
 
          //]]>
        </script>
      </head>
      <body>
        <form action="#" onclick="doSearch();" onsubmit="return(false);">
          <label>East <input type="radio" name="whichCoast" value="East"/></label>
          <label>West <input type="radio" name="whichCoast" value="West"/></label>
          <label>Either <input type="radio" name="whichCoast" value="Either" checked="checked"/></label>
        </form>
        <ul>
          <xsl:for-each select="job">
            <li class="job">
              <ul>
                <li class="name"><xsl:value-of select="name"/></li>
                <li class="desc"><xsl:value-of select="desc"/></li>
                <li class="coast"><xsl:value-of select="coast"/></li>
              </ul>
            </li>
          </xsl:for-each>
        </ul>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Conditional Test for IE6 in CSS

I recently had a problem where I had to make a tweak in the CSS just for IE6. I couldn’t find any way to conditionally compile in the .css standalone file and I didn’t want to create a whole new .css file just for IE6 and conditionally compile it in. Anyway, in IE6 I was getting a gap of 3 pixels between two divs that contained images. The solution I found was to take advantage of the way IE6 has a CSS node above HTML when its in standard mode. So I could write


  * html div#fixforie6 { margin-right: -3px; }

And that only made the change in IE6 (out of IE6, IE7, and FF2 which are my target browsers).

The full code for the example is here.


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title>IE6 CSS fix</title>
    <style type="text/css">
      div {
        margin: 0;
        padding: 0;
        border: 0;
      }
      div#clear { clear: both; }
      div.float-left {
        float: left;
      }
      * html div#fixforie6 {
        margin-right: -3px;
      }
    </style>
  </head>
  <body>
    <div class="float-left"><img src="http://www.exfer.net/test/images/MenuTopLeft.gif"/></div>
    <div><img src="http://www.exfer.net/test/images/MenuTopRight.gif"/></div>
    <div id="clear"/>
    <div id="fixforie6" class="float-left"><img src="http://www.exfer.net/test/images/MenuTopLeft.gif"/></div>
    <div><img src="http://www.exfer.net/test/images/MenuTopRight.gif"/></div>
  </body>
</html>

And a link to the code is here so you can check it out in the different browsers.

Book Reviews

I’ve decided to do a few book reviews for some of the books I’ve read recently. Since the most recent is Prototype & Scriptaculous in Action I figured I’d do that review first.

Simple Ajax Example

Here is an Ajax example that was put together to demonstrate how Ajax can be used to validate something without refreshing the page. The link is here.

JavaScript Libraries

Well between various distractions, including income tax, I’ve been able to get through most of the Prototype & Scriptaculous in Action book. So far I have really enjoyed it although much of it is an easy read for an experienced programmer. Still it is fun to see what a popular JavaScript library can make it easy to do. Now I can’t wait to finish so I can check out some of the others before I choose one.

Seeing Generated Source

One of the nice features in FireFox with the Web Development addon is the ability to see the generated source after you have done DOM manipulations.  Unfortunately it isn’t as easy in IE, but here is a tip that helps me.  Just type this in the address bar of the page you’d like to see the generated source.


javascript:alert(document.body.innerHTML);

And if it gets to long for an alert window you can also try this


javascript:document.write(document.body.innerHTML.replace(/</g,'&lt;'));

It comes in handy now and then.

Learning Prototype and Scriptaculous

Well today I am learning Prototype and Scriptaculous.  Up until now I’ve been using my own home grown Javascript library, but I’ve decided it is time to see what else is out there.  Clearly anything open source will have a lot more testing, features, and support.  I decided to start with this library largely because of the book Prototype & Scriptaculous in Action by David Crane, Bear Bibeault, and Tom Locke.  It was released at the perfect time for me to use it.  After I feel comfortable with these libraries I think I’ll move on and try YUI next.

Starting Out

Well, here is my first post.  Like most first posts this one is completely uninspired.  Hopefully I’ll have something more interesting (at least to me) available for my next post.  In any case…  Welcome. :)