# Jaxer WikiLite Guide [edit]

This page explains the WikiLite sample application included with Jaxer.

## Introduction to the WikiLite application

Your Jaxer installation includes an example of a very basic Wiki web application. This simple application allows you to enable text editing, write a few text characters, save your text to a file, and reload your data into the web page when you re-enter or refresh the page.

The diagram below shows the basic flow of this application.

Image:WikiLiteOverview.png

This application consists of a single HTML file (WikiLite/index.html) that contains style information and a bit of JavaScript. Open this page in Aptana Studio to follow along as the following sections walk you through the application code.

## Viewing the sample application

Your Jaxer installation (whether as a standalone Jaxer Package or in Aptana Studio) includes the WikiLite application.

To access the WikiLite application from within Aptana Studio:

1. In the Samples View, expand the Aptana Jaxer folder.
2. Select the WikiLite example.
3. Click either the Preview Sample button to do a quick preview of the sample, or click the Import Sample button to import the sample as a project into your workspace.

To access the WikiLite application from a standalone Jaxer Package installation:

1. Navigate to your Jaxer installation folder, and double-click the StartServers.bat file.
2. In your web browser, navigate to the following URL: http://localhost:8081/aptana/
3. From the column on the left, click the Apps and Tools link.
4. Click the WikiLite link.

## About the client-side WikiLite code

Before we what happens on the server with the WikiLite application, let's take a look at the client-side code, including how the web page is laid out.

### Style information

The `head` tag of this web page contains some basic CSS styling, contained in a set of `style` tags:

`[html,N]<style> html { height: 95%; width: 99%; padding: 0; margin: 0; } body { font: 10pt verdana; font-family: verdana; height: 100%; padding: 10px; margin: 0; } #contents { width: 100%; height: 95%; } #editOrSave { width: 100%; } .readonly { font: 8pt verdana; background-color: #f0f0ff; border: none; padding: 8px; } </style>`

This styling formats the text area slightly differently than the rest of the page. The `.readonly` class displays the `textarea` with a different font and background color when the page is in read-only mode.

### The `body` area

The body of the HTML page consists of a single text area and an input button:

`[html,N]<body onserverload="init()">`

<textarea id="contents"></textarea>

<input type="button" id="editOrSave" onclick="editOrSave()">

</body>

The `textarea` holds the contents of the wiki, and the `input` button has an `onclick` event handler that toggles the "edit" functionality on when the page is read-only. The button also saves the textarea contents when the page is in "edit" mode.

Note: The `body` tag also has an `onserverload` event handler. We'll discuss the functionality of this event handler later on in this article.

### Client-side scripting

The `head` tag contains a `script` tag with the JavaScript for the WikiLite application. Five of the functions in this `script` tag perform client-side functionality:

- `init()`
- `setEditing()`
- `$()`
- `editOrSave()`
- `checkValid()`

#### `init()`

The <tt>init() function is called when the page loads. It sets the page to read-only mode on the page load. It also calls the `readAndFill()` function, which reads the contents of a file and displays them in the `textarea` on this page. We'll discuss this in more depth later on in this article.

`[javascript,1]function init() { setEditing(false); readAndFill(); }`

#### `setEditing()`

The `setEditing() function sets the mode (read-only or read-write) of the contents area by using the <tt>readOnly` and `className` attributes of "contents". If the "contents" are not "editable", the "contents" are then "readonly".

This function also sets the value of the `editOrSave` button. If the "contents" are read-only, the button reads "edit". If the "contents" are "editable", the button reads "save", and the function sets the focus to the "contents" area, so that a user can easily type something in the `textarea`.

`[javascript,1]function setEditing(editable) { $("contents").readOnly = !editable; $("contents").className = editable ? "" : "readonly"; $("editOrSave").value = editable ? "save" : "edit"; // set the button label if (editable) { $("contents").focus(); } }`

#### `$()`

The `$()` function is a simple helper function to get elements by ID. If you were coding this on your own, you could choose to use the `$()` function of your favorite Ajax library.

`[javascript,1]function $(id) { return document.getElementById(id); }`

#### `editOrSave()`

The `editOrSave()` function first determines if you are already in edit mode or not. If you are in edit mode, it does a quick validation check on the contents of the text area, and if these validate, saves the contents and re-sets the page to read-only mode.

If the contents are not valid, `editOrSave()` throws an alert containing a message describing the error.

If you are not in edit mode, `editOrSave()` simply toggles off the read-only mode for the contents `textarea`.

