This page has been archived. For the latest news on FormAssembly, go to: http://www3.formassembly.com/blog

Ajax Makeover : Client-side data management with XML (part 2)

XML Data Manipulation

In the first part of this article I explained how to create a DOM Document to maintain application data on the client-side. I will now explain how we can manipulate such data, using the DOM and Javascript. If you haven’t done so already, you may want to read about the personal time tracking application I am building, before continuing.

Adding a new task

In this application, the DOM document holds a list of tasks. Let’s see the XML for one task:

<task status="hold" edit="true" id="" >
<timetrack>
<timeslice startdate="" enddate="" />
</timetrack>
<label></label>
<category></category>
</task>

The status of a task defines whether its timer is running or not. The edit attribute determines if the task characteristics are editable or read-only. By default, a new task is editable. The Timetrack element will be used to record the periods of time during which the task was running.

I set up this XML as a separate file so that I can load it in the engine and keep it as a template for every new task.
var xmlNewTask= Sarissa.getDomDocument();
xmlNewTask.onreadystatechange = loadHandler;
xmlNewTask.load("/time-tracker/xml/tmpl_task.xml");

To add a new task, I simply need to clone the XML contained in xmlNewTask and insert it under the tasklist element of xmlTaskList.

function newTask() {
var task = xmlTaskList.firstChild.appendChild(xmlNewTask.firstChild.cloneNode(true));
task.setAttribute('startdate',(new Date()).toLocaleString());
task.setAttribute('id',randomId());
// ...re-paint user interface ...
}

Note that xmlTaskList and xmlNewTask are references to DOCUMENT_NODEs. In order to manipulate document trees we need to work with ELEMENT_NODEs. <tasklist>, the root element of xmlTaskList, is obtained with xmlTaskList.firstChild (same with xmlNewTask).

Modifying a task

setAttribute is the standard DOM method to modify an attribute. It will conveniently create the attribute if it does not exist. For instance, this will set the starting time of a task:

task.setAttribute('startdate',(new Date()).toLocaleString());

Modifying the text value of an element is a bit more complex. Take the <label> for instance. I first need to get a reference to the element, then retrieve its text node (usually its first child) and finally change the nodeValue property.

If I have already a reference to the task. I can use getElementsByTagName to find the <label> element. getElementsByTagName returns an array of elements, but since we will have only one label per task, the array will always have only one row, getElementsByTagName[0].

task.getElementsByTagName('label')[0].firstChild.NodeValue = ' new task label ';

Deleting a task

To delete a task I just need to remove the corresponding node from the document tree. With a reference to the node to delete and its parent, I can use:

parentnode.removeChild(nodetodelete);

In my XML, all task elements have the same parent, the root element ‘TaskList’, which I can access by xmlTaskList.firstChild.

function deleteTask(taskId) {
if(confirm('Are you sure you want to delete this task ?')) {
xmlTaskList.firstChild.removeChild(getTaskById(taskId));
}
//.. repaint interface ..
}

getTaskById is a custom function that, given a task id, returns a reference to the task element in the xmlTaskList DOM tree. I cannot use getElementById because this method doesn’t work in the context of a non-HTML DOM Document (at least for most browsers).

So I simply iterate the task elements until I find one with the given id attribute.
function getTaskById(taskId) {
for(var i=0;i < xmlTaskListRoot.childNodes.length; i++) {
if (xmlTaskListRoot.childNodes[i].nodeType == 1 ) {
if(xmlTaskListRoot.childNodes[i].getAttribute('id') == taskId)
return xmlTaskListRoot.childNodes[i];
}
}
return null;
}

The Ajax engine has now the basic methods to handle data. Next time, we will (finally) deal with the application interface, using XSL templates and XSL Transformation (XSLT).

Thanks for reading.

Technorati Tags: , , ,

One Response to “Ajax Makeover : Client-side data management with XML (part 2)”

  1. The World According To Buchs Says:

    Ajax-ified

    So, there’s this “new” technology on the web that’s all the rage. Except that it’s not really new, it’s been around for a while. People have just started to figure out how to cobble the bits and pieces together and d…