jQuery and XML namespaces: a solution

In my previous posts I did present a solution for selecting XML namespaces that was quite clunky. Thanks to Gianluca Troiani, I'm now aware of a simpler solution. This solution involves the use of a double backslash just before the ':' token of the XML suffix. Further, this is the standard procedure that jQuery uses to escape selectors inside an expression. So, given the following XML fragment:

<dvd xmlns:dvd="http://onwebdev.blogspot.com/ns/dvd">
 
 <dvd:item>
 
    <dvd:title>Mr. Jones</dvd:title>
    <dvd:year>1993</dvd:year>
 
 </dvd:item>
 
 <dvd:item>
 
    <dvd:title>Alien</dvd:title>
    <dvd:year>1977</dvd:year>
 
 </dvd:item>
 
 <dvd:item>
 
    <dvd:title>Dead Poets Society</dvd:title>
    <dvd:year>1989</dvd:year>
 
 </dvd:item>

</dvd>

we can write the following jQuery code:

$(document).ready(function() {


   $('dvd').find('dvd\\:item').each(function() {
   
   
       var $item = $(this);
       var $title = $item.find('dvd\\:title').text();
       var $year = $item.find('dvd\\:year').text();
       
       alert('DVD title: ' + $title + '\n' + 'DVD year :' + $year);
   
   });


});

That's a lot neater than using DOM properties (and more cross-browser).

CSS: nested floats

Nested floats require some basic knowledge of how CSS floats actually work. The first thing you need to know is that a floated element automatically contains another floated element (from the point of view of containing floats). Another important thing to note is that floated elements automatically push other elements to another line when there's no more room available on the line where they are enclosed. Let's say that we have an HTML structure like this:

<div id="container">

    <div id="left">
    
       <div id="left-1"></div>
       <div id="left-2"></div>
       
       <div id="clear-1"></div>
    
    </div>
    
    <div id="right">
    
        <div id="right-1"></div>
        <div id="right-2"></div>
        
        <div id="clear-2"></div>
    
    </div>
    
    <div id="clear"></div>

</div>

So we have a container, two sub-container and three other elements within such containers. We can write the following CSS code:

#container {

    width: 450px;
    background: gray;
    overflow: auto;


}

#left {

    float: left;
    width: 200px;
    height: 200px;
    background: orange;

}

#right {

    float: right;
    width: 200px;
    height: 200px;
    background: crimson;


}

#left-1 {

    float: left;
    width: 90px;
    height: 100px;
    background: teal;


}

#left-2 {
    
    float: right;
    width: 90px;
    height: 100px;
    background: fuchsia;

}

#right-1 {

    float: left;
    width: 90px;
    height: 100px;
    background: silver;


}

#right-2 {
    
    float: right;
    width: 90px;
    height: 100px;
    background: maroon;

}

#clear-1,
#clear-2,
#clear {

    width: 90%;
    margin: 0 auto;
    height: 50px;
    background: yellow;
    clear: both;

}

First we take care of containing floats by specifying overflow: auto on the main container. This works because this declaration actually prevents vertical space from collapsing. Then we float every box inside the two sub-containers and the other elements within these boxes with the exception of the three elements that need to be cleared. You can see the result of this test below.

As you can see, in our test we only needed to add the declaration clear: both to the yellow boxes. This is due to the fact that all floats inside the main container are not wide enough to fill the line that encloses them. If this was the case, then all yellow boxes would be automatically pushed on the next line, though no clearance would be added to them.

Serving HTML5 as application/xhtml+xml

Serving HTML5 as application/xhtml+xml is quite simple, though there are some gotchas you need to know before doing so. The first thing to do is to set an XML prolog before the HTML5 DOCTYPE, thus providing also the default character encoding of the entire document. Since all XHTML documents have also a meta tag that tells the validator what kind of content type they're going to handle, most developers will try to set this kind of tag in the head section of their documents. Unfortunately, this will return a validation error.

There's no need to set this kind of tag. To pass validation, you have to follow two approaches:

  1. if you're serving a static file with a file extension (such as xht or xhtml), you don't need this tag
  2. if you're serving a dynamic document, just set the appropriate HTTP header before returning any output.

Finally, you have to set the XHTML namespace on the root element, which is http://www.w3.org/1999/xhtml. A basic HTML5 template served as application/xhtml+xml is shown below.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Serving HTML5 as application/xhtml+xml</title>
</head>

<body>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
</body>
</html>

jQuery: the explode() plugin

This plugin works in a destructive way, in the sense that its primary use is related to the removal of certain page elements where they're no longer needed. In its essence, it is as follows:

/** jQuery explode() plugin

   
   Adds a simple exploding effect to a jQuery's element
   and then removes the element from the DOM
   
   Usage: $(element).explode(speed);
   speed: any value accepted by the animate() method
   
   @author Gabriele Romanato <http://onwebdev.blogspot.com>
   @version 1.0  */
   
   
   


(function($) {
 
 $.fn.explode = function(speed) {
  
  var self = this;
  
     return this.each(function() {
     
         speed = speed || 'fast';
  
      var winWidth = $(window).width();
      var winHeight = $(window).height();
  
      self.animate({
       
       display: 'block',
       width: winWidth,
       height: winHeight,
       opacity: '0'
   
   
      }, speed, function() {self.remove();});
  
     }); 
  
 };
 
})(jQuery);