`[javascript,1]function editOrSave() { var isEditing = !$("contents").readOnly; if (isEditing) // try to save and get out of edit mode { try { var contents = $("contents").value; checkValid(contents); save(contents); setEditing(false); } catch (e) { alert(e); } } else // go into edit mode { setEditing(true); } }`

#### `checkValid()`

The `checkValid()` function does a quick validation check on the number of characters input into "contents". If a user types more than 10000, it throws an error message saying "Too long!".

`[javascript,1]function checkValid(contents) { if (contents.length > 10000) { throw "Too long!"; } }`

### Server-side scripting

Now that you have a basic idea of how the page is set up and how it functions, we'll examine how this page interacts with the Jaxer server. By adding server-side functionality, we're able to save the text that you type into "contents" and have it persist from one session to another.

Since we'll be running our JavaScript on the server, we need to specify this in our `script` tag. If you look at the `script` tag in our sample code, you'll see that we've added a `runat="server"` attribute:

`[html, N]<script type="text/javascript" runat="server">`

#### Determining which functions run where

Out of the functions described in the above section, we'll need several of them to be available both on the client and on the server. On line 54, we set the `setEditing` function to be available to be run on both:

`[javascript,N]setEditing.runat = "both";`

We need this function available both on the server when we prepare the page and on the client when the user toggles editing mode on and off.

On line 60, we set the `$()` function to run at both:

`[javascript,N]$.runat = "both";`

This is so that we can perform various Ajax functionality and DOM manipulation on both the front and back end of the application.

On line 93, we also set the `checkValid` function to run at both:

`[javascript,N]checkValid.runat = "both";`

We need to be able to validate the contents on both the client and the server. The client performs an initial check, but the server validation catches anything not caught by the client.

Because the `editOrSave` function is only applicable to the client, we set its `runat` value to "client"only.

`[javascript,N]editOrSave.runat = "client";`

Finally, remember the `init()` function that was attached to an event handler in the `body` tag? We want the page to be initialized when the server loads, so this is when we specify for `init()` to be called:

`[html,N]<body onserverload="init()">`

### Server-side functions

The WikiLite application has three functions that are specific to server-side functionality:

- `readAndFill()`
- `getFilePath()`
- `save(contents)`

#### `readAndFill()`

The `readAndFill()` function gets the contents of a file that is obtained by calling the `getFilePath` function. It checks if a file exists at the filepath, and if the file exists, gets the file contents and sets the value "contents" to those file contents. If the file does not exist, `readAndFill()` leaves "contents" blank.

`[javascript,1]function readAndFill() { var filePath = getFilePath(); var fileExists = Jaxer.File.exists(filePath); $("contents").value = fileExists ? Jaxer.File.read(filePath) : ""; }`

#### `getFilePath()`

The `getFilePath()` function returns the "contents.txt" file. (This has been hard-coded for the sake of the demo application):

`[javascript,1]function getFilePath() { return "contents.txt"; }`

#### `save(contents)`

The `save(contents)` function normalizes newline characters for Windows and Mac and then does an additional validation check on the contents. `save` then finally writes "contents" to the file at `getFilePath`.

`[javascript,1]function save(contents) { contents = contents.replace(/\r\n/g, "\n"); // normalize newlines for Windows/IE; contents = contents.replace(/\r/g, "\n"); // normalize newlines for Mac; checkValid(contents); Jaxer.File.write(getFilePath(), contents); }`

We set the proxy value of this function to "true" so that the function can be called from the client, but the contents are actually saved on the server.

`[javascript,N]save.proxy = true;`

## Testing the WikiLite application

This section walks you through a few quick tests to see how the functionality of the WikiLite application works. You'll add some text to the page, save that text to a file on the server, and perform a validation check both on the client and then on the server.

### Editing and saving text

To test the functionality of the WikiLite application:

1. With the index.html file for the WikiLite application open, click the Firefox tab to preview the application in Firefox. The preview should look like the screen below.

   When the page loads, the `onserverload` event triggers the `init()` function, which in turn calls the `setEditing` function to set the text area to read-only. The `init()` function also calls `readAndFill` which reads the contents of a remote file (if it exists) and fills the text area with those contents .

   Image:WikiLite1.png

2. Click the edit button.

   WikiLite enables the text area for typing, which switches from a blue background to a white background. It also changes the name of the button from "edit" to "save". These events happen as a result of calling the `editOrSave` function.

3. In the text area, type a few characters, and click the save button.

   Clicking save calls `editOrSave` again and toggles edit mode off. It also calls the `save` function, which normalizes whitespace, validates the text contents, and writes the contents to a file on the Jaxer server.

### Validating the text area contents

