|
|
Advanced Tutorial - More Bindings - Some new bindings
SUMMARY
This step looks beyond the basic binding which were created in the 'introductory' tutorial and creates bindings to list components.
FURTHER READING To review the basic bindings go to the 'introductory' tutorial In this step we will go into some more detail on how the model can be used to bind to page components and in the next step we will see how the model can be manipulated to restore the model state. We will begin by rearranging the welcome page as follows... Listing 1 - welcome.xml
<Label x="10" y="5" w="80" h="20" style="prompt" content="WEL_LANG" alignment="Left"
opaque="true"/>
<Combo name="languageList" x="90" y="5" w="120" h="20"/>
<Label x="230" y="5" w="350" h="60" style="Heading" content="WEL_TEXT"
alignment="Left" opaque="true"/>
<Panel x="0" y="60" w="650" h="60" style="Heading">
<Label x="120" y="5" w="130" h="60" style="prompt"
content="Would you like to..." alignment="Left" opaque="true"/>
<RadioButton name="createRadio" x="250" y="5" w="200" h="20" style="data"
content="Create a new application" alignment="Leading"/>
<RadioButton name="openRadio" x="250" y="25" w="200" h="20" style="data"
content="Open an existing application" alignment="Leading"/>
</Panel>
<Panel name="createPnl" x="0" y="150" w="650" h="50">
<Panel x="0" y="0" w="650" h="50" style="banner/prompt">
<RadioButton name="soleRadio" x="226" y="15" w="100" h="20"
style="banner/prompt" content="WEL_SOLE" alignment="Leading"/>
<RadioButton name="jointRadio" x="330" y="15" w="100" h="20"
style="banner/prompt" content="WEL_JOINT" alignment="Leading"/>
</Panel>
</Panel>
<Panel name="openPnl" x="0" y="120" w="650" h="150" style="Heading">
<Label x="120" y="5" w="80" h="20" style="prompt" content="Files:"
alignment="Left" opaque="true"/>
<ScrollPane x="220" y="5" w="200" h="100" vertical_scrollbar="always">
<List name="fileList" x="0" y="0" w="200" h="100" style="data"
SelectionMode="0"/>
</ScrollPane>
</Panel>
The welcome text has been moved and two new radio components will give the user the option of creating a new mortgage application or working with an existing one. The existing radio buttons which specify a Sole or a Joint Application have been embedded within a named panel createPnl. The panel is named so that it's visibility can be set from the Java code. Another panel has been defined which contains a new list component fileList Next, we need to hook up some events to the new radio components. Listing 2 - welcome.xml
...
<Event method="createApp" target="createRadio" type="ItemHandler"/>
<Event method="openApp" target="openRadio" type="ItemHandler"/>
...
The createApp and openApp events are defined in the Welcome class as follows... Listing 3 - Welcome.java
...
public void openApp()
{
createPnl.setVisible( false );
openPnl.setVisible( true );
}
public void createApp()
{
createPnl.setVisible( true );
openPnl.setVisible( false );
}
...
The above code assumes that references to the panel components have already been created using the findComponent call. Now in the welcome.xml file, create two more bindings for the createRadio and fileList components. Listing 4 - welcome.xml
...
<Bind target="createRadio" source="temp/createApp" output="temp/createApp"/>
<Bind target="fileList" source="applications" output="temp/filename"/>
...
Again the Welcome class needs to be modified to populate the applications node in the model when the page is created. The loadFiles function is called from the pageCreated function. Listing 5 - Welcome.java
...
private void loadFiles()
{
String dir = System.getProperty( "user.dir" );
appsMdl = ( XBaseModel )rootModel.get( "applications" );
File folder = new File( dir + "\\files" );
File files[] = folder.listFiles();
for ( int i = 0; i < files.length; i++ ) {
String name = files[ i ].getName();
XBaseModel filMdl = new XBaseModel ( appsMdl, name, name );
}
updateBindings();
}
...
The function begins by getting the project directory and then getting a reference to the applications node in the model which is being bound to by the fileList component. It then checks the contents of the files directory. This is a new folder which you have to create in your project directory. Before proceeding with the saving and opening of files, we need to change the checkCreateSetup and add a new validation checkOpenSetup to check that a file has been selected when the openRadio is checked. Listing 6 - Welcome.java
...
public Integer checkCreateSetup()
{
int level = XBaseValidator.LEVEL_IGNORE;
if ( createRadio.isSelected() && ( !jointRadio.isSelected()
&& !soleRadio.isSelected() ) )
level = XBaseValidator.LEVEL_ERROR;
return new Integer( level );
}
public Integer checkOpenSetup()
{
int level = XBaseValidator.LEVEL_IGNORE;
if ( ( ! createRadio.isSelected() ) && ( fileList.getSelectedIndex() == -1 ) )
level = XBaseValidator.LEVEL_ERROR;
return new Integer( level );
}
...
The declarations for the validation are as follows... Listing 7 - validations.xml
...
<validation name="openApp" type="function" msg="Please select a file to proceed!"/>
...
Listing 8 - welcome.xml
...
<Validation rule="openApp" target="languageList" method="checkOpenSetup"/>
...
In order to prepare for the next step in the tutorial, we can add the openApp function which will take care of opening a selected file in the next step. Listing 9 - Welcome.java
public void openFile()
{
String filename = ( String )fileList.getSelectedObject();
// to do - add open code
updateBindings();
}
Now, we need to change the Finish page to allow the model to be saved to file. This had been done in the introductory tutorial but we want to allow the user to specify the filename which will be used to save the file. Listing 10 - finish.xml
<XPage prev="finance" class="net.xoetrope.mortgage.Finish">
<Components>
<Label x="150" y="60" w="100" h="20" style="prompt"
content="Filename:" opaque="true" />
<Edit name="filename" x="250" y="60" w="200" h="20" style="data" />
<Button name="saveBtn" x="220" y="100" w="160" h="30" style="Heading"
content="Save Application" opaque="true" />
</Components>
<Events>
<Event method="save" target="saveBtn" type="ActionHandler"/>
</Events>
<Data>
<Bind target="filename" source="temp/filename" output="temp/filename"/>
</Data>
<Validations>
<Validation rule="filename" target="filename"/>
</Validations>
</XPage>
The page now has a text component and a save button. The text component has been bound to the same model node as the fileList on the welcome page is outputting to. The Finish class now looks like this... Listing 11 - Finish.java
public class Finish extends NavigationHelper
{
private XModel filenameMdl, createMdl;
private XEdit filenameText;
public void pageCreated()
{
filenameMdl = ( XModel )rootModel.get( "temp/filename" );
createMdl = ( XModel )rootModel.get( "temp/createApp" );
filenameText = ( XEdit )findComponent( "filename" );
}
public void pageActivated()
{
boolean enabled = createMdl.get().toString().indexOf( "Create" ) > -1;
filenameText.setEditable( enabled );
if( filenameText.isEditable() )
filenameText.setText( "" );
}
public void save()
{
String filename = null;
boolean create = createMdl.get().toString().indexOf( "Create" ) > -1;
if ( create && ( checkValidations() != XBaseValidator.LEVEL_IGNORE ) )
return;
if ( create )
filename = filenameText.getText();
else
filename = ( String ) filenameMdl.get();
// to do - add saving code
}
The pageCreated method creates references to the models we are interested in and also to the filename text component. The pageActivated method checks the content of the createMdl model node and sets the filename text component to enabled or disabled accordingly. The save method checks to see if a file is being created or amended. If it is creating a file, the text component will be blank and the checkValidations method needs to be called to make sure that a file name has been entered by the user. Finally, the filename validation as referred to in the finish xml file is defined in the validations file... Listing 12 - validations.xml
<validation name="filename" type="mandatory" msg="Please enter a filename!"/> Log in or register to download the source code for this step. |