State management
In traditional web development all logic runs on the server which handles all state. The server shows the page you clicked on, displays the right item in the menu. Context based content will be displayed in certain area’s. Certain buttons will be available others are not. After compiling the entire state of the webapp in a single HTML page it’s send to the browser where it’s displayed.
With Ajax we use a single page interface. There is no refresh. Thus all the above described state management has to be handled within the browser. Javeline Platform offers clean js API’s and an event system. We could use them to set the states of the components in the GUI. I actually did that for a couple of project. After a while I felt it became tedious to switch to JavaScript for this logic. We came up with a system that can do most of this processing automatically by just specifying what you want the state to be. Here is the first example:
<j:Frame caption="Example 1">
<j:Radiobutton id="rbPage" value="0">
Page 1
</j:Radiobutton>
<j:Radiobutton id="rbPage" value="1" checked="true">
Page 2
</j:Radiobutton>
<j:Radiobutton id="rbPage" value="2">
Page 3
</j:Radiobutton>
<j:Tab id="tbExample" activepage="[rbPage.value]">
<j:Page caption="Page 0" />
<j:Page caption="Page 1" />
<j:Page caption="Page 2" />
</j:Tab>
<j:Button id="btnBlah"
tooltip="[rbPage.value]"
onclick="alert(this.tooltip)"
caption="{'Value=' + rbPage.value}" />
<j:Textbox value="[rbPage.value]" />
</j:Frame>
Please note that I combined this example with the two below.
You can click around the tab and radiobuttons and change the number in the Textbox. Notice that the state of the components are interconnected. Lets take a look at the code. The radiobuttons look normal. We see each has a value ranging from 0 to 2. The middle one is checked. The first dynamic state is set on the activepage attribute for tbExample. It uses a state binding syntax: [rbPage.value]. The brackets tell Platform to create a two-way bind on that property; whenever the value of rbPage changes the activepage property of tbExample will change and vice verse. In the same way the tooltip property of the button is bound.
The other state syntax is used on the caption property of the button. The curly braces tell Platform to create a one-way bind. The curly braces allow javascript code. In this case the caption of the button is set by combining a string ‘Value=’ and the value of rbPage. More advanced javascript such as function calls is possible as well.
In both cases Platform will take care of setting all the necesary events and makes sure the states of the components are always in sync.
I believe in all projects I’ve done, it’s the visibility property that is used most often in state management. Especially in webapps that look like web sites. See the example below:
<j:Frame caption="Example 2 (Hint: Set Tab to 0)">
<j:Radiobutton id="rbShow" value="true">
true
</j:Radiobutton>
<j:Radiobutton id="rbShow"
value="false"
checked="true">
false
</j:Radiobutton>
<j:Label id="lblShow"
visible="[rbShow.value]"
height="20">
Radio is true
</j:Label>
<j:Label id="lblAdv"
visible="{rbShow.value=='true' and rbPage.value==0}"
width="200">
Tab 0 is active and radio is true
</j:Label>
</j:Frame>
Please be especially aware of this rule: {rbShow.value==’true’ and rbPage.value==0}. This is not entirely JavaScript. JavaScript uses && and || in conditional statements. The problem with && in XML is that you have to encode it so the line would become: {rbShow.value==’true’ && rbPage.value==0}. To prevent this use ‘and’ and ‘or’ in these conditional statements.
In certain cases you want to set the state of multiple components at the same time. This ’state of the application’ can be defined using a j:State component. By specifying a group you can toggle between two or more states:
<j:Frame caption="Example 3">
<j:State id="myState1"
value="false"
group="group1"
xvalue="true"
btnTest.caption="First State" />
<j:State id="myState2"
value="false"
group="group1"
xvalue="false"
btnTest.caption="Second State" />
<a href="javascript:group1.toggle()">Toggle States</a>
<j:Checkbox id="cbTest"
value="{group1.xvalue}"
values="true|false"
height="20" width="200">
Choose a state using the 2 links
</j:Checkbox>
<j:Button id="btnTest" caption="Start State"/>
</j:Frame>