The `checkValid` function checks whether the text entered into "contents" meets its validity criteria. As currently written, the text must simply be less than 10000 characters. This function is run on the client when it is called by the `editOrSave` function, and it is also run on the server when it is called by the `save` function. To test this function yourself, you can make a couple of minor changes to the code.

To test validity checking on the client:

1. Go to the `checkValid` function on line 87 in index.html.
2. Change the length limit from 10000 to 10 (shown below):

   `[javascript,1]function checkValid(contents) { if (contents.length > 10) { throw "Too long!"; } }`

3. Test the client-side validation:
   1. Click the Firefox preview tab to preview the page in Firefox.
   2. Click the edit button to toggle on edit mode.
   3. In the text area, type over 10 characters of text.
   4. Click the save button.

      The WikiLite app displays a "Too long!" error telling you that the text that you entered is too long.

To test validity on the server:

1. Leave the `checkValid` function with the modification that you made above.
2. Comment out the validity check on the client-side:
   1. Go to the `editOrSave` function (line 63).
   2. Comment out line 71, where the `checkValid` function is called (shown below):

      `[javascript,1]function editOrSave() { var isEditing = !$("contents").readOnly; if (isEditing) // try to save and get out of edit mode { try { var contents = $("contents").value; //checkValid(contents); save(contents); setEditing(false); } catch (e) { alert(e); } } else // go into edit mode { setEditing(true); } }`

   3. Test the client-side validation:
      1. Click the Firefox preview tab to preview the page in Firefox.
      2. Click the edit button to toggle on edit mode.
      3. In the text area, type over 10 characters of text.
      4. Click the save button.

         The WikiLite app displays a "Too long!" server error telling you that the text that you entered is too long.

   ## Complete WikiLite application code

   The following code sample is the entire page of code for the WikiLite application:

   `[html,1]<html>`

   <head>

   <title>WikiLite</title>

   <style> html { height: 95%; width: 99%; padding: 0; margin: 0; } body { font: 10pt verdana; font-family: verdana; height: 100%; padding: 10px; margin: 0; } #contents { width: 100%; height: 95%; } #editOrSave { width: 100%; } .readonly { font: 8pt verdana; background-color: #f0f0ff; border: none; padding: 8px; } </style>

   <script type="text/javascript" runat="server">

   function init() { setEditing(false); readAndFill(); }

   function setEditing(editable) { $("contents").readOnly = !editable; $("contents").className = editable ? "" : "readonly"; $("editOrSave").value = editable ? "save" : "edit"; // set the button label if (editable) { $("contents").focus(); } } setEditing.runat = "both";

   function $(id) { return document.getElementById(id); } $.runat = "both";

   function editOrSave() { var isEditing = !$("contents").readOnly; if (isEditing) // try to save and get out of edit mode { try { var contents = $("contents").value; checkValid(contents); save(contents); setEditing(false); } catch (e) { alert(e); } } else // go into edit mode { setEditing(true); } } editOrSave.runat = "client";

   function checkValid(contents) { if (contents.length > 10000) { throw "Too long!"; } } checkValid.runat = "both";

   function readAndFill() { var filePath = getFilePath(); var fileExists = Jaxer.File.exists(filePath); $("contents").value = fileExists ? Jaxer.File.read(filePath) : ""; }

   function getFilePath() { return "contents.txt"; }

   function save(contents) { contents = contents.replace(/\r\n/g, "\n"); // normalize newlines for Windows/IE; contents = contents.replace(/\r/g, "\n"); // normalize newlines for Mac; checkValid(contents); Jaxer.File.write(getFilePath(), contents); } save.proxy = true;

   </script>

   </head>

   <body onserverload="init()">

   <textarea id="contents"></textarea>

   <input type="button" id="editOrSave" onclick="editOrSave()">

   </body>

   </html>

   ## Related Topics

   - About the Jaxer server
   - Getting Started with Jaxer in Aptana Studio
   - Creating a new Jaxer project
   - Previewing a Jaxer project
   - About Jaxer Views
     - Displaying the Servers View
     - Displaying the TailView View
     - Displaying the Jaxer Activity Monitor View
     - Displaying the Jaxer Shell View
   - Configuring your Jaxer servers
   - Setting your TailView preferences
   - JaxerManager_Command_Line_Interface_(CLI) Reference
   - Jaxer sample application guides
     - Getting started with Jaxer development using the Tasks sample application
     - Inside the Jaxer Chat application
     - Running the Jaxer server diagnostic tools

Retrieved from "http://aptana.com/docs/index.php/Jaxer_WikiLite_Guide"

Category: AptanaHelp