It accepts as its sole parameter a speed value which corresponds to the values accepted by the animate() method. When the animation is complete, the element is removed from the DOM. Note also that it turns an element into a block-level one by operating on its CSS display property (remember that setting width and height on an inline element doesn't work).

Live example

Live example

Download

jquery.explode.js

CSS counters

CSS generated content allows for the insertion of a simple numbering system called counters. In its simplest form, CSS counters rely on the creation of scopes within the page element they're attached to. For example, let's say that we have a simple unordered list and we want to attach counters to it. Here's the markup:

<ul id="one">
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>

And here's our element's scope:

ul [SCOPE]
  1 li
  2 li
  3 li
/ul [/SCOPE]

In this case, our counters will work on a single scope. Here's the CSS code:

#one {

    counter-reset: one; /* creates the scope for the counter and initializes it */

}

#one li:before {

    counter-increment: one; /* increments the counter */
    content: counter(one) '. '; /* displays it */

}

As you can see, the counter one lives within the scope of our simple unordered list. I've first initialized it, then incremented it and finally inserted it just before the actual content of each list item. But what happens when we have multiple nested elements and we want that each element have its numbering system? In this case, multiple scopes will be created. For example, given the following markup:

<ul id="multiple">
<li>Item

<ul>
    <li>Item
        <ul>
        
            <li>Item</li>
        
        </ul>
    </li>
</ul>

</li>

<li>Item</li>

</ul>

we have this structure:

ul [SCOPE 1]

  1 li
  
    ul [SCOPE 2]
    
      1.1 li
      
        ul [SCOPE 3]
        
          1.1.1 li
          
        /ul [/SCOPE 3]
        
    /ul [/SCOPE 2]
    
  2 li
  
/ul [/SCOPE 1]

As you can see, each scope is contained within a parent scope. This reflects the progressive numbering showed in the diagram. To get the desired result, we have to concatenate each counter with its parent counter, like so:

#multiple {

    counter-reset: multiple;
    

}

#multiple li:before {

    counter-increment: multiple;
    content: counter(multiple) '. ';

}

#multiple li ul {

    counter-reset: multiple-a;

}

#multiple li ul li:before {

    counter-increment: multiple-a;
    content: counter(multiple) '. ' counter(multiple-a) ' ';

}

#multiple li ul li ul {

    counter-reset: multiple-b;
    


}

#multiple li ul li ul li:before {

    counter-increment: multiple-b;
    content: counter(multiple) '. ' counter(multiple-a) '. ' counter(multiple-b) ' ';

}

Each scope has its own counter which also inherits the counter from the parent scope. Here all the work is done by the content property that displays the counters in the desired order. You can see the results below.

JavaScript: object instance getters

I'm basically a developer with a classical, traditional OOP background, so when it comes to JavaScript, I just keep banging my head on the desk because many things that I take for granted are not so easy in JavaScript. In other words, they need a little bit of language introspection to get to the point. I mean, JavaScript is a Jedi Master language, so beautiful, so powerful but, ouch, also so puzzling.

Take PHP for example: you have self and... voilà, here's your object instance. Further, you can even use $this and you're done. With all these ideas which crowded my mind, I basically tried this:

function Class() {
    var self = this;
    this.getInstance = function() {
        return new self();
    }
    this.method = function() {
        alert('Method');
    }
}

var myClass = new Class();
myClass.method(); // alerts 'Method'

var instance = myClass.getInstance();
instance.method(); // ERROR: 'this' is not a constructor

Yeah, a constructor. In JavaScript, objects, methods and classes are functions, so we need a function here. I banged my head on the desk for a while, looked through my messy code and then:

var self = Class;

That was so obvious that I felt a little stupid. Dear reader, maybe I am.

jQuery's object inheritance and the call() method

jQuery provides a great tool to handle inheritance in OOP: the extend method. With this method, we can actually create a target object that contains all the methods and properties of one or more objects. The basic syntax is as follows:

$.extend(target, object1, object2, objectN);

Let's say that we have the following two classes:

var Class = function() {

    this.message = 'Foo';


    this.method = function() {
    
        alert(this.message);
    
    };
    
    
};

var SubClass = function() {

    this.message = 'Hello';

    this.show = function() {
    
        alert(this.message);
    
    };

};



var myClass = new Class();
myClass.method(); // 'Foo'
var mySubClass = new SubClass();
mySubClass.show(); // 'Hello'

So far so good: two objects, two methods, two instances, two results. Everything works as expected. Now let's try to merge these two objects into a third one:

var ThirdClass = function(){};
$.extend(ThirdClass, myClass, mySubClass);

We've created an empty class that will work as our target object to be passed to the extend() method. One important thing to note is that in our particular case we've used class instances as arguments for this method, not class names. In fact, if we don't do this, we get undefined because the resulting object is considered to be empty.

Now we want to call the method of the first original class in order to make it display the property of the second original class. To accomplish this task, we use call:

ThirdClass.method.call(mySubClass); //'Hello'

With this code, we've changed the execution context of our method that now points to the second class. As you can see, jQuery's way of handling inheritance preserves a basic aspect of JavaScript OOP programming.

JavaScript: the this keyword

In JavaScript, the this keyword points to the owner of the function it is contained within. If it occurs within a method as part of a class, it refers to the class itself, or rather the object instance of the class created when your code is executing. Out of the context of a class, this usually points to the global window object.

If you want to call a method and make sure that this refers to a different object than the one it would normally refer to, use apply or call. There's a slight difference between these two methods: the former expects any arguments you're passing to the function to be supplied as an array, while the latter does not. Examples:

var showMessage = function() {
  alert(this.message);
};

var setMessage = function(message) {
  this.message = message;
}

// this points to window

showMessage(); // undefined
setMessage('Foo');
showMessage(); // 'Foo'

In these examples, the this keyword refers to the global object itself. Now we can create a class and force the this keyword to refer to our class instead of window.

var LogMessage = function() {
  this.message = '';
};

