UCOSP End of Term Results Part 1

Announcements

How fast the time flies. It feels like the kickoff sprint for the UCOSP term was just last week, but the two months have passed already. The students have all finished their contributions for this term, and are now busy with exams. Our final student bloggers both had plenty to say and included some good technical content, so I’ve split the term summary into two parts. For this post, let’s hear from David Clarke of Laurentian University:

“Being able to contribute to BlackBerry open source projects has been a real treat. While I am still inexperienced with GitHub, it was great experience to be able to use it in a real world scenario. I knew from the start that I would focus my efforts in the local web apps portion of BlackBerry WebWorks and bbUI.js.

After quickly getting a basic HTML5 web app up and running on my BlackBerry Dev Alpha B, I was keen to dig into creating a BlackBerry specific web app that matched the look and feel of the new BlackBerry 10 operating system. Having had great success, I wanted to share a bit of insight into the key areas for accomplishing this.

If you are like me, you may be used to loading JavaScript on particular HTML pages and then using a window.onload function to get things started.

window.onload = function() {
	//some code!
}

You might do this to grab some data from HTML5 local storage and load some values into your HTML page. With bbUI.js, you won’t be doing this quite the same way! Instead you’ll be using Screens. bbUI.js uses AJAX to load new screens instead of regular old links to load new HTML pages. When loading a new screen, you’ll typically use code like this:

onclick="bb.pushScreen('mypage.htm', myPageID);"

This says to load the new screen myPageID using the code in the mypage.htm file. Simple enough, but now we want to run some JavaScript when this new page (screen) loads and perhaps change or add some elements to the resultant screen.

The key to understand how to use your JavaScript in conjunction with Screens lies with the onscreenready and ondomready functions. Take a look in the index file of the sample bbUI.js app, you’ll see bb.init function and within its constructor, you’ll see code for onscreenready and ondomready. The key difference between these two is that onscreenready represents the HTML code before it is inserted into the DOM, and the ondomready represents the HTML code after it has been inserted into the DOM.

If you are used to using window.onload and accessing the DOM with document.getElementById(‘myEleID’), then you’ll want to put your code within either onscreenready or ondomready instead. Both of these will fire when you load a new screen, first onscreenready, then ondomready. In order to target a particular screen with particular JavaScript code you would have some code like the following:

ondomready: function(element, id) {
	if (id == 'myPageID') {
		document.getElementById('myEleID').innerHTML = locallyStoredData;
	} else if (id == 'someOtherPageID') {
	//more code
}
}

As we saw above, to push a new screen into view you use onclick=”bb.pushScreen(‘mypage.htm’, myPageID);”, now when ondomready is triggered, we use a simple if else statement to determine what code to execute based on which screen was loaded.

So great, myPageID was loaded, and then document.getElementById(‘myEleID’).innerHTML = locallyStoredData; gets executed. This works, and is similar to what we are used to seeing. DOM manipulation, however, can be quite taxing on the system, and you will see a noticeable delay if you try to execute your DOM manipulation from ondomready when you are first loading a screen. To avoid this, we need onscreenready.

onscreenready loads the target screen’s HTML into memory, but it is not yet in the DOM. That means simply moving the code from ondomready to onscreenready won’t work:

onscreenready: function(element, id) {
	if (id == 'myPageID') {
		document.getElementById('myEleID').innerHTML = locallyStoredData; //Fail!
	} else if (id == 'someOtherPageID') {
		//more code
	}
}

This will generate an error: Uncaught TypeError: Cannot set property ‘innerHTML’ of null

Instead, when targeting items by ID, you’ll want to use element in place of document, like so:

onscreenready: function(element, id) {
	if (id == 'myPageID') {
		element.getElementById('myEleID').innerHTML = locallyStoredData; //Success!
	} else if (id == 'someOtherPageID') {
		//more code
	}
}

Further still, if you want to call a function located in another JavaScript file, you’ll want to pass element along, so you can manipulate the pre-DOM HTML data.

onscreenready: function(element, id) {
	if (id == 'myPageID') {
		doThisFunction(element);
	}
}

…

function doThisFunction(element) {
//still uses *document* for new elements
var newParagraph = document.createElement('p'); 
newParagraph.innerHTML = "A new paragraph.";

//use *element* to target existing pre-DOM elements
element.getElementById('myEleID').appendChild(newParagraph);
}

You’ll notice that in your external JavaScript function, you’ll still need to use document when creating new elements, but in order to insert them into your pre-DOM HTML you’ll want to use element instead of document to target existing elements.

So if you’ve been having difficulties interacting with the DOM in your bbUI.js web app, hopefully this small tutorial was helpful! Of course, the best way to learn bbUI.js is to take a look at some sample applications. I’ve had a blast working with bbUI.js and I am almost ready to submit my first web app to the BlackBerry App World.”

Quality tips that should help other new developers make the most of their time with bbUI.js and BlackBerry 10. Stay tuned for part 2 of the end-of-term blog posts to get hear from our final student contributor, see a summary all that we did this term, and what’s next.

About Tim W.

Tim works on the Developer Relations team at BlackBerry, focusing on WebWorks, HTML5, and Open Source.

Join the conversation

Show comments Hide comments
+ -
blog comments powered by Disqus