★ wanayoo — archive 1999 http://developer.iplanet.com/viewsource/husted_jshtml.htmlNouvelle recherche | Portail wanayoo
 
           
 
Sun Microsystems Logo
Products and Services
 
Support and Training
 
 

Interleaving JavaScript With HTML
Browse
 
Downloads
 
Documentation
 
Product News
 
Support
 
For Developers
 
For Sys Admins
 
 
 
 

By Robert W. Husted


Send comments and questions about this article to View Source.


You're creating a server-side JavaScript (SSJS) application and find that you need to embed HTML in your JavaScript code in order to present users with truly dynamic pages. You use the write() function to explicitly print the required HTML, but your code ends up looking insanely messy with all those quote (") and escape quote (\") characters. If you accidentally forget to escape a quote, you'll introduce a bug into the code. And if you ever need to edit the HTML in your application, you'll find it difficult to read and to spot mistakes, which means you'll be spending a lot of time debugging while your friends play Quake II on the net.

Isn't there an easier way? Well, yes, there is. Unbeknownst to many developers and even to some folks at Netscape, you can "interleave" SSJS code with HTML, just like you can do with competing products. While not publicized, and not even mentioned in much of the existing documentation, this capability has been available since the inception of the LiveWire product (now called SSJS and included with the Netscape Enterprise Server). Indeed, interleaving was included in LiveWire by design. With interleaving, the SSJS code and the HTML are distinctly separate units; it's obvious where one stops and the other starts. The application looks cleaner and is easier to maintain.

You can also clean up your JavaScript code by using presentation templates to separate out the HTML, as detailed in the View Source article Using Presentation Templates with Server-Side JavaScript. Here I'll show you how to use interleaving by comparing interleaved HTML with embedded HTML in three different situations that you might run into when developing an SSJS application.

EXAMPLE 1: DISPLAYING HTML TEXT BASED ON USER INPUT

Okay, so in your SSJS application you want to display different HTML text depending on what the user has entered. Let's suppose that you want to display a search form when the user first accesses a given page, and on subsequent accesses you want to display database information (and not the form). How will you do it? Well, if you don't interleave the JavaScript code and the HTML, you'll have to embed the HTML in JavaScript write() statements as shown in Listing 1.


Listing 1. HTML embedded in JavaScript code
<BODY> 
...

<SERVER>
if (request.search) {

    // STATEMENTS THAT DISPLAY DATABASE INFORMATION GO HERE
}
else {
    write "<FORM NAME=\"myForm\" ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%5C&y=1999"thisPage.html\" METHOD=POST>";
    write "<INPUT NAME=\"search\" SIZE=30 MAXLENGTH=60>";
    write "</FORM>";
}
</SERVER>

...




The <SERVER> tags mark the beginning and end of the SSJS code executed by the server. Notice that the HTML is sandwiched between quotes in the write() statements. Any quote marks (") appearing in the HTML must be escaped (\"); otherwise, they'll cause JavaScript errors when you try to compile your application.

Using quote and escape quote characters makes your code all but unreadable. It's really difficult to pick out where the HTML begins and ends. If you later want to edit the HTML on the page, you'll have to worry about HTML and SSJS -- and if you accidentally forget to escape a quote character, you'll introduce bugs into the code. I can't tell you how many times this has caused me grief when creating an application.

To make the code more readable, what you can do is to end the SSJS code preceding your write() statements with a </SERVER> tag, dispense with the write() statements and instead insert the plain HTML, and then start the next section of SSJS code with another <SERVER> tag. This will result in the interleaved code shown in Listing 2.


Listing 2. HTML interleaved with JavaScript code
<BODY>
...

<SERVER>
if (request.search) {
    // STATEMENTS THAT DISPLAY DATABASE INFORMATION GO HERE
}
else {
</SERVER>

<FORM NAME="myForm" ACTION="/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2FthisPage.html&y=1999" METHOD=POST>
<INPUT NAME="search" SIZE=30 MAXLENGTH=60>
</FORM>

<SERVER>
}
</SERVER>

...
</BODY>


Notice how much easier it is to read the HTML in this fragment. The HTML looks like HTML now, rather than like some bizarre mutation. If you have to alter the form, you can do it easily. Without having to worry about escaping quotes, you've just monumentally reduced your chances of creating bugs in the application. Now, if only you could do this with client-side JavaScript! (You can't.)