var myLogMessage = new LogMessage();

setMessage.call(myLogMessage, 'Foo');
setMessage.apply(myLogMessage, ['Foo']);
showMessage.call(myLogMessage); // 'Foo'

Object-oriented CSS: modules

The first thing we need to understand about CSS and OO coding is the fact that a CSS style sheet can actually be broken down in several components that we can call modules. There's a module for generic HTML elements, another for page layout and so on. By splitting down our CSS code into these parts, we actually create a series of strictly connected components that can be used in several ways.

Further, these modules can also be imported into other style sheets, thus creating something that, with a certain degree of imagination, we can call a framework. A fundamental thing to grasp in order to get this results is using abstract names for these modules. The names used should also be semantical, as shown by Andy Clarke in his Transcending CSS. For example, we can use branding instead of header, content-sub instead of sidebar and so on.

Since CSS doesn't have the concept of modules in their essence, we should mark up our code with comments, for example using a syntax like this:

/* @module CSS classes
    @members (.foo, p.bar, div.baz) */

This allows also for a rapid text search through our code, thus resulting in a better and easier file maintenance. However, the concepts exposed here are still in a development stage and they'll require further investigations in the next posts.

CSS: printing URLs with generated content

A couple of months ago I wrote this post that showed how to display link URLs in print with the aid of JavaScript. Honestly speaking, I hate to use JavaScript when the same thing can be actually done with CSS. However, at the time of that post IE 6 and 7 got a still significant market share. But now, as Brian Adams sings, times are changing and IE 8 is gaining its momentum among the various IE machines.

IE 8 actually supports CSS generated content, so it's possible to display link URLs in print only with these few lines of code:

@media print {

    a[href]:after {

        content: ' (' attr(href) ') ';

    }

} 

Is that all? Actually, yes! Anyway, if your primary concern is still supporting old dinosaurs like IE 6 and 7, then my previous post will probably fit your needs.

Multi-level menu with CSS

Roger Johansson is one of the best web developers on the WWW. His posts are always seminal and inspirational, particularly those related to front-end languages. A couple of years ago I saw an excellent test page on his website showing a multi-level menu. Today I decided to try to build something similar with CSS and a bit of jQuery. CSS will play the major role, while jQuery will simply add some cosmetic effect. We start with a basic markup like this:

<ul id="navigation">
    <li><a href="#">Home</a></li>
    <li><strong>Articles</strong>
       <ul>
          <li><a href="#">CSS</a></li>
 <li><a href="#">JavaScript</a></li>
        </ul>
     </li>
     <li><a href="#">About</a></li>
</ul>

What we got here is a nested sub-menu contained within an upper-level menu item. We want that the selected item show the child list with all its items displayed as inline elements, just below the strong element. To accomplish this task, I'll try to use floats and not to position elements. Here's the main CSS:

body {
 margin: 0;
 padding: 0;
 color: #333;
 background: #fff;
 font: 76% Verdana, sans-serif;
}

#navigation {
 margin: 0;
 padding: 0;
 list-style: none;
 height: 100%;
 overflow: hidden;
 font-size: 1.2em;
 background: #eee;
 border-bottom: 1px solid #999;
}

#navigation > li {
 float: left;
 margin: 0 0.5em;
}

#navigation > li > a {
 float: left;
 display: block;
 color: #338;
 text-decoration: none;
 padding: 0.3em;
 font-weight: bold;
}

#navigation > li > a:hover {
 color: #00f;
}

#navigation li strong {
 display: block;
 padding: 0.3em;
 text-transform: uppercase;
 text-align: center;
 background: #fff;
 float: left;
 cursor: pointer;
}

#navigation li strong:hover:after {
 content: ' +';
 color: blue;
 font-size: 1.2em;
}

 

#navigation li ul {
 margin: 0;
 padding: 0;
 list-style: none;
 background: #fff;
 clear: left;
 display: none;
}

#navigation li ul li {
 display: inline;
 margin-right: 0.3em;
}

Let's break down this code into logical parts: first of all, I used the child selectors just to be sure that only the direct children of the main list were selected. In other words, I did not want to select the sub-menu and its children. Done this, I've created the horizontal menu only with floats. On the strong element I've added a pseudo-animation on hover by using CSS generated content (just a plus sign after the textual content of such element). Of course the secondary menu did not need to be floated, so I've used clearance on it. Finally, I turned all the sub-items into inline elements to create the effect of a secondary horizontal menu.

jQuery is used only to show the sub-menu when a user clicks on the active element. Basically, this code has the major disadvantage of creating a gap between the active tab and the rest of the navigation menu, especially when there are many sub-items. However, it doesn't use positioning, and that's what I wanted to do. You can see this demo here.

jQuery: selecting XML namespaces

jQuery was originally built with a syntax which quite resembled the XPath's formal grammar. This was due to the fact that jQuery can actually support both HTML and XML. But what happens when an XML document contains namespaces? Here's an example:

<book xmlns:xdc="http://www.xml.com/books">
  <xdc:bookreview>
   <xdc:title>XML: A Primer</xdc:title>
     <xdc:author>Simon St. Laurent</xdc:author>
     <xdc:price>31.98</xdc:price>
     <xdc:pages>352</xdc:pages>
     <xdc:date>1998/01</xdc:date>
  </xdc:bookreview>
</book>

In this case we have six elements which live inside the main namespace of the book element. Further, all these element have an XML suffix so that it's impossible to select them using normal jQuery's selectors. A good solution to this problem is using the namespaceURI and localName DOM properties to parse the above fragment. Here's how:

