« Screenshot example of simple form rendering | Main| En route (Meiten Sei?) to Developer2008 in Amsterdam »

Ask Dojomino Sensei: How do I replace the first element in my HTML body with Dojo?

Category    
Bookmark : del.icio.us  Technorati  Digg This  Add To Furl  Add To YahooMyWeb  Add To Reddit  Add To NewsVine 

Welcome to a new segment in the Dojomino blog, "Ask Dojomino Sensei". Our team has lots of questions we have to resolve for ourselves on a daily basis around the dojo toolkit, so we thought it'd be nice to start distributing that information here and give you a chance to pose questions too.

Today's topic: How do I replace the first element in my HTML body with Dojo?

This topic comes up when we think about our recent blog post about replacing Domino's default action bar with one that has dijit.form.Buttons. To do that, we know that Domino will produce the action bar as the first element in the body, a table. We'll need to grab that element, get what we need from it, and ultimately in our case, build a replacement for it and throw out the original table. To do that we're going to make use of dojo.body(), dojo.query(), and dojo.place().

There are 3 dojo core elements that we'll talk about here. The first is dojo.body(). Getting the body element from an HTML page should be a pretty simple task, and these days with modern browsers, document.body will pretty much do the trick. However, that wasn't always the case and dojo provides a little shortcut here to get the body element.

var body = dojo.body();

We know we need to fetch the first table in the document (the container of the action bar), so we can use dojo.query() to do so. It would be nice if we could use dojo.byId() or document.getElementById(), but since Domino (to date) doesn't do a very good job of putting the ID tag on any of its generated elements, we'll go the dojo.query() route. Some good information on dojo.query can be found here and here.

var actionTable = dojo.query('table')[0];

Now that we have a table, we can set an id on it by a simple actionTable.id = 'FormActionTable' statement. And here's where we can use dojo.query's capabilities in a little more interesting way. All the action "buttons" are actually just a href elements in table cells. So let's get those elements into an array that we can work with.

var actionsArray = dojo.query('table#FormActionTable td a');

This reads as, "find the table element with the id of FormActionTable and within its cells give me all the a elements as an array". Cool! What an easy way to navigate the DOM! It sure beats the heck out of dealing with the vagaries of how IE and FF handle child nodes manipulation. We'll leave the topic of working with that array, assume that we've gotten what we needed and created a new "replacement" action bar. Now we need to replace the original table with our new action bar. Removing the original table is pretty easy. We can do something like this:

actionTable.parentNode.removeChild(actionTable);

But how are we going to insert the new action bar as the first element in the body? With DOM, we can easily append a new element with body.appendChild(newBar), but that puts it after all the existing elements in body. We could also use DOM's insertBefore, but that requires that we know what element we want to go in front of. All of this is doable of course, but it's a pain. Enter dojo.place(). Dojo.place() allows us to specify the index of where we want to put our DOM node within another element. For example:

dojo.place(newBar, body, 0);

That lets us put the newBar node inside the body as the first element. Simple.

Comments

Gravatar Image1 - Nice article. Simple and clear.

Naturally I start thinking of extending this. For example, will this work for embedded views that are not at the top of the page? Is there a way to save your place in the dom?

Peace,

Rob:-]

Gravatar Image2 - I've got a new question for you. It may or may not be dojo related so you can always point me to another place for the answer.

I see that your primary domain name is dojomino.com but once I click on a link within your site I get dojomino.com/dojomino/blog.nsf plus some more stuff. This is how Domino works, I guess. I get the same thing on my web site, shaverassociates.net

I know from my experience that dojomino is a subdirectory in the Domino data directory. This directory contains the Notes database named blog.nsf which contains a view named d6plinks.

Question
Is there any way to shorten the URL so that it look like "blog.dojomino.com/d6plinks/LSPN-YL52DL" or "dojomino.com/blog/d6plinks/LSPN-YL52DL" or something like that?

Just a thought.

Peace,

Rob:-]

Gravatar Image3 - @Rob: dojo.place places the dom relative to the 2nd argument specified by the 3rd argument. So you can do something like this to replace an element further down the list:

var hai = document.createElement('div');
hai.innerHTML = 'o hai';
// nodelist is zero based
var gone = dojo.query('div')[4];
dojo.place( hai, gone, "before" );
dojo.query( gone ).orphan();


This will replace the 5th div on the page with "o hai". dojo.query and dojo.place are probably two of my favorite dojo commands.

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Documentation

Tutorials

Dojo Blogs

TripIt

RSS