State and Events

Jaxer provides four state contexts, with each state having its own container to persist values. To illustrate session state: when a user closes and then reopens a browser window of a web application yet remains logged in, the state of that user's session remains in effect.

Contexts

The four states, from the narrowest scope to the broadest, are:

  • Jaxer.sessionPage: Values stored in the private context of a single page and belong to a specific session, and as such will endure over the entirety of that session, expiring when the user's session expires.
  • Jaxer.session: A session is automatically created within the context of an application, expiring when the user's session expires. Session containers are not shared among applications so if a user is working with two distinct Jaxer web applications, that user has a separate session container for each application.
  • Jaxer.page: Persist values within the private context of a single page and shared within the application and among sessions. This is analogous to a static member of a class in Java—the container belongs to the page yet the values are static within the application. This container only expires when the Jaxer server is shutdown.
  • Jaxer.application: Stores values accessible within a single application. The application container is always available when any user accesses a page belonging to an application. An application container might be used to cache shared, rarely changed data originally loaded from disk or a database; your application code is reponsible for managing the cache and updating the session as necessary. This container and its values expire only when the Jaxer server is shutdown.

Using the State Containers

Even though each state is stored internally as a Jaxer.Container object, you don't interact though the Container API; instead, your code treats each state as if it were a normal JavaScript associative array:

Jaxer.session["username"] = "Bullwinkle";
var username = Jaxer.session["username"];
var exists = ("username" in Jaxer.session);
delete Jaxer.session["username"];
Jaxer.session = {};
Jaxer.application["app_key"] = "s0m3h4sh";
var app_key = Jaxer.application["app_key"];
var akExists = ("app_key" in Jaxer.application);

Passing Data to the Client

The Jaxer.clientData container is used to send data from the server to the client at the end of server-side page processing. Using Jaxer.clientData is a simpler technique to pass data to the browser at the initial page request than using hidden form elements to pass values.

When Jaxer begins to process a page at the server, Jaxer.clientData object is empty: {} . If you set any property on this object, the entire object will be serialized to JSON at the end of processing on the server, and will be automatically deserialized by Jaxer in the browser. This data is referenced in the browser also as Jaxer.clientData. If no data was added at the server, Jaxer.clientData is not created in the browser.

Session State and Scaling

Jaxer stores session state in the database it's configured to use. If scalability is required, it's best to configure Jaxer to use an external database instead of the internal SQLite database. Multiple Jaxer servers will then be able to share session data upon requests.

Jaxer and Event Handlers

Typically the interesting events in a web application occur on the client: a document finishes loading, the user clicks a link or submits a form, or hovers her mouse over an image. Because the events happen after the server completes its processing by default the events aren't available to handle with Jaxer.

Your code can, though, in unobtrusive fashion, assign handlers for events dynamically in processing the DOM before it gets streamed to the user's browser. Since one powerful use case for Jaxer is to build pages dynamically on the server Jaxer.setEvent() is a convenient way to assign such handlers.

function clickMe() {
  // do something interesting here
 }
 
var inp = Document.getElementById('someElement');

// your first instinct is the following line but it doesn't work:
// inp.onclick = clickMe;

// instead, use setEvent:
Jaxer.setEvent("onclick", input, clickMe);

// the generated client side code you'll see using View Source
// should be similar to:

Event Listeners

Your Jaxer apps can leverage window.addEventListener to hook into events in the browser in an unobtrusive manner. Jaxer adds the following events to those you can listen on:

  1. serverload
  2. aftercallbackprocessing
  3. load

Note that the window.onserverload and window.onaftercallbackprocessing event handlers have been replaced with values from the body element. Similarly, making the window.on<event> assignment after the body element will replace handlers specified in body attributes.

The behavior of events listeners assigned to the load event is controlled through the Jaxer.Config.ONLOAD_ENABLED configuration option as well as per-request via the Jaxer.onloadEnabled runtime value (which defaults to true). As always, the body's onload event handler is never executed server-side.