$(document).ready(function(){

   var NS = 'http://www.xml.com/books';
   var contents = [];
   
   $('book').find('*').each(function() {
   
       if($(this).get(0).namespaceURI == NS) {
       
           var local = $(this).get(0).localName;
           var content = $(this).text();
           
           var domBit = local + ': ' + content;
           
           contents.push(domBit);
       
       }
   
   });
   
   $('<ul></ul>').appendTo('body');
   
   for(var i= 0; len = contents.length, i<len; i++) {
   
   
       var part = contents[i];
       $('<li></li>').text(part).appendTo('ul');
   
   
   }
    
});

As you can see, we test the namespace stored in the NS variable against the namespace contained in each element. Further, the localName property is used to access the local name of each element, that is, the string that comes after the ':' token in an XML full qualified name. Notice that I had to use the CSS universal selector to access the children elements of book because any other approach would return null or rise a JavaScript error.

Unfortunately, IE6 and 7 don't support the aforementioned DOM properties. However, if we insist on supporting obsolete browsers, we'll probably miss one important thing: the web is evolving and there's no time for dinosaurs.

Yahoo and Bing ignore Blogspot

That hurts. I've tried to type "fbml html validation" in Yahoo and Bing to check whether these search engines correctly index Blogspot's sites... nada, zippo, nichts. Generally, when you type these keywords on Google you get one of my posts among search results. This is not a surprise, of course. I think that some kind of war is currently going on. Probably this is due to the existing differences between the various search algorithms or perhaps to a little revenge against Google. That is, why Yahoo and Bing should pay attention to Blogspot given that this platform is run by Google? However, that's a pity.

CSS image gallery with jQuery

Last variation on the theme: an image gallery with CSS and jQuery. In this example, the main role is played by CSS because it actually creates the final effect of a gallery set on multiple layers. The effect in itself is not very complicated: it's only a matter of adding some vertical padding to the images placed on both sides. jQuery, instead, could be further enhanced by using some plugin (like Cycle, for instance). One thing to note is that everything is set in percentages. This is quite a challenge with CSS but it actually allows us to get the maximum flexibility required for this purpose.

CSS prototypes

After four years of CSS coding I realized the importance of prototypes applied to CSS. My approach to web development is essentially based on two steps: first structure (HTML), then presentation (CSS). I begin finding this approach too limited when I developed the Icosfitness front-end part. I actually had a series of screenshots and all the images that made up the graphics of such drafts. The problems started arising when some change needed to be applied to the drafts. In short, all the graphics had to be updated. This was really time-consuming.

But then it came the light at the end of the tunnel: I did read a fantastic book by Andy Clarke, Transcending CSS, where he emphasized the importance and role of CSS prototypes. One great method is the approach called grey boxes, as shown below:

All you have to do is drawing a grid system based on a series of boxes filled with solid colors and some sample text. As you can see, graphics come only later in the development process, so you don't have to get mad to handle a design that is still in progress. So our process is actually made up of three steps:

  1. structure (HTML)
  2. prototyping (CSS)
  3. presentation (CSS and graphics)

This approach is really flexible and useful. You'll find yourself sparing a lot of time without worrying too much about the final design.

jQuery: dealing with empty elements

From a DOM perspective, an element is said to be empty when it doesn't contain child nodes. In other words, an element is empty when its firstChild property is set to null. Consider the following markup:

<p id="test1"></p>
<p id="test2">  </p>

In this case, only the first paragraph is empty, because the second one contains some white-space that is considered as a text node. In jQuery we can only check whether an element contains other elements, for example by using the html() method or the length property, but in either case we have to know in advance what kind of element we're actually searching for. So we can write the following plugin in order to address the particular case showed earlier:

(function($) {


   $.fn.isEmpty = function() {
   
   
       if(this[0].firstChild == null) {
       
           return true;
       
       
       } else {
       
       
           return false;
       
       }
   
   };



})(jQuery);

This plugin checks only if the firstChild property of a given element is null or not. Once applied to our example, it returns the following results:

$(document).ready(function() {

  alert($('#test1').isEmpty()); // true
  alert($('#test2').isEmpty()); // false



});

As you can see, this turns out to be very useful when we're traversing the DOM in a while loop or when we want to get a map of our DOM tree.

jQuery: AJAX image gallery

So far we've seen AJAX content generated after a successful request triggered by a call-to-action. But this kind of content can actually be generated when the page is finished loading. A typical example is an image gallery retrieved from a server-side script like this:

header('Content-Type: text/xml');
  $xml = '<?xml version="1.0" encoding="utf-8"?>';
  $xml .= '<gallery>' . "\n";
  
  $dir = opendir('books');
  $images = array();
  
  while($fname = readdir($dir)) {
     
     if(preg_match('/[.]gif$/', $fname)) {
         
         $images[] = $fname;
         
     }
     
     
     
 }  
 
 closedir($dir);
 
 function imgSort($a, $b)
 {
     $a1 = str_replace('.gif', '', $a);
     $a2 = str_replace('.gif', '', $b);
     
     return $a1 > $a2;
     
 }
 
 usort($images, 'imgSort');
 


 
 foreach($images as $img) {
     
     $xml .= '<img>books/' . $img . '</img>' . "\n";
     
 }
 
 $xml .= '</gallery>';
 
 echo $xml;

This PHP script generates an XML file containing a list of images. We can fetch this file using jQuery, like so:

$(document).ready(function() {

    $('<ul id="gallery"></ul>').appendTo('body');
    var html = '';
    
    $.ajax({
        type: 'GET',
 url: 'gallery.php',
 dataType: 'xml',
 data: null,
 success: function(xml) {
 
     $(xml).find('img').each(function() {
     
         var url = $(this).text();
  html += '<li><img src="' + url + '" /></li>';
  
     
     
     });
     
     $('#gallery').html(html);
 
 
 }
 
    });

});

