Hello World Tutorial Part 2: Adding Buttons and JavaScript

This part of the Hello World tutorial explores how to add logic to your XML documents. Without code to support a user interface, e.g., to respond to menu item selections and button presses, or to initialize fields in a dialog, your Trixul-based application is going to be pretty useless. We will build upon the previous example by adding a text field and a button. The button, when pressed, will invoke some code that we will create in JavaScript. This code will read the contents of the text field, and then it will launch another dialog to display the value that it retrieved. Let’s start by looking at the code from Part 1 of the tutorial:

<window name="main" title="Trixul Hello World" main="true" width="250" height="100">
    <spacer/>
    <box orient="horizontal">
        <spacer/>
        <statictext string="Hello World!" width="100" height="20" >
        <spacer/>
    </box>
    <spacer/>
</window>

The above code displays a static (non-editable) text field in the center of the window. We need to change a following things in this window:

  • Convert the statictext widget to a text widget so that we can edit the text.
  • Add a <script> element to the document that references the JavaScript code (which we will write, below) that implements the functionality we seek
  • Add a button to the UI that, when clicked, will invoke the JavaScript code mentioned above

The first step seems easy, just open an editor, replace the statictext element with a text element:

<window name="main" title="Trixul Hello World" main="true" width="250" height="100">
    <spacer/>
    <box orient="horizontal">
        <spacer/>
        <text editable=”true” selectable=”true” string=”Hello World!” width=”100" height=”20" />
        <spacer/>
    </box>
    <spacer/>
</window>

The element is nearly the same as statictext. The “editable” attribute is used to specify if the text field can be edited or not, and the “selectable” attribute tells Trixul that users can select the text (and then copy it to the clipboard, or paste over the selected text).

So, now that we have done this, the next step is to bring in some code. We do that, just like in HTML and XUL, with the script element:

<window name="main" title="Trixul Hello World" main="true" width="250" height="100">
    <script type=”text/javascript” src=”resources/content/tutorial.js”/>
    <spacer/>
    <box orient=”horizontal”>
        <spacer/>
        <text editable=”true” selectable=”true” string=”Hello World!” width=”100" height=”20" />
        <spacer/>
    </box>
    <spacer/>
</window>

As you can see, the script tag loads the script tutorial.js. We’ll discuss the code later, but let’s complete the UI first by adding a button, as follows:

<window name="main" title="Trixul Hello World" main="true" width="250" height="100">
    <script type=”text/javascript” src=”resources/content/tutorial.js”/>
    <spacer/>
    <box orient=”horizontal”>
        <spacer/>
        <text editable=”true” selectable=”true” string=”Hello World!” width=”100" height=”20" />
        <spacer/>
    </box>
    <spacer/>
    <box orient=”horizontal”>
        <spacer/>
        <button label=”Click Here” />
        <spacer/>
    </box>
    </window>

Here is the resulting UI:

Ok, on to the JavaScript. Our goal is simple — when the “Click Here” button is clicked, we will call a function found in tutorial.js called “ClickHereHandler”. To map the code to the button, all we need to do is provide an onlick attribute for the button, and give it a value containing the appropriate JavaScript code for calling ClickHereHandler():

<window name="main" title="Trixul Hello World" main="true" width="250" height="100">
    <script type=”text/javascript” src=”resources/content/tutorial.js”/>
    <spacer/>
    <box orient=”horizontal”>
        <spacer/>
        <text editable=”true” selectable=”true” string=”Hello World!” width=”100" height=”20" />
        <spacer/>
    </box>
    <spacer/>
    <box orient=”horizontal”>
        <spacer/>
        <button label=”Click Here” onclick="ClickHereHandler();"/>
        <spacer/>
    </box>
    </window>

For now, we’ll just make ClickHereHandler() empty:

function ClickHereHandler()
{
    // do nothing
}

This is the general pattern one follows for linking UI to JavaScript code. Most of the time, you will either be responding to button clicks, or menu item selections. In either case, an attribute like onclick contains JavaScript code that is executed when the button click, or the menu item selection, is made.

Of course, our function so far is pretty useless (but it is also pretty bug free). Adding the needed functionality is where things get interesting. Recall our goal: we want to extract the value typed by the user into the text field, and then create and display a second dialog that displays that text in a static text field.

To extract the data from the text field, we can make use of the DOM. The DOM is, effectively, a data structure that contains a representation of each of the elements in the dialog. The text field, and the button, and the primary objects represented in the DOM. We can use the built in JavaScript document object to call functions that allow us to obtain objects that represent elements like the text field and the button. And then, we can call functions that these objects implement to do things like get or set the value in the text field, or even change the label of the text button.

The primary way in which we find objects is the DOM is by 1) associating a unique ID with an element when we create the XUL document describing the window or dialog and then 2) at runtime, calling document.getElementById(id) from our JavaScript code, where id is the unique ID associated with the element we want to find. (Those of you familiar with w3 DOM APIs will no doubt recognize this paradigm. Trixul, at this point in time, doesn’t come close to implementing a complete API as defined by w3, but this may change in the future if there is enough interest.) Here is code to get a JavaScript object associated with the ID “mytext”:

var obj = document.getElementById("mytext");
if (obj) {
    // we got the object
} else {
    // element with ID "mytext" does not exist in the DOM
}

To get the value of the text field is a pretty simple matter of referencing the object’s “value” attribute, like this:

var obj = document.getElementById("mytext");
if (obj) {
    var value = obj.value;
} else {
    // element with ID "mytext" does not exist in the DOM
}

Once the above code is executed, the variable named “value” will contain whatever text had been typed into the text field before the code was executed.

The next step is to create a dialog to display the value retrieved by the preceding code. The design of the dialog is similar to what we have developed so far.