EXAMPLE 2: DISPLAYING DATABASE QUERY RESULTS IN A FORM

Okay, now let's assume we want to do something trickier. We want to query a database and display the results in a form so that the user will be able to edit the database information easily. Normally, to do this we'd have to write something like the code shown in Listing 3.


Listing 3. HTML embedded in JavaScript code
<TABLE BGCOLOR=BLUE>
<TR BGCOLOR=LIGHTYELLOW>
  <TD><B>NAME</B></TD>
  <TD><B>JOB</B></TD>
  <TD><B>SALARY</B></TD>
  <TD> </TD>
</TR>

<SERVER>
if (dbConnection.connected()) {

    // EXECUTE SQL STATEMENT
    var cur = dbConnection.cursor(mySQLStatement);
    while (cur.next()) {
        write("<TR><FORM METHOD=POST ACTION=/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2F%5C&y=1999"update.html\">" +
        "<TD><INPUT TYPE=TEXT NAME=\"employee\" " +
        "VALUE=" + cur.ename==null?'':cur.ename) +
        " SIZE=20></TD>" +
        "<TD><INPUT TYPE=TEXT NAME=\"job\" " +
        "VALUE=" + cur.job==null?'':cur.job +
        "SIZE=20></TD>" +
        "<TD><INPUT TYPE=TEXT NAME=\"salary\" " +
        "VALUE=" + cur.sal*12 + " SIZE=20></TD>" +
        "<TD><INPUT TYPE=HIDDEN NAME=\"empno\" " +
        "VALUE=" + cur.empno + ">" +
        "<INPUT TYPE=SUBMIT NAME=\"UPDATE\" " +
        "VALUE=\"Update\" SIZE=20></TD>" +
        "</FORM>" +
        "</TR>";
    }
    cur.close();
}
</SERVER>

</TABLE>


Boy, does that suck! Try to figure out where the HTML form starts -- kinda hard, isn't it? If we need to change our HTML to do something like add another column to the table, we've got to read the messy JavaScript code very carefully and make our changes without introducing new bugs.

There's an easier way to do it. We'll simply interleave our HTML inside an SSJS while loop. To put the database values directly into our form fields as we display them, we'll put JavaScript variables inside backquote characters (`) in the HTML tags. (Note that backquotes work only inside HTML tags; they don't work inside the plain text portions of a document.)


Listing 4. HTML interleaved with JavaScript code
<TABLE BGCOLOR=BLUE>
<TR BGCOLOR=LIGHTYELLOW> 
  <TD><B>NAME</B></TD> 
  <TD><B>JOB</B></TD> 
  <TD><B>SALARY</B></TD> 
  <TD> </TD>
</TR>

<SERVER> 
if (dbConnection.connected()) {
    // EXECUTE SQL STATEMENT 
    var cur = dbConnection.cursor(mySQLStatement);  
    while (cur.next()) { 
</SERVER> 

<TR> 
  <FORM METHOD=POST ACTION="/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2Fupdate.html&y=1999"> 
  <TD><INPUT TYPE=TEXT NAME="employee" VALUE=`(cur.ename==null?'':cur.ename)` SIZE=20></TD> 
  <TD><INPUT TYPE=TEXT NAME="job" VALUE=`(cur.job==null?'':cur.job)` SIZE=20></TD> 
  <TD><INPUT TYPE=TEXT NAME="salary" VALUE=`cur.sal*12` SIZE=20></TD> 
  <TD><INPUT TYPE=HIDDEN NAME="empno" VALUE=`cur.empno`>

  <INPUT TYPE=SUBMIT NAME="UPDATE" VALUE="Update" SIZE=20></TD> 
  </FORM> 
</TR> 

<SERVER> 
    } 
    cur.close(); 
} 
</SERVER>

</TABLE>