The above code generates an unordered list that contains all of our images. As you can see, the AJAX request takes place when the page is ready and without a call-to-action. You can see this demo here.

CSS and image layout

First of all, there's no reference in the current CSS 2.1 specifications to the layout used to display images. Images, in their essential form, are considered to be inline-block elements. This means that images can have a width, an height, borders, margins and padding but with few minor differences. In their default display role, images can only be affected by horizontal margins, for example. Usually a safe way to get more control over images is to turn them into block-level elements. By doing so, vertical margins are also allowed.

Technically speaking, an image is made up by replaced content, meaning that the actual content of an image is inserted in a web document by fetching an external resource. In that sense, an image behaves more like an object element and that explains why some W3C members proposed to remove the img element in favor of the object element.

In CSS, images can be handled either as inline-block elements (default) or as block elements. A good example of the former group are emoticons. This kind of images live inside a line of text. By default, their vertical alignment is baseline. Bear in mind, however, that they actually affect the overall height of a line. IE6 has an obtuse bug that makes it double the line height when that line contains an image. If you want to change the vertical alignment of such images, just write this:

img {vertical-align: middle;}

With this rule, images are now aligned with the middle line that intersects a line of text. Obviously the final effect depends on the font size and line height of the text. So if you have some text with a base font size of 12 pixels and an emoticon which is 10 pixels tall, everything should work just fine.

The latter group, instead, requires more attention. When you turn an image into a block-level element, all the rules of a block formatting context are then applied. A frequent question asked by many developers on the web is: "How can I adjust the dimensions of an image so that it fit the dimensions of its container?". Use percentages, like so:

img {
  display: block;
  width: 100%;
}

This technique works fine only if the intrinsic dimensions of the child image are equal to or greater than the actual dimensions of its parent element. So if you have a container which is 200 pixels wide and an image whose intrinsic width is 300 pixels, then everything will be ok. On the contrary, if the image is 100 pixels wide, then the image will be displayed distorted by the browser.

A field that would require some further investigation is when you try to turn images into something different from inline and block elements. For example, what happens to an image when it's displayed as a table cell? If I have more spare time in the future, I'll test that.

jQuery: the contains() selector

The jQuery's :contains(search) selector is a powerful feature that can actually enhance our ability to perform text searches. For example, given the following HTML:

<ul>
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>

We want to add a CSS class only to the list item that contains the word "one". Here's how it can be done:

$(document).ready(function() {

    $('body > ul').find('li:contains("one")').addClass('one');
    
});

As you can see, this selector comes attached to the element that is supposed to contain a given text. Below you can see the results.

jQuery: styling file inputs

File inputs are a kind of form controls that are almost impossible to stylize using only CSS. The problem is that this type of form controls is considered sensitive by all browsers due to the security implications that their CSS styles always imply. For example, file inputs cannot be hidden with the visibility property nor with the display property. But a couple of years ago this brilliant article enlighted new ways of handling this problem.

First of all, let's start with a basic form for handling file uploads:

<form action="" method="post">
<div class="file">
    <input type="file" name="file" id="file" />
</div>
</form>

See what's our goal? We want to assign a backgroud image to the container of the file input and then hide the file input itself. How? Before giving you an answer to this question, let's add some CSS styles:

div.file {
 width: 80px;
 height: 22px;
 background: url(file.gif) no-repeat;
}

div.file input {
 display: block;
 width: 80px;
 height: 22px;
}

Finally, we use the opacity property in a cross-browser way thanks to jQuery:

$(document).ready(function() {
    $('#file').css('opacity', '0');
});

I didn't test this solution in IE 6 and 7, so please let me know if something is wrong with these browsers. You can see this demo here.

jQuery: the end() method

jQuery's architecture is based on the concept of chaining. Everything in jQuery relates to a chain, usually called selector chain. A chain in jQuery starts with a selector and ends with a method, but there could be even more combinations. Since the direction of a selection moves from the first group of components on the left and ends with the last group on the right, sometimes it's difficult for web developers to add more methods to the first group of components. In other words, the jQuery's selector chain looks like a one-way path for selecting elements.

Fortunately, jQuery's developers introduced the end() method that allows us to move back to the first group on the left. For example, given the following code:

$('#test').find('div').addClass('foo');

You may want to add a CSS class to the element with the ID test as well. Here's how it can be done with the end() method:

$('#test').find('div').addClass('foo').end().addClass('test');

As you can see, this method tells the jQuery's engine to move back to the first selector in the chain. It's a very useful and powerful method that often spares us a lot of coding.

Matilde Romanato is growing up

Some breaking news from my little niece's world: she started walking about two months ago and now she's able to walk just like little children can do. But wait, there's more: she can say "mama", "tata" (dad), "grazie" (thanks) and some other words. She can also say "zia" (aunt) but not "zio" (uncle) (ok, so I should teach how to call me properly..). She's very friendly with other persons, especially with other children. She always smile at you and she's absolutely lovable. I'm very proud of her. We're very proud of her. I think that she resembles mostly her parents, especially in her temper. My smart brother and his wife have given us the best gift of ever.

CSS: default styles for XML elements

When dealing with CSS and XML is crucial to understand how XML is rendered by default in a web browser. Since XML has no default DTD associated with it, it's practically impossible for a web browser to give default styles to XML elements. In fact, XML elements have no default styles. Unlike HTML and XHTML elements, XML elements are all rendered as inline elements. It's up to the web developer to stylize XML elements. However, there are a couple of things you need to know before doing this.

The root element

