Archive

Archive for August, 2009

DATA pt. 4 – Running from Command Line and Logging

August 31st, 2009 Ali Faiz No comments

This is part of the continuing series of articles on Developing Appcelerator Titanium Applications (DATA)

Running Titanium Apps from the Command Line

To run a Titanium app using a command line script as opposed to starting it up through the Titanium Developer App, we placed the following in a file named run.sh inside our app’s directory.

export PATH=$PATH:/Library/Application\ Support/Titanium/sdk/osx/0.6.0/
tibuild.py -d . -s /Library/Application\ Support/Titanium -r -a /Library/Application\ Support/Titanium/sdk/osx/0.6.0 ./

The tibuild.py does our work for us and running ./run.sh from the command line starts our app up without having to open the Titanium Developer App.

Logging

This is a short blurb on the difference between Titanium logging and Firebug’s logging. At the top of our Javascript file we have the following try/catch statement to setup our log var.

try {
    var log = Titanium.App.stdout; // Titanium's logging to the command line
} catch (squash) {
    var log = console.log; // console logging for Webkit/Firebug
}

The try/catch is an easy way to ensure we have the right logging for the right environment. We want TItanium logging when running Titanium and console.log as the default.
Calling logging is simple from this point:

 log('HELLO!');

Technorati Tags: , , ,

DATA pt. 3 – File I/O with jQuery and Titanium

August 25th, 2009 Ali Faiz No comments

This is part of the continuing series of articles on Developing Appcelerator Titanium Applications (DATA)

Opening an XML file dialog in Titanium

The props variable specifies that only xml files will be highlighted and accepted in the file dialog. In order to highlight and accept all file types, just make props and empty array: var props = {};

var props = {multiple:false,types:['xml']};
Titanium.UI.openFileChooserDialog(function(filenames) {
	if (filenames[0]){
		Editor.load_file(filenames[0]);
	}
},props);

Reading an XML file

Here are the ways to read an xml (or any) file using both jQuery and Titanium. In both examples, lambda represents a function pointer.

jQuery

	$.get(filename,lambda);

Titanium

	var f = Titanium.Filesystem.getFile(filename);
	var xml = ""+f.read();
	lambda(xml);

Writing an XML file

This of course can only be done with Titanium. Below is how we formatted the xml to pretty print the xml string before writing out to the file. The raw xml string doesn’t lay out nicely so we have to add some spacing.