Again, the HTML in this code actually looks like HTML. We can edit the HTML or the SSJS easily without worrying about causing problems in the JavaScript code. Even adding another column to this table would be remarkably easy, because we can clearly see the HTML.

EXAMPLE 3: QUERYING A DATABASE COLUMN AND GENERATING A SELECT LIST

Now let's try one last example. Certainly you've created forms that had list boxes in them (select lists). How do you use this technique to query a column in a database and then generate a select list? Well, let's look at how you would do it without interleaving (Listing 5), and then at how you can improve the readability of your code with interleaving (Listing 6).


Listing 5. HTML embedded in JavaScript code
<FORM ACTION="/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2Fdb2.html&y=1999" METHOD="GET"> 

. . .;

<SELECT NAME="state">

<SERVER>
if (dbConnection.connected()) {
    sql = "SELECT NAME FROM LU_STATE";

    // EXECUTE SQL STATEMENT
    cur = dbConnection.cursor(sql);

    while(cur.next()) {
        if (cur.name == request.name) {
            write("<OPTION SELECTED VALUE=\"" +
            cur.name + "\">" + cur.name);
        }
        else {
            write("<OPTION VALUE=\"" +
            cur.name + "\">" + cur.name);
        }
    }
    cur.close();
}

dbConnection.release();
</SERVER>

</SELECT>

. . .

</FORM>



Listing 6. HTML interleaved with JavaScript code
<FORM ACTION="/old?u=http%3A%2F%2Fdeveloper.iplanet.com%2Fviewsource%2Fdb2.html&y=1999" METHOD="GET">

. . .

<SELECT NAME="state">

<SERVER>
if (dbConnection.connected()) {
    sql = "SELECT NAME FROM LU_STATE";

    // EXECUTE SQL STATEMENT
    cur = dbConnection.cursor(sql);

    while(cur.next()) {
        if (cur.name == request.name) {
</SERVER>

<OPTION SELECTED VALUE=`cur.name`>

<SERVER>
            write(cur.name);
        }
        else {
</SERVER>

<OPTION VALUE=`cur.name`>

<SERVER>
            write(cur.name);
        }
    }
    cur.close();
}

dbConnection.release();
</SERVER>

</SELECT>

. . .
</FORM>


Okay, okay, so this last example isn't as dramatic as the previous one. However, notice that by interleaving in this last example we've made it much easier to quickly spot the <OPTION> tags and read them.

IN CLOSING

If you've never looked at a .web file, try it sometime -- it will help you better understand how interleaving works on the Enterprise Server. Basically, the JSAC compiler concatenates all of your HTML and JavaScript code into a single .web file. The SSJS code is compiled into JavaScript byte-code and appears intermixed with the HTML and client-side JavaScript. So your .web file is one big file with a bunch of HTML pages, JavaScript libraries (.js files), and compiled SSJS. When you request an HTML page within an application, the server parses this big .web file (which is resident in memory) and locates the specific page you want. As the page is sent to you, the server executes all of the SSJS byte-code it finds.

Interleave SSJS and HTML in your applications to make the code easier to read and understand. You can use this technique to conditionally display parts of a page without having to rely on JavaScript write() statements. This will make your maintenance efforts much easier and will greatly improve the readability of your code. For those of you who asked why we haven't provided this capability like our competitors have, there's your answer. We've always provided it . . . that's where they got the idea.


FURTHER RESOURCES


View Source wants your feedback!
Write to us and let us know
what you think of this article. 

The author wishes to thank Paul Dreyfus, JJ Kuslich, Willy Mena, and Basil Hashem for their timely assistance and encouragement.

Robert W. Husted is a technology evangelist at Netscape, focusing on the Netscape Application Server and server-side JavaScript. He enjoys spending time with his wife, Wanda, and their two children, Joseph (3) and Rebekah (1.5), who have recently learned how to open the refrigerator -- much to their parents' dismay. The couple's next child product, Girl 2.0 (code-named "Rachel"), is due out October 6, 1998. Three more product releases are planned in the 21st century.

(7:98)


Related Reading


Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use