The last example showed how to navigate 'upwards' in the RDF graph. By carefully defining the RDF graph and using the right triples we can usually navigate to any part of the RDF data that is necessary in order to get the right results. Usually, however you will want to iterate only over the children of a node using a <member> tag and use a <triple> or <binding> for each predicate of each child that you wish to display. This is the way that the template system was originaly designed to be used and many of the datasources used by Firefox and other Mozilla products work with datasources in this way.

A very uncommon form of navigation you can also do is to navigate upwards using a <member> tag, that is to get all the parents of a node, as in this example:

<conditions>
  <content uri="?start"/>
  <member container="?parent" child="?start"/>
</conditions>

This might be used, for instance, to start at a particular photo and find all of the containers that it is inside.

Sometimes you may wish to change the conditions at a later time. For example, you wish to user to be able to select a value from a list, and the template results should be filtered based on that value. This can be done by modifying the DOM nodes inside the conditions and rebuilding the template. For instance, to apply a filter, you might add a new <triple> element. To remove the filter, the <triple> should be removed again. Let's assume that we've given an id of 'cond' to the <conditions> tag.

function applyFilter(country)
{
  var cond = document.getElementById("cond");
  var triple = document.getElementById("filterTriple");
  if (country) {
    if (!triple) {
      triple = document.createElement("triple");
      triple.id = "filterTriple";
      triple.setAttribute("subject", "?photo");
      triple.setAttribute("predicate", "http://www.daml.org/2001/09/countries/iso-3166-ont#Country");
    }
    triple.setAttribute("object", country);
    cond.appendChild(triple);
  }
  else if (triple) {
    cond.removeChild(triple);
  }
  document.getElementById("photosList").builder.rebuild();
}

The 'country' argument to the applyFilter function holds the value to filter by. If this is set, we add a filter, otherwise we remove it. The code is fairly straightforward. A new <triple> element is created and the object attribute is set to the value to filter by. For example, the resulting triple for the Netherlands might be:

<triple subject="?photo"
        predicate="http://www.daml.org/2001/09/countries/iso-3166-ont#Country"
        object="http://www.daml.org/2001/09/countries/iso#NL"/>

This triple is then appended to the conditions. The triple is given an id so that it can be found later if a different filter is applied. Naturally, we only want to apply one filter at a time, so we can just reuse the same triple for each filter. When removing the filter, we only need to remove the triple from the conditions. This example only adds one triple, but you could add others, or add <member> elements. Whether a triple or member is added or removed, the template must be rebuilt by calling the rebuild method. This method will remove all of the existing generated content, delete all of the internal information pertaining to the results, and start again as if the template was just being examined for the first time. The template will be parsed again and the data examined for new results.

You can view a complete example of this in action. A menulist is used to allow one to select either a specific country, or select All to show all of the photos. When a choice is made, the applyFilter function as shown above is called and the template content gets rebuilt with the desired filter applied.

In this example, the menulist is hard-coded to contain the items that we know are in the datasource. Next, we'll look at also generating this list using a template.