formatXml: function(xml, lambda) {
    var formatted = '';
    var reg = /(>)(<)(\/*)/g;
    xml = xml.replace(reg, '$1\r\n$2$3');
    var pad = 0;
    jQuery.each(xml.split('\r\n'), function(index, node) {
        var indent = 0;
        if (node.match( /.+<\/\w[^>]*>$/ )) {
            indent = 0;
        } else if (node.match( /^<\/\w/ )) {
            if (pad != 0) {
                pad -= 1;
            }
        } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
            indent = 1;
		} else {
            indent = 0;
		}
 
        var padding = '';
        for (var i = 0; i < pad; i++) {
            padding += '  ';
		}
 
        formatted += padding + node + '\r\n';
        pad += indent;
	});
    lambda(formatted);
},

Below is the code that actually writes out to the filesystem. If the file represented by the filename already exists, the write simply overwrites it. If the file doesn’t exist, a new one with that filename is created. Because of the way we had to parse the xml read in, it was necessary to tack on the the xml header.

try {
	var TFS = Titanium.Filesystem;
	var file = TFS.getFile(filename);
	Editor.formatXml(Editor.currentopenfile.filexml, function(xml) {
		header = '<?xml version="1.0" encoding="UTF-8"?>';
		file.write(header+xml);
		var contents = file.read();
	});
} catch (squash) {
	alert("Failed to write to File");
}

Technorati Tags: , , , ,

DATA pt. 2 – Accessing the DOM with jQuery

August 20th, 2009 Ali Faiz No comments

This is part of the continuing series of articles on Developing Appcelerator Titanium Applications (DATA)

The many ways to access the DOM with jQuery

In part 1 of this series, I ended the post with stating that I would follow up with how we accessed the DOM with jQuery and why we weren’t always using the best way to do it. Given more time, we would likely have gone back and changed all methods of accessing the DOM to be consistent.
Below are 3 ways that we used to access the DOM. It is almost a chronological journey through how we figured out the different methods.
For this part, as I did in my last post, I’ll be using the PushToTest datasource as an example.

Here again is the html used to render a datasource.

<div id="datasources_iterator${id}" class="datasource_container">
	<input type="hidden" name="id" value="${id}" fieldset="datasource"/>
	<table cellpadding="0" cellspacing="0" border="0">
		<tr>
			<td>Name</td>
			<td><input type="text" name="name" value="${name}" fieldset="datasource" class="name"/></td>
			<td><input type="image" name="delete" value="${id}" src="images/cross.png" fieldset="datasource"/></td>
		</tr>
		<tr>
			<td>Type</td>
			<td>
				<select id="datatypeselect${id}" name="datatypeselect" fieldset="datasource">
				  	<option value="HashDPL">HashDPL</option>
				  	<option value="CSVDPL">CSVDPL</option>
				  	<option value="RDBMSDPL">RDBMSDPL</option>
				  	<option value="TheLocker">TheLocker</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>Resource Name</td>
			<td><select id="rscname${id}" datasourceid="${id}" name="rscname" fieldset="datasource"></select> (From Resources)</td>
		</tr>
	</table>
</div>

The Unique ID Approach

The simplest way to manipulate the DOM with jQuery is using the id based method.
In the html we have datatypeselect drop down menus.

<select id="datatypeselect${id}" name="datatypeselect" fieldset="datasource">
  	<option value="HashDPL">HashDPL</option>
  	<option value="CSVDPL">CSVDPL</option>
  	<option value="RDBMSDPL">RDBMSDPL</option>
  	<option value="TheLocker">TheLocker</option>
</select>

For each individual datasource displayed, there is a datatypeselect drop down with a unique id associated with that element.
Here is the javascript to set the value of the datatypeselect for a given datasource object. This follows the method for populating the html we covered in part 1 of this series.

$("#datatypeselect"+datasource.id).val(datasource.datatypeselect);

The ‘#’ at the beginning of the selector signifies that we’re selecting based on the id attribute of the html element. The value is being set to the datasource object’s datatypeselect field.

The div ID Approach

This approach is similar to the Unique ID Approach, but instead of using the id for the particular element, we can use the id for a parent of this element. This forces us to only have a unique id at the parent level instead of a unique id for each individual html element.

The parent of the datatypeselect element in the html:

<div id="datasources_iterator${id}" class="datasource_container">

Here’s the javascript for this approach to accessing the datatypeselect element:

var divid = '#datasources_iterator'+datasource.id;
$(divid+ ' select[name=datatypeselect]').val(datasource.datatypeselect);

The Parent Selector Approach

This approach uses the same divid as the div ID Approach above but we pass the selector as an argument. Here we also use the fieldset attribute to give greater specificity to the jQuery selector.

$('select[name=datatypeselect][fieldset=datasource]', $(divid)).val(datasource.datatypeselect);

Ultimately we want to strip our html elements to the bare minimum of what we really need to access and manipulate their values and get away from using unique ids for each element.

Technorati Tags: , , , ,

Developing Appcelerator Titanium Application (DATA) pt. 1 – A series of articles on lessons learned…

August 20th, 2009 Ali Faiz No comments

The Application: PushToTest TestMaker

As part of our work on the PushToTest TestMaker open source project, we ran into numerous issues and resolutions that we felt should be shared.

Some background on what we used:
- Appcelerator Titanium Developer
- Javascript
- jQuery 1.3.2
- jQuery template plugin
- jQuery scrollTo plugin
- ExtJS 3.0 rc 3

First Issue To Address

One of the key first issues we ran into was how to render the html using jQuery on the client side for the Titanium application without doing too much manual DOM manipulation. Also, since most of the information being rendered would be in arrays, it would preferably make displaying arrays easier.

The Solution

Our solution came in the form of the jQuery template plugin.
For our implementation, we created html code snippets that we placed in individual html files. Each html file would be loaded and be passed into the $.template method which would then be passed into a .append method along with an object whose values would be injected into the html.

The reason why templating and more specifically why breaking the html into snippets was necessary is almost entirely because we wanted to be able to iterate through multiple objects and display them the cleanest and most efficient way possible.

Example with the PushToTest Datasource

For an example I’ve lain out how we rendered the information for datasources. Datasources are objects that have names, types, and resource names.
First we created a datasources.hmtl page that will be a container for all the datasources rendered:

<div class="panelmessage">
Make this a data-driven test.
</div>
 
<div class="form">
	<div class="title">
		Data Production Libraries (DPLs) provide operational test data to the tests as they operate. For example, a DPL reads data from a relational database, comma-separated-value (CSV) file, or data generating object and injects it into a test script. <a id="ShowTutorials" name="ShowTutorials" class="link">Read more about it.</a>
	</div>
	<div id="datasources_iterator" style="display:none" class="">
	</div>
	<div class="adddatasource">
		<a id="adddatasource" name="adddatasource" class="link" dirty="true">Add DPL</a>
	</div>
</div>

Then, we created a _datasourcestemplate.html file with all the attributes for a datasource specified:

<div id="datasources_iterator${id}" class="datasource_container">
	<input type="hidden" name="id" value="${id}" fieldset="datasource"/>
	<table cellpadding="0" cellspacing="0" border="0">
		<tr>
			<td>Name</td>
			<td><input type="text" name="name" value="${name}" fieldset="datasource" class="name"/></td>
			<td><input type="image" name="delete" value="${id}" src="images/cross.png" fieldset="datasource"/></td>
		</tr>
		<tr>
			<td>Type</td>
			<td>
				<select id="datatypeselect${id}" name="datatypeselect" fieldset="datasource">
				  	<option value="HashDPL">HashDPL</option>
				  	<option value="CSVDPL">CSVDPL</option>
				  	<option value="RDBMSDPL">RDBMSDPL</option>
				  	<option value="TheLocker">TheLocker</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>Resource Name</td>
			<td><select id="rscname${id}" datasourceid="${id}" name="rscname" fieldset="datasource"></select> (From Resources)</td>
		</tr>
	</table>
</div>

Then in the javascript we use this code to get that content and template it:

	$.get('content/_datasourcestemplate.html', function(html) {
        Editor.datasourcesTemplate = $.template(html);
    });
 
	for (var i=0;i<Editor.currentopenfile.datasources.length;i++) {
		var datasource = Editor.currentopenfile.datasources[i];
		$('#datasources_iterator').append(Editor.datasourcesTemplate, datasource);
	}

Using this method we were able to iterate through the datasource objects and inject them into the template, then append it to the datasources.html page.

Post implementation lessons

As you can see in the _datasourcestemplate.html code, we placed the datasource object’s id all over the place. Originally this was needed because of the way we were using jQuery to get values from the DOM. After doing some more research we found out better ways to gain access to the DOM which is what I will cover in the next post.

Technorati Tags: , , , ,