The root element is not "magic" as in HTML. Its width and height and, consequently, its background color will not automatically stretch to cover the whole viewport. You have to manually set this behavior in your style sheet:

root {
    display: block;
    width: 100%;
    height: 100%;
    background: silver;
    min-height: 100%;
}

Class and ID selectors

Class and ID selectors have a different meaning in XML. In fact, they're not considered as a part of the default set of attributes of an element. So the following rules will fail:

element.foo {color: blue;}
section#bar {color: green;}

Instead, you should use attribute selectors for this task, like so:

element[class="foo"] {color: blue;}
section[id="bar"] {color: green;}

Namespaces

For namespaces, you must use namespace selectors, like so:

@namespace element 'http://www.site.com/ns/elements/element';

element|ns {color: blue;}

Default display roles

Since all XML elements are displayed as inline by default, you must explicitly set a default display role for each element in your style sheet using the display property and its values. Example:

para {display: block;}
item {display: list-item;}

PHP: top errors in MVC tutorials

Frustration is sometimes what we get from reading an online tutorial. Tutorials on implementing the MVC pattern in PHP are a good example of this. First of all, most of these tutorials don't explain clearly how the MVC pattern works, but only show practical examples of their implementation. Here are a couple of top errors in these tutorials:

  1. UML diagrams

    Only very few developers can actually understand a UML diagram. The best thing you can do is to draw some illustrated schematics which are more comprehensible.

  2. Lack of details on how classes are automatically loaded

    Web developers sometimes get confused by seeing a unique file containing the whole application, especially when they have a traditional procedural approach to PHP programming. Please devote most of your tutorial to this kind of explanation.

  3. Paths and URL rewriting

    You should always explain clearly how these two key aspects work and not provide only some code snippets to be copied and pasted. For example, you can add further details on URL rewriting by linking your tutorial to a tutorial on URL rewriting.

But the most important thing is: be clear. And never, never take anything for granted when it comes to your reader experience.

jQuery: AJAX response delay

When we develop an AJAX application we usually test it on our local web server first. However, this kind of test is not very reliable, because it doesn't take into account a possible delay that might occur when an AJAX transaction takes place. For testing purposes, it's useful to mimic such delay with our server-side language of choice. For example, here's a basic implementation in PHP:

header('Content-Type: text/plain');
sleep(3);
echo 'Request complete!';

The sleep() function delays the execution of our script by taking an integer (seconds) as its only argument. So our AJAX request will receive a response after 3 seconds. Done that, we can build up our jQuery code:

function addMarks() {
    var html = $('#loader').html();
    var mark = '>';
    $('#loader').html(html + ' ' + mark);
     window.setTimeout(addMarks, 1000);
   
}



$(document).ready(function() {

    $('#loader').hide();
    
    $('#response').ajaxStart(function() {
        $('#loader').show();
 addMarks();
    });
    
    $('#response').ajaxStop(function() {
        $('#loader').hide();
    });
    
    $('#run').click(function(e) {
    
        $.ajax({
     type: 'GET',
     url: 'delay.php',
     data: null,
     success: function(text) {
         $('#response').text(text);
  
     }
     
 });
 
 e.preventDefault();
    
    });

});

The addMarks() function has only a demonstrative purpose (you can use an AJAX spinner here) and simply adds a character to our AJAX loader after 1 second. So there will be three characters when our transaction is complete. Note that here we've used .ajaxStart() and .ajaxStop() for showing and hiding our loader. You can see this example here.

Animating SVG with jQuery

Although SVG elements can actually be animated using SMIL, sometimes it's preferable to use another approach. In this case we're going to use jQuery to animate a simple SVG graphic. Before we get through this topic, there are a couple of things that you have to know. First of all, you have to serve your documents as application/xhtml+xml. In fact, SVG doesn't work if you use text/html. Second, your documents must be well-formed or you get an XML parsing error. Now let's start with a simple SVG image embedded in an XHTML document:

<svg width="300px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg" id="svg-img">

   <desc>Sample logo</desc>
 
   
    <defs>
    
    
     <filter id="dropshadow">
     
     
     
      <feGaussianBlur result="blurredAlpha" in="SourceAlpha" stdDeviation="3" />
      <feOffset result="offsetBlurredAlpha" in="blurredAlpha" dx="3" dy="3" />
      <feFlood result="flooded" style="flood-color: black; flood-opacity: 0.65" />
      <feComposite result="coloredShadow" in="flooded" operator="in" in2="offsetBlurredAlpha" />
      <feComposite in="SourceGraphic" operator="over" in2="coloredShadow" />
     
     
     
     </filter>
    
    
    
    
    </defs>
    
    <polygon points="114, 61, 87, 211, 140, 211" style="filter: url(#dropshadow); stroke: #ddd; stroke-width: 1;
    stroke-opacity: 1; fill: #ccc; fill-opacity: 1;" />
 
  
</svg>

Now we can use jQuery:

$(document).ready(function() {

    $('#svg-img').css('position', 'relative');

    $('#animate').click(function(e) {
    
        $('#svg-img').animate({
     left: '100px',
     height: '0',
     width: '0',
     opacity: 'toggle'
     }, 'slow');
     
     e.preventDefault();
    
    
    });


});

This example works as expected in Opera, Safari and Chrome. Firefox 3.6 simply makes the SVG image disappear. You can see the final result here.

jQuery: AJAX and the live() method

Have you ever noticed what happens when an AJAX content is inserted in a web document? If you try to attach some DOM events to the newly inserted content, nothing happens. In jQuery there are two solutions to this problem. First, you can attach an event to the target element when the transaction is complete, for example by using the success method of the $.ajax() wrapper. This solution works fine, but there's a catch: if you have multiple target elements, your code is actually going to become unwieldy. The second solution, instead, it's a lot neater: simply use the live() method to attach an event handler to your target element.

