AJAX3D Tutorial 1:
Connecting X3D SAI to HTML DOM node events.

Here is the next step in developing AjaX3D. This sequence loads a "blank" scene, then updates the X3D scene to display a message when the user clicks a button on the HTML page. Here we see the basics of establishing a connection between the html host Document Object Model (DOM) events and the embedded X3D Scene Access Interface (SAI) - the “DOM" of X3D. That connection is then used to dynamically change content of the X3D scene using a simple interface of the html page.

Launch Hello AJAX3D!

Initially, nothing is displayed, then, when you click either
"Say Hello AjaX3D!" or "Say Hello X3D!" HTML button
either the Hello AjaX3D! or Hello X3D! text appears in the scene.

Setup: Embed X3D content in the page.
The X3D content is embedded in the html document using the technique shown in Tutorial 0. In this case the player is started with the scene Text node "empty":

.x3d
  <Text DEF="THETEXT" string='""'>

In the .x3d source code, the X3D node we wish to reference is assigned a DEF - the "ID" of X3D - equal to "THETEXT". We will load new Text node content dynamically using DOM and SAI.

The web page includes two buttons. The script provides html DOM onClick event handlers for the web page buttons then uses the event to trigger update of the X3D scene.

Step 1: When the page is loaded, get a handle to the X3D “Browser".
In X3D SAI, the term "Browser" actually refers to the web3D X3D viewing application. The html window onload event triggers the initX3Dbrowser() function. The statement:

dom.js
  web3Dbrowser = document.objectDOMID.getBrowser();

where objectDOMID is the html DOM object element ID string.
getBrowser creates reference to the X3D SAI "Browser" object.
web3Dbrowser represents the connection between the HTML DOM and the X3D SAI.
The 'live' DOM object can now be controlled to exchange events and data with the 'live' SAI "Browser".

Q: Why is this handle to the web3D X3D application SAI called "Browser"?
A: Well, one reason is that the web3D X3D application can freely browse to other 3D scenes. However, many have thought this terminology was a bit unfortunate and could lead to confusion with the containing “web browser” – but that’s the way it is and we need to live with it.

Step 2: Get a handle to the X3D SAI ExecutionContext.
Once we have a handle to the X3D browser, we can access the X3D SAI ExecutionContext object from the DOM as follows:

dom.js
  web3Dbrowsercontext = web3Dbrowser.getExecutionContext();

which allows the DOM to get access to all of the objects in the current embedded X3D scene through this web3Dbrowsercontext object.

Q: Why is this handle to the X3D SAI called an "ExecutionContext"?
A: Because everything is in there. But, too much information; we will answer some details of that question in a subsequent SAI tutorial. Just go with the flow for now…

Step 3: Get a handle to the X3D scene Text node.
The target scene contains an X3D Text node used to display objects within the 3D world. The X3D Text node is initialized with an empty string as shown above. We are going to change that in the next steps.

Here is the code to get a handle to the X3D Text node:

dom.js
  theText = web3Dbrowsercontext.getNode("THETEXT");

Once DOM has the Text node, the operative lines of the DOM script code send an event to the SAI Text node and the content changes.

Step 4: Set the Text node value.
When a button is clicked - here is where the action is – the script then sets the string property of the Text node. This property is defined as a multi-valued array, with one entry per line of text.

dom.js
  theText.string[0] = "Hello";
  theText.string[1] = "AJAX3D!";

Now when you click an html "Say Hello ..." button the DOM script tells the SAI to change the Text node which will cause a representation of the strings to appear in the X3D scene. You should see either “Hello AJAX3D!” or "Hello X3D" appear in the X3D scene because the X3D Text node is now as if it were written as:

.x3d
  <Text DEF="THETEXT" string='"Hello","AJAX3D!"'>

  or
  <Text DEF="THETEXT" string='"Hello","X3D!"'>

That is really all there is to have DOM<=>SAI interactivity. In this example the DOM has sent events to the SAI to control scene loading and scene content, while the SAI has provided its status and content to the DOM. Thus, SAI and DOM will work well together if the html/xhtml web browser permissions allow a scriptable object.

If you are not comfortable with this concept, just think of the X3D scene as using some of the host application services in a friendly and standardized way. These 'external' host services can do just about all the same operations on the scene as you might do with SAI scripts 'internal' to an X3D scene.
When you are comfortable with this idea, please consider the following details about loading and controlling the scene using host DOM services.

Advanced Info: Is the target scene running? Platforms will vary, but when the host document window.onload event is issued, we could grab a reference to the X3D browser and SAI execution context and hope that the target scene is already loaded and running - and it probably is. Looking at the html script initX3Dbrowser() sequence, in order to make absolutely sure we know when a particular scene is loaded, we can manage it closely.

First we start the X3D application with an "empty" scene. This is done by ommitting the object element src param. The DOM will handle this as if it were written:

dom.js
  <param name="src" value="">

The expectation is that when window.onload triggers, the player is already running with an empty scene. We can then set up a SAI<=>DOM connection that first tells us that the X3D browser is indeed alive, then that our initial target scene is loaded and running.

After DOM window onload we get a handle to the X3D “Browser" as shown in Step 1, above. When we have this, then we tell the SAI to "callback" when the scene is loaded and running.

dom.js
  // Connect SAI browserChanged event to DOM
  listener = new Object();
  listener.browserChanged = web3DbrowserChanged;
  // assign DOM browserChanged() handler
  web3Dbrowser.addBrowserListener(listener);

Now the DOM knows what to do when the SAI issues a browserChanged event.

When this callback is set, then we load the actual target scene:

dom.js
  web3Dbrowser.loadUrlS('helloAJAX3D.x3d');

When this scene is loaded and running, the SAI signals the host DOM with a browserChanged event. When the SAI sends browserChanged then the function web3DbrowserChanged is executed to obtain the current SAI execution context and node reference as shown in Steps 2 and 3, above.

This is discussed in more detail in the following tutorial.

Q. Why is the target scene loaded with loadUrlS instead of the ISO X3D SAI standard loadURL script interface?
A. For that, we will have to ask Tony. This interface name is certainly an artifact from a pre-standard implementation and we will have to hope he changes from "de-facto" to "de-speco" soonest.
If you are experimenting with an "other-than-Flux Player™" web3D browser, you will probably need to change this line of script.

Advanced Info: Reusing the SAI execution context. Looking at the onclick functions, please notice that we have obtained SAI execution context and node reference in global variables after we know the scene is loaded. Then we are able to repeatedly 'reuse' the existing execution context and node reference each time a button is pressed.

Refresh/Reload Example page to restart.

Next step Tut2 - Connect DOM to SAI node events

This AjaX3D tutorial start

AJAX3D.org Tutorials

Original Author: Tony Parisi  tparisi@mediamachines.com
last updated: October 12, 2006
This version by: Joe D Williams  joedw@hypermultimedia.com
last updated: October 15, 2006