Web framework topics:

Getting started

To run the simpleSync example in clientServer mode:

scc -v -vs example/simpleSync/clientServer

This builds and runs a "hello world" web application using the framework layers: js.schtml, jetty.schtml, and js.sync. The -v option enables basic verbose logging and -vs enables verbose sync so you can see the client/server communication.

Use the same UI layer in server-only mode:

scc -v -vs example/simpleSync/server

There are three application layers in this example: model, UI, and server.

Model layer

file: example/simpleSync/model/HelloWorld.sc
object HelloWorld {
   String message = "hello";
   
   // The 'reply' using a binding in the server only layer
   String reply;

   // When message or reply change print them using 'reverse only' binding
   message =: System.out.println("--- Message: " + message);
   reply =: System.out.println("--- Reply: " + reply);
}

UI layer

file: example/simpleSync/ui/HelloWorld.schtml
<html>
<body>
   <form id="helloForm" onSubmit="return false;">
      <!-- value connects to message with a bi-directional binding  -->
      <input id="messageInput" type="text" value=":=: message" size="45"/>
      <!-- reply is set in a binding in the server layer -->
      <div><%= reply %></div>
   </form>
</body>
</html>

In schtml files, an html attribute can use an expression with or without data binding by prefixing the attribute value with the "=" operator, or one of the data binding operators: ":=", ":=:", or "=:".

Use just the = operator for a simple one-time assignment. Use a forward data binding to update the attribute when the expression's value changes. Use a reverse binding to go in the reverse direction: either updating a property, calling a method etc.

The <%= directive works like JSP to output an expression as content. When used in a declarative context, the expression uses a data binding expression so the content is updated incrementally.

Server-only layer

file: example/simpleSync/server/HelloWorld.sc
HelloWorld {
   // When the message changes, set the reply property.
   // Use server-only bindings like this for database queries or other logic
   // that should not run on the client.
   reply := "Server says: " + message;
}

For the server's version of the HelloWorld class, there's a forward binding which recomputes the value of 'reply' when the message property changes. The change to reply will be sync'd back to the client so the user sees that message printed in the JS console as well as the server's console.