The live() method simply keeps track of the current status of the DOM and reacts to any change that might take place on your document. In other words, this method observes the DOM status in order to allow us to add some further behaviors to it. Let's do an example. Suppose that we have a link that fires an AJAX transaction. On the server side, the content returned is an HTML element. You want this element to show an alert when clicked. First, our file is a plain text file that contains the following line:

<div id="foo">Click me</div>

Very simple. This element has an ID, so the first thing we need to do is using the live() method to attach an event to it:

$('#foo').live('click', function() {
    alert('I am foo!');
});

We've just attached our event to the AJAX element. Now we can perform the actual request:

$('#run').click(function(e) {

    $.ajax({
        type: 'GET',
 url: 'live-test.txt',
 data: null,
 success: function(text) {
     $(text).insertAfter('body > p');
 }
    });
    
    e.preventDefault();

});

Once clicked, our new HTML element will alert "I am foo!". You can see this test here.

YouTube's embedded videos are not valid HTML5

With HTML5 the embed tag is now recognized as a valid HTML tag. So I ran a simple test by copying and pasting a YouTube's embedded code into a web document, like so:

<div>
 <object width="640" height="385">
 <param name="movie" value="http://www.youtube.com/v/1-EguTJQm3s?fs=1&hl=en_US"></param>
 <param name="allowFullScreen" value="true"></param>
 <param name="allowscriptaccess" value="always"></param>
 <embed src="http://www.youtube.com/v/1-EguTJQm3s?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed>
 </object>
</div>

The W3C Validator says that:

An object element must have a data attribute or a type attribute.

End of games. Since YouTube uses the param element to fetch video's data, this error is really annoying and requires a manual check to make sure that the final code is in the correct form. However, if you add such attributes, you have to run additional tests to check whether your video works in all browsers. Hope they will fix this soon.

jQuery: basic content pagination

With jQuery it is possible to add simple but effective pagination effects to our documents. In this post I'd like to show you a basic implementation of content pagination. We start with a basic markup like this:

<div id="pagination"></div>

<div id="slider">

    <div>1</div>
    <div>2</div>
    <div>3</div>

</div>

So far we have an element which will contain our pagination links and three other content boxes inside a wrapper. Since we actually want our content to be displayed one box at time, we have to add the following CSS styles to our document:

#slider {
 width: 300px;
 height: 200px;
 overflow: hidden;
 background: gray;
}

#slider div {
 float: left;
 width: 300px;
 height: 200px;
 background: silver;
 line-height: 200px;
 text-align: center;
 font-size: 4em;
}

#pagination {
 width: 300px;
 margin-bottom: 0.5em;
 text-align: center;
}

#pagination a {
 margin-right: 0.3em;
}

Thanks to the overflow property we hide the exceeding boxes that will be shown later. Now, since the jQuery code requires a few more steps, it's better to show that code in a more useful order. First of all, we need to initialize our code when the DOM is ready, like so:

$(document).ready(function() {

// jQuery code here

});

Now we need to:

  1. assign a unique ID to each content box
  2. create pagination links with anchors that point to our IDs

The following code use some counters to perform this task:


    var idCounter = 0;
    var idName = 'slide-';
    var idRefs = [];
    
    var linkCounter = 0;
    
    $('#slider div').each(function() {
    
        idCounter++;
 
 $(this).attr('id', idName + idCounter);
 
 idRefs.push($(this).attr('id'));
 
 $(this).hide();
    
    });
    
    
    for(var i=0; i<idRefs.length; i++)     {
    
        linkCounter++;
        var id = idRefs[i];
 $('<a></a>').attr('href', '#' + id).text(linkCounter.toString()).appendTo('#pagination');
 
    
    
    }

We've simply created an ID whose name makes use of a progressive numbering, so we'll have slide-1, slide-2 and so on. Each ID is the result of a string concatenation between the ID name and its counter. Here I'm simply taking advantage of the loose typing of JavaScript, but if you want to be more accurate, use the toString() function on the counter. We use the idRefs array also for creating our pagination links. Note, however, that our content boxes are all hidden by default.

Let's move on our newly created pagination links and add the desired behavior to them. Here's the code:

 $('#pagination a').each(function() {
    
        var $a = $(this);
 
 $a.click(function(e) {
 
     var href = $a.attr('href');
     var $id = href.replace('#', '');
     
     for(var j=0; j<idRefs.length; j++) {
     
         var idRef = idRefs[j];
  
  if($id == idRef) {
  
      if($(href).is(':hidden')) {
      
          $(href).show(300);
      
      }
  
  } else if($id != idRef) {
  
      var ref = '#' + idRef;
      
      if($(ref).is(':visible')) {
      
          $(ref).hide();
      
      }
  
  
  }
     
     
     }
     
     e.preventDefault();
     
     
 
 });
    
    
    });

Again, we're using our idRefs array to check whether a box is currently visible or not. If a box is visible but it's not the target of our link, we hide it. On the contrary, if a box is the target of our link and is hidden, we show it. It's worth mentioning that browsers store anchor values with an hash before the actual value of the anchor, so for our example we've replaced it to make a comparison with our idRefs array. You can see the final result here.

Firefox: the Layout component

This is an interesting slideshow about the Layout component of the latest releases of Firefox. I have to say that during the last two years this component has been noticeably improved. With the new version 4, still in beta at the moment, Firefox's developers have boosted up the overall rendering speed. Further, now Firefox supports more CSS3 features than before.

jQuery: fading background colors

One of the most interesting parts of jQuery is its ability of adding nice visual effects with a minimum effort. I was developing an Ajax validation system for a contact form and I was strucked by the fact that my error messages were pretty plain. When a user made a mistake, an error message appeared and when he actually inserted the correct values, then the message disappeared. I did want to add some color effect to this transition, so I wrote this simple plugin inspired by the code of Douglas Crockford:

(function($) {

    $.fn.fade = function(speed) {
    
        speed = speed || 100;
 
 var level = 1;
 
 var node = this;
 
 var step = function() {
 
     var hex = level.toString(16);
     node.css({
         backgroundColor: '#ffff' + hex + hex
     });
  
     if(level < 15) {
         level += 1;
  window.setTimeout(step, speed);
     }
 
 
 
 };
 
 window.setTimeout(step, speed);
    
    
    
    };


})(jQuery);

The transition is pretty simple: the box first turns yellow and then fades to white in a time span defined by the speed parameter. There are a few gotchas to keep in mind with this code. First, to properly get a reference to the jQuery element, I've created a variable called node and I've stored that reference in this variable. Second, the setTimeout() function has been called using its complete hierarchy path, starting from the global window object. This avoids us any possible scope problem. You can see the final result here.

CSS: order of at-rules

With the introduction of the CSS3 @namespace rule most web developers get confused by the order in which the at-rules must appear. First of all, there are three types of at-rules that must be put at the very beginning of a style sheet: @charset, @import and @namespace. Before the adoption of the @namespace rule, the order was the following:

  1. @charset
  2. @import

Now the order has been changed, because the @namespace rule is at the bottom of the list:

  1. @charset
  2. @import
  3. @namespace

As you can see, the order reflects the new status of CSS at-rules.

jQuery, Ajax and accessibility

Most developers tend to overuse Ajax for the sake of the large amount of features and enhancements that can be added to a web application through this widespread technology. However, this abuse poses some major accessibility problems that I'd like to outline here by taking the jQuery library as an example of Ajax-enabled framework.

The problem of updated content

With jQuery is really easy to update the content of a given HTML element to reflect a change in the Ajax response. For example, we can use the load() method to insert some HTML code on a target element. The problem with this approach is that the overwhelming majority of screen readers won't be able to properly read the new updated content. A screen reader usually comes with an internal feature called virtual memory, that is, a buffer-based portion of its memory where it can load the entire content of a document and store it for later use.

Unfortunately, all screen readers have this option disabled by default, so if a user doesn't activate it, the entire document won't be kept in memory. From an Ajax perspective, this means that when you update an element with an Ajax response, the screen reader won't even notice it and it will continue to read the normal content. A simple solution in this case would be the WAI-ARIA roles. The problem with this solution is that is still under development and it will take some time to get a massive adoption by browsers and screen readers.

Further, a screen reader could even get confused and start reading the whole document again. Imagine what might happen if your page contains a lot of content.

The problem of links

Link targets should not be empty. Most developers use links with an empty href attribute and this is a bad practice. If a user-agent doesn't support Ajax, an empty link make it reload the entire document. Further, also dynamic links should be avoided. For dynamic links I mean those links created via JavaScript. Remember that screen readers can handle properly only certain DOM events, such as load. If your links are generated through a call-to-action that is fired with an event that screen readers don't support well (or don't support at all), then your links won't be generated.

You can use anchors (hashes) to make your links point to an effective portion of your page. This will avoid the problem of empty links and offer some kind of reference for browsers or agents that don't support Ajax.

The problem of widgets

Progress bars, spinners and the like are all nice Ajax widgets. However, since they're all made for a presentational purpose, they should not be inserted in the markup. Further, they should not convey any semantic information that could be possibly relevant for the correct use of a document. In other words, you should not rely on them, because it's always a good practice to provide alternate ways of informing a user.

The problems of events

Screen readers don't support DOM events very well. There's no universal rule to use with screen readers, because there are many differences among them. The only thing that we know for sure is that they support the load event. For other events, there's no rule of thumb for dealing with them, so you're warned.

jQuery: expanding menu items animation

Expanding menu items with jQuery is pretty straightforward. Thanks to the animate() method we can add some nice effects when a user hovers a link with his/her mouse. We can start from a simple navigation menu like this:

<ul id="navigation">
    <li><a href="#">Home</a></li>
    <li><a href="#">About Us</a></li>
    <li><a href="#">Contacts</a></li>
</ul>

Then we attach some styles to it:

#navigation {
 width: 10em;
 list-style: none;
 margin: 0;
 padding: 0;
 color: #333;
}

#navigation li {
 height: 100%;
 margin-bottom: 0.5em;
 line-height: 1.4;
 padding-bottom: 2px;
 border-bottom: 1px solid #999;
}

#navigation a {
 color: #338;
 font-weight: bold;
 text-decoration: none;
 border-left: 10px solid #fff;
}

#navigation a:hover {
 border-left-color: #999;
 background: #eee;
}

Finally, we can use jQuery:

$(document).ready(function() {


    $('#navigation li a').each(function() {
    
        var $a = $(this);
 var baseFontSize = $a.css('fontSize');
 
 $a.hover(function() {
 
     $a.animate({
        display: 'block',
        textAlign: 'center',
        fontSize: '1.5em'}, 'slow');
 
 }, function() {
 
     $a.animate({
         display: 'inline',
  fontSize: baseFontSize}, 'slow');
  
  
  
 });
    
    
    });


});

In this case we change only some CSS properties for each link and we restore them when we've finished, that is, when the user moves his/her mouse away from the link. Note that this code doesn't work in IE 6, 7 and 8. You can see the final result here.