NEFS Sampler Tutorial


Table of Contents

Objectives
Learning Objectives Checklist
Assumptions
Downloading Java Developer's Kit (JDK)
Application Server (Servlet Container)
Starting the NEFS Sampler
Trying the NEFS Sampler Application Online
Setting up the NEFS Sampler Application on Your Own App Server
Downloading the Sampler Application
Setting up the Sampler Application
Testing the Sampler Application in a Browser
NEFS Sampler Objectives
Viewing the XDM Code
Viewing Project Folder and Files
Sparx Navigation Tree Overview
Introduction to Navigation Declaration Tags
NEFS Sampler Main Components
Home
Forms Input
Text
Numbers
Boolean
Selection
Conditional Select
Grids
Conditionals
Popups
Date/Time
Advanced
Forms Execution
Director
Templates
Handlers
Inheritance
Delegation
Access Control
Change Role
Test 1
Test 2
Test 3
Play
Sitemap
Console
Sample Apps Home
Conclusion

Objectives

Welcome to the NEFS Sampler Tutorial (Tour)! This tutorial aims at giving you a tour of the NEFS Sampler. It facilitates your learning by reducing the learning time through quick familiarization with various Sampler sections. You don't have to worry about learning the use of Sampler. Instead, you can concentrate on the core concepts being highlighted by the Sampler sections.

Learning Objectives Checklist

At the end of this tutorial, you should be able to understand:

  • the objectives of NEFS Sampler

  • how to set up the NEFS Sampler at your application server

  • how to view the XDM code within NEFS Sampler

  • purpose of NEFS Sampler sections

  • usage of NEFS Sampler sections

Assumptions

For the purpose of this tutorial, we will be assuming that you installed the following:

We assume that you are using the default port 8080 for your web server. If you chose different values for the installation path and the port number, you should substitute the paths and the URLs in our example with your values as needed. This tutorial also assumes your familiarity with XML, SQL, Java, Servlets and JDBC.

Downloading Java Developer's Kit (JDK)

Since NEFS comprises Java libraries, a fundamental requirement to develop applications with it is a Java SDK (the full SDK is required, the JRE will not be enough). You can obtain Sun’s official Java SDK from its Java web site at http://java.sun.com/j2se/1.4/download.html. This is a link to the Java 1.4 SDK but Java 1.2 and 1.3 will also work.

Application Server (Servlet Container)

Since Sparx works with standard J2EE application servers, a Servlet container is required if you're going to use Sparx. Both Axiom and Commons work in web-based or non-web-based applications but Sparx is a web application development library so an application server with a Servlet 2.2 or better container is necessary. Sparx-based applications have been tested on the following application servers:

[Note]Note

We recommend the Caucho Resin application server if you're not familiar with other Servlet containers or if you're new to Java/J2EE application servers. It's an easy to install, easy to use, and fast Servlet container with advanced features that rival other more expensive application servers such as WebLogic and WebSphere. Resin is free for development use but requires a paid license before putting your application into production use. Rest assured though that all Sparx-based applications you write, even on Resin, will remain app-server neutral.

Starting the NEFS Sampler

There are two ways of exploring the NEFS Sampler:

Trying the NEFS Sampler Application Online

You may test the Sampler Application online at http://www.netspective.com/corp/products/frameworks/try All you need is a web browser and you can start using the NEF Sampler immediately.

Setting up the NEFS Sampler Application on Your Own App Server

You may download the NEFS Sampler application as app-server-independent .war file. The Sampler Application's .war file includes all of the NEF binary files, resources and everything you need to use NEF. Once you have downloaded the .war file, you have everything you need to start modifying and adding to the app.

Downloading the Sampler Application

You can download the NEF Sampler Application file from http://www.netspective.com/corp/downloads/frameworks/samples

Setting up the Sampler Application

Copy the downloaded nefs-sampler.war file to the webapps folder of your servlet container (application server) and run (or restart) the application server. This will create an Application Directory Structure containing the necessary NEF files and sub-folders, under the webapps folder of your application server.

Testing the Sampler Application in a Browser

Use a web browser to access the root of the Sampler Application using the URL of the form http://host:port/nefs-sampler. If everything worked as it should, you will see the Sampler Application Welcome Page.

NEFS Sampler Objectives

As the name suggests, the purpose of NEFS Sampler Application is to give you an idea of how easy it is to build J2EE web applications using the powerful building blocks provided by our Java Frameworks. The NEFS Sampler uses an interactive mode thus making it easy to understand and use the samples. It includes various examples of creating forms and input fields, performing a variety of different data validations and executing forms to provide end-user functionality.

Although you start with simple NEFS usage examples, as you learn more about Sparx and Axiom you will see that flexibility and extensibility are also a part of their attributes.

Viewing the XDM Code

The eXtensible Markup Language (XML) plays an important role in NEF's ease of use, extensibility, and code generation. NEF declarations are performed using XML -- all dialogs, fields, validation rules, some conditional processing, all SQL statements, dynamic queries, configuration files, database schemas, and many other resources are stored in XML files that are re-usable across applications.

XDM is an acronym for "XML Data Model" and is designed to help Java programmers construct and configure Java objects using XML files without worrying about parsing and error checking. The APP_ROOT/WEB-INF/sparx/project.xml file uses XDM to declare all project components.

In the Sampler app if you see the XML icon along with a View Page XDM Code link, at the bottom of the page, you can view the Netspective Xml Data Model (XDM) source code for various objects on the page. This helps you view the XML code and see it working on the same page.

The XML icon also appears under various panels (like forms/dialogs) to see their code as well.

Clicking on the View Page XDM Code link to see the XML code (as shown below):

  1. The link to hide the currently visible XDM code. Clicking on this link hides the currently visible XDM code.

  2. Location of the currently open XDM code in the application's project file (WEB-INF/sparx/project.xml). Clicking on this link takes you to the Project | Project Files section of the Sampler app's Console, with Sampler app project file being displayed in browse mode.

  3. Java class file being instantiated for this page. Clicking on this link takes you to the Project | Project Files section of the Sampler app's Console, with the selected java file (AppPage.java in this case) being displayed in browse mode.

  4. XDM code (from the Sampler app project file) corresponding to the currently opened page.

Viewing Project Folder and Files

At the end of the Sampler App Home page, there is a link for browing through all the source directories and files of the Sampler App.

When you click on the browse link, it takes you to the Project | Project Files section of Sampler app Console, displaying all the source folders and files for the Sampler app.

Sparx Navigation Tree Overview

The NEFS presentation layer tags are broken up into several groups: navigation, forms/fields, on-screen validation, and conditional processing. Almost all of the presentation layer tags are managed by Sparx.

Introduction to Navigation Declaration Tags

The navigation tags comprise primarily the navigation-tree, page, and body tags. These are very high-level tags that provide a great deal of functionality without requiring any HTML or JSP. However, if you need to customize the behavior you have full access to the APIs through both inheritance and delegation. You focus on the hierarchy, specify the structure and rules and NEF will do the rest. The Sparx navigation system fully implements MVC (model-view-controller) design pattern.

Example 1. Navigation Tags in the Presentation Layer

<project xmlns:xdm="http://www.netspective.org/Framework/Commons/XMLDataModel">
...

<navigation-tree name="app" default="yes"> 1

    <page name="home" default="yes" caption="Hello" heading="Hello World!"> 2
        <body> 3
            <![CDATA[
            This is the 'Hello World' app. Click <a href="next-steps">here</a> 
            to see what's next.
            ]]>
        </body>
    </page>

    <page name="next-steps" caption="Next Steps" heading="What's next?">
        <body source="next-steps.ftl"/> 4
    </page>

    <page name="some-stuff" caption="Panels instead of Body">
        <panels> 5
             <panel type="command" 
                   command="query,org.get-sponsor-info-by-id,-,-,-,detail-compressed"/>
             <panel type="command" 
                   command="query,org.get-org-addresses-by-id,-,-,-,report-compressed"/>
        </panels>
    </page>

    <page name="sampler" caption="Sampler" 
                         redirect="vs-expr:${netspective-url:sampler}"/> 6
    <page name="sampler" caption="Sampler" include="/some/file.jsp"/> 7
    <page name="sampler" caption="Sampler" forward="/some/file.jsp"/> 8

    <page name="add" caption="Add Book" command="dialog,schema.db.Book_Info,add"/> 9
    <page name="edit" caption="Edit Book" command="dialog,schema.db.Book_Info,edit"
          require-request-param="id" retain-params="id">
        <missing-params-body> 10
         Please choose a book to edit from the &lt;a href='home'&gt; books list&lt;/a&gt;.
        </missing-params-body>
    </page>
</navigation-tree>
1

The navigation-tree tag starts out the definition of a tree. You may declare as many navigation trees as your application needs. Consider different trees for different users (based on personalization) or a different tree for each access-control role (for security) or any other criteria required by your application. Each tree has a name and may be marked with default=yes if it is to be the default tree. Which tree is actually used by the application may be specfied as a servlet parameter or chosen dynamically at runtime based on some processing rules.

2

Each navigation-tree tag one or more page tags that define what pages should be visible to the user. Each page tag supports common things like the page's name (unique identifier), a caption (what might show up in a tab or menu), a heading, and title.

3

Each page tag may have an optional body tag with contents directly specified as XML content. You can use the CDATA XML element to escape HTML tags. The content of the body tag is treated as a FreeMarker template by default.

4

The page tag's body tag may instead specify a source attribute that indicates the given file is a a FreeMarker template relative to the APP_ROOT directory. Other template engines like JSP are also supported.

5

The page tag's body tag may be replaced with the panels tag to have automatic layouts of mutliple panels.

6

The page tag may specify a redirect attribute to automatically redirect to another page whenever it is chosen.

7

The page tag may specify an include attribute to simply insert the contents of another web resource directly into the body.

8

The page tag may specify a forward attribute to forward the request to another web resource (this is the same as Servlet forwarding not HTTP forwarding).

9

The page tag may specify a command attribute to use the Command pattern and delegate the body to a com.netspective.commons.command.Command interface. These are very high-level commands like interacting with a dialog and displaying the results of a query that can be defined elsewhere and called on different pages.

10

The page tag may specify required request parameters and optionally produce automatic error messages when they are not provided.

[Note]Note

Almost all page tag attributes support Value Sources for their values so the values may be static or dynamic. This allows, for example the captions, headings, and all user-visible values to be properly placed in property files or other external resources and mapped in a language-specific manner for internationlization purposes. The important thing to understand is that even though the declarations are in a static XML file, the values of the descriptors are capable of being dynamic.

[Note]Note

Please see the NEF User's Manual for instructions on how to use the Console to review tag documentation and use the Tags Tree to get further details on the navigation-tree and page tags.

NEFS Sampler Main Components

The NEFS Sampler groups the samples into following logical sections:

  • Home

  • Forms Input

  • Forms Execution

  • Access Control

  • Play

  • Sitemap

  • Console

  • Sample Apps Home

Home

This is the Welcome page for the Sampler. It outlines the objectives of the Sampler and also contains a list of links pointing to the logical sections of the Sampler. You may access the Sampler sections by these links or the tabs provided the top of the page.

Forms Input

This module contains samples that demonstrate how forms and input fields are created in Sparx. There are many examples that show how quick and easy it is to set up forms to accept input values and automatically validate them.

The examples contained in this section are further divided into sub-categories. The Forms Input page contains a list of links to its children pages containing the categorized example pages. Links to these children pages are also provided through a submenu bar under the Forms Input tab.

Text

The Framework provides different styles of displaying text input fields. One is a simple one line text input field while another is a multi-line text input field.

The Line-based text input examples are included under Line-oriented submenu.

Figure 1. Sample Page for Line-oriented Text Fields

Sample Page for Line-oriented Text Fields

The sample text fields on this page show the usage of static text fields, input text fields (text boxes), email fields and masked fields for password entry. You can also see how to associate hints with a particular text input field. The example also implements field validation. Click on the OK button to see how field validation messages are displayed.

Figure 2. Field Validation Messages

Field Validation Messages

At times you need multi-line fields (e.g. text area) for your text input. The Block-oriented submenu contains examples highlighting the block based text input.

Figure 3. Sample Page for Block-oriented Text Fields

Sample Page for Block-oriented Text Fields

This page shows the usage of memo and template fields using custom CSS and HTML. The sample page also incorporates error messages using message boxes (as shown in the above image).

Numbers

This page demonstrates the usage of various types of numeric fields that are available: float, integer, currency, phone, and zip code. Each type have their own validation rules and formatting patterns.

Figure 4. Sample Page for Numeric Fields

Sample Page for Numeric Fields

Boolean

This page demonstrates usage of boolean fields which are fields that can only have a value that is either true or false. There are several display styles available for boolean fields: radio, check-alone, popup, and combo.

Figure 5. Sample Page for Boolean Fields

Sample Page for Boolean Fields

Selection

This page demonstrates how to create and use fields that allow selection of values. There are several styles available: list, multidual, multilist, combo, radio, and multicheck. You can also see the implementation for popup based select field.

Figure 6. Sample Page for Select Fields

Sample Page for Select Fields

Conditional Select

This page demonstrates how to create and use fields that allow selection of values and auto submit forms that will do other data population from the server side (for conditional values).

Figure 7. Sample Page for Conditional Select Fields

Sample Page for Conditional Select Fields

Grids

This page demonstrates how to create and use grid and composite fields. A composite field can be described as a logical field that contains several children fields. Usually, a grid field will have multiple composite fields which act as rows.

Figure 8. Sample Page for Grid and CompositeFields

Sample Page for Grid and CompositeFields

Conditionals

This page demonstrates how flags and values can be applied to a dialog field based on conditionals defined for that field. Conditional fields are fields whose state depends upon the state of other entities (in this case, other fields called partner fields).

Figure 9. Sample Page for Conditional Fields

Sample Page for Conditional Fields

Popups

This page demonstrates how to create and use popup fields. Sparx provides a feature to display a popup dialog box when a popup icon is clicked and values from a selection in the popup can be returned to the main window. Popup fields are visually identifiable by their special magnifying glass icon beside them.

Figure 10. Sample Page for Popup Fields

Sample Page for Popup Fields

Date/Time

This page demonstrates how to create and use date/time fields. There are several versions of date/time fields that are available: time, date, date and time, and duration.

Figure 11. Sample Page for Date/TimeFields

Sample Page for Date/TimeFields

Advanced

This page and its children pages are for demonstrating more advanced usage of the built-in features of the dialog fields.

Client-side Script

This page demonstrates how to "plug" custom javascript calls to the client-side events (e.g. click, value-changed, lose-focus, key-press, is-valid) of the dialog fields.

Figure 12. Sample Page for Custom Javascript

Sample Page for Custom Javascript
Perspectives

Generally dialogs are used for different data processing actions: entering new data, editing existing data, and deleting existing data. The Framework considers these separate data processing actions as perspectives of the dialog. Thus, there are several different perspectives to which a dialog can be set to: add, edit, delete, print, and confirm. This page demonstrates the usage of data perspectives for filling dialog fields.

Figure 13. Sample Page for Perspectives

Sample Page for Perspectives
Hidden Fields

This page demonstrates different usages of hidden fields in a dialog. Hidden fields are useful for keeping track of information that you don't want the user to see.

Figure 14. Sample Page for Hidden Fields

Sample Page for Hidden Fields

Click the OK button. The dialog context is displayed in debug mode (as shown below). You may check the values of the hidden fields and other dialog fields from there.

Figure 15. Dialog Context Debug Information

Dialog Context Debug Information
Command Fields

This page demonstrates the usage of a List command to populate a dialog field. Only certain commands can be used for dialog fields. Commands execute arbitrary tasks defined either by you or the framework. They are used to encapsulate common logic and reuse that logic across pages and dialogs (forms). For information on Commands in general, please consult the User Manual.

Figure 16. Sample Page for List Command

Sample Page for List Command

Forms Execution

This module contains samples that demonstrate how forms are executed in Sparx. While the Forms Input module described how to create forms and fields, this module deals with how to perform actions based on already validated input. Numerous examples delve into how to perform custom validation and execute dialog handlers based on existing Sparx functionality or creating your own through inheritance and delegation.

The examples contained in this section are further divided into sub-categories. The Forms Execution page contains a list of links to its children pages containing the categorized example pages. Links to these children pages are also provided through a submenu bar under the Forms Execution tab.

Director

This page demonstrates the usage of a Dialog Director which controls destinations after successful form submission and the display of the dialog buttons.

Figure 17. Sample Page for Director

Sample Page for Director

Select the value from the Next Action select box and click the OK button to see the execution of next action for this dialog.

The XML Code that configures the Dialog Director is given below:

Example 2. XML for Using the Dialog Director

<project>
...
 <dialog type="exec-sample" name="director-next-action" 
         redirect-after-execute="yes"> 1
  <frame heading="Test Dialog Director's Next Action"/>
   <field type="html">
    <body>
      <![CDATA[
        <div class="textbox">
         Every dialog is associated with a <i>Director</i> which controls the 
         actions available inside<br>
         the form (such as the <i>Submit</i> and <i>Cancel</i> buttons) and the 
         destination page to<br>
         redirect to after the execution of the dialog. Visually the <i>Director</i> 
         can be configured<br>
         to display multiple destinations to allow users to select the destination 
         as shown in<br>
         this dialog.
        </div>
        <hr/>
      ]]>
    </body>
   </field>
   <field type="text" name="text_field" caption="Text Field (formOrRequestAttr)"
        default="request:value"/>
   <director> 2
     <next-actions caption="Next Action\:" 
                   choices="text-list:Netspective=http\://www.netspective.com;
                                      Google=http\://www.google.com"
                   display-single-action="yes"/> 3
   </director>
</dialog>
...
</project>
1

The dialog tag defines a dialog using exec-sample template as the dialog-type.

2

The director tag is used to define the director to be associated with this dialog.

3

Configuring the director to display multiple destinations.

Templates

This page demonstrates the ability to execute templates or display JSP output after successful submission of a dialog. Usually executing a template means displaying the output from a template processing engine.

Body in XML

This page contains an example of a dialog which will execute a template body defined in the dialog's XML declaration and display the output. The XML template is used to display the Welcome message to user.

Figure 18. Sample Page for Templates using Body in XML

Sample Page for Templates using Body in XML

The XML Code for using the FreeMarker™ template (embedded within project.xml) is given below:

Example 3. XML Code for Using Template (embedded in project.xml)

<project>
...
 <dialog type="exec-sample" name="body-xml"> 1
    <frame heading="Hello World Form"/>
    <field type="text" name="first_name" caption="First Name" required="yes"/>
    <field type="text" name="last_name" caption="Last Name" required="yes"/>

    <on-execute handler="template"> 2
        <![CDATA[
        Welcome to NEFS, ${vc.fieldStates.getState("first_name").value.textValue} 3
        ${vc.fieldStates.getState("last_name").value.textValue}.
        <p>Form1 demonstrated how you can take two
        pieces of data and execute an arbritrary 
        <a href="http://www.freemarker.org">FreeMarker</a> template embedded in 
        the project.xml file.
        ]]>
    </on-execute>
 </dialog>
</project>
1

Declaring a dialog using "exec-sample" template as the dialog type.

2

The handler attribute of on-execute tag specifies the "template" handler for this dialog. Sparx provides various handlers for the dialogs (forms): include, mail, command, panels and style-sheet.

3

Retrieving the value of dialog (form) fields, from their value contexts.

[Note]Note

In the above example, the template is embedded within project.xml

Body in File

This page contains an example of a dialog which will execute a template body defined in a seperate file and display the output.

Figure 19. Sample Page for Templates using Body in a Separate File

Sample Page for Templates using Body in a Separate File

This example shows a Welcome message, obtained from a separate file, to the user. It also explains the loop attribute of dialog tag. To return to the dialog, you will need to click on the Return to dialog link provided on the page (as shown below):

Figure 20. Returning to the Dialog

Returning to the Dialog

The XML Code for using the FreeMarker™ template (available in a separate file) is given below:

Example 4. XML Code for Using Template (in a separate file)

<project>
...
 <dialog type="exec-sample" name="body-file" loop="no"> 1
    <frame heading="Hello World Form"/>
    <field type="text" name="full_name" caption="Full Name" required="yes"/>
    <field type="date" name="birth_date" caption="Birth Date" required="yes" 
                       popup-calendar="yes"/> 

    <on-execute handler="template">
        <source>form/exec/template-body-file.ftl</source> 2
    </on-execute>
 </dialog>
...
</project>
1

The loop attribute of dialog tag is used to specify not to show the dialog after the dialog executes.

2

Source tag is used to specify the template source file to be used (template-body-file.ftl in this case)

Body in JSP

This page contains an example of a dialog which will display an output from a JSP upon execution.

Figure 21. Sample Page for Templates using Body in a JSP File

Sample Page for Templates using Body in a JSP File

This example shows a Welcome message, obtained from a JSP file, to the user. It also explains the loop attribute of dialog tag. To return to the dialog, you will need to click on the Return to dialog link provided on the page (as shown below):

Figure 22. Returning to the Dialog

Returning to the Dialog

The XML Code for using the jsp file is given below:

Example 5. XML Code for Using a JSP File

<project>
...
 <dialog type="exec-sample" name="inc-jsp" loop="no">
    <frame heading="Hello World Form"/>
    <field type="text" name="full_name" caption="Full Name" required="yes"/>
    <field type="date" name="birth_date" caption="Birth Date" required="yes" 
           popup-calendar="yes"/>

    <on-execute handler="include"> 1
        <path>/jsp/template-inc-test.jsp</path> 2
    </on-execute>
 </dialog>
...
</project>
1

The handler attribute of on-execute tag specifies the "include" handler for this dialog.

2

Path tag is used to specify the JSP file to be used (template-inc-test.jsp in this case)

Handlers

This page demonstrates the usage of various handlers for the execution of a dialog. These handlers are processed once the internal validation of the dialog is complete and the dialog is ready to be be executed. Handlers are special built-in actions defined for convenience and reusability: url, mail, command, panels, and style-sheet. For defining more complex actions and logic for execution, please take a look at the inheritence or delegation examples.

Include URL

This page contains an example of a dialog which has a handler that will display HTML from an external page.

Figure 23. Sample Page for HTML Include of an External Page

Sample Page for HTML Include of an External Page

Enter a URL and click the OK button. The contents of the target page, pointed to by this supplied URL, is displayed (as shown below):

Figure 24. Contents of the External Page

Contents of the External Page

The XML Code for this example is given below:

Example 6. XML Code for Including an External Page

<project>
...
 <dialog type="exec-sample" name="inc-html" loop="prepend" 
                            allow-multiple-executes="yes">
    <loop-separator>&lt;hr size=1&gt;&lt;p&gt;</loop-separator> 1
    <frame heading="Get contents of URL"/>
    <field type="text" name="url" caption="URL" size="60" required="yes" 
           default="http\://www.yahoo.com">
     <hint>
       Please provide a complete URL such as http\://www.google.com.&lt;br&gt;
       This form will read the contents of the URL and show it below.
     </hint>
    </field>

    <on-execute handler="include"> 2
        <url>dialog-field:url</url> 3
    </on-execute>
 </dialog>
...
</project>
1

The loop-separator tag specifies a horizontal row to be displayed between the dialog and the external page content.

2

The handler attribute of on-execute tag specifies the "include" handler for this dialog.

3

The URL tag is used to specify the URL of the external page. The dialog-field static value specifies that the URL is obtained from the dialog field named URL

Send Mail

This page contains an example of a dialog which has a handler that will send an email upon execution of the dialog.

Figure 25. Sample Page for Send Mail

Sample Page for Send Mail

Enter the values for the mail dialog fields and click the OK button. A success message is displayed, along with the body of the email, if the mail is sent to the specified recipient. In case of an error, an appropriate error message is displayed.

Figure 26. Mail Send - Success Message

Mail Send - Success Message

The XML Code for this example is given below:

Example 7. XML Code for Using the Mail Handler

<project>
...
 <dialog type="exec-sample" name="send-mail" loop="append" 
                                             allow-multiple-executes="yes">
    <frame heading="Send Mail Handler Example"/>
    <field type="text" name="host" caption="Host" required="yes" 
                                   default="mail.netspective.com"/>
    <field type="text" name="from" caption="From" required="yes" 
                                   default="dummy@mail.com"/>
    <field type="text" name="to" caption="To" required="yes"/>
    <field type="text" name="subject" caption="Subject" required="yes"/>
    <field type="memo" name="body" caption="Body"/>

    <on-execute handler="mail"> 1
        <host>dialog-field:host</host> 2
        <from>dialog-field:from</from>
        <to>dialog-field:to</to>
        <subject>dialog-field:subject</subject>
        <body>You entered this e-mail body: 
                 ${vc.fieldStates.getState("body").value.textValue}</body> 3
        <success-message> 4
            <![CDATA[
            Thank you for sending e-mail to <code><b>
                ${vc.fieldStates.getState("to").value.textValue}</b></code>.
            ]]>
        </success-message>
        <failure-message> 5
            <![CDATA[
            Unable to send e-mail to <code><b>
                ${vc.fieldStates.getState("to").value.textValue}</b></code>.<p>
            Exception:<br>
            <pre>${exception}</pre> 6
            ]]>
        </failure-message>
    </on-execute>
 </dialog>
...
</project>
1

The handler attribute of on-execute tag specifies the "mail" handler for this dialog.

2

The host tag is used to specify the address for the mailing host. The dialog-field static value specifies that the mailing Host address is obtained from the dialog field named host.

3

Displays the email's body text.

4

The success-message tag specifies the message to be displayed when the email is successfully sent to the supplied recipient.

5

The failure-message tag specifies the message to be displayed when the email is not sent to the supplied recipient due to some error.

6

Displays the details of exception, in the error message.

Exec Command

This page contains an example of a dialog which has a handler that will process a command upon execution of the dialog. Enter the command and click the OK button to see the command execution result.

Figure 27. Execute Command

Execute Command

The XML Code for this example is given below:

Example 8. XML Code for Using the Command Handler

<project>
...
<dialog type="exec-sample" name="exec-cmd" allow-multiple-executes="yes">
    <frame heading="Command Handler Example"/>
    <field type="text" name="command" caption="Command" required="yes" size="60"/>

    <on-execute handler="command" command-expr="dialog-field:command"/> 1
</dialog>
...
</project>
1

The handler attribute of on-execute tag specifies the "command" handler for this dialog. The command-expr field specifies the dialog field named command as the source for the command expression.

Exec Panels

This page contains an example of a dialog which has a handler that will display panels upon execution of the dialog. The panels can contain HTML from various entities such as JSPs or URLs.

Figure 28. Sample Page for Execution of Panels

Sample Page for Execution of Panels

Provide a local source for HTML (/jsp/panel-inc-test.jsp in the above example) for Include Local field and a URL (http://www.yahoo/com in this case) as the value for Command 2 field. Click the OK button. The HTML contents from the JSP and the yahoo web site are displayed in two different panels (as shown below):

Figure 29. HTML Loaded in Two Panels

HTML Loaded in Two Panels

The XML Code for this example is given below:

Example 9. XML Code for Using the Panels Handler

<project>
...
 <dialog type="exec-sample" name="exec-panels" allow-multiple-executes="yes">
    <frame heading="Panels Handler Example"/>
    <field type="text" name="local-include" caption="Include local" 
           required="yes" size="60" default="/jsp/panel-inc-test.jsp"/>
    <field type="text" name="remote-include" caption="Command 2" 
           required="yes" size="60" default="http\://www.yahoo.com"/>

    <on-execute handler="panels" style="two-columns"> 1
        <panel type="include" path="dialog-field:local-include"> 2
            <frame heading="dialog-field:local-include"/> 3
        </panel>
        <panel type="include" URL="dialog-field:remote-include"> 4
            <frame heading="dialog-field:remote-include"/>
        </panel>
    </on-execute>
 </dialog>
...
</project>
1

The handler attribute of on-execute tag specifies the "panels" handler for this dialog. The style field specifies how the panels will be arranged in the output HTML. In this example, the panels will be arranged in two columns (one panel per column).

2

Declaring the panel. The type attribute specifies the use of "include" template as the panel type. The path attribute uses a value-source to get the path from where the include file will be obtained. In the above example, this path value is obtained from the dialog field named local-include.

3

The heading attribute of this frame specifies the value of the dialog-field named local-include as the heading for the frame.

4

The URL attribute of this panel tag specifies the URL for the external page. In the above example, the value for the external page's URL is obtained from the dialog-field named remote-include.

Transform Bean

This page contains an example of a dialog which has a handler that will display output from a XSL style sheet transformation upon execution of the dialog.

Figure 30. Sample Page for XSL Transformation

Sample Page for XSL Transformation

The XSL style sheet is provided in the dialog. Click on the OK button to see the transformed XML describing the dialog's Context Bean (as shown below):

Figure 31. Transformed XML Describing the Dialog's Context Bean

Transformed XML Describing the Dialog's Context Bean

The XML Code for this example is given below:

Example 10. XML Code for Using the Style-Sheet Handler (Transform Bean)

<project>
...
 <dialog type="exec-sample" name="transform-xslt-dc" loop="prepend" 
                                                     allow-multiple-executes="yes">
  <frame heading="XSLT Handler Example"/>    
   <field type="select" name="style-sheet-file" caption="Style sheet File" 
          required="yes" 
          choices="filesystem-entries:servlet-context-path:/form/exec,\.xsl$,yes"/> 1

  <on-execute handler="style-sheet"> 2
      <style-sheet-file>dialog-field:style-sheet-file</style-sheet-file> 3
  </on-execute>
 </dialog>
...
</project>
1

The choices attribute declares the list of XSL files from which the user can select. The filesystem-entries value-source specifies the list of all XSL files, available from the path specified by servlet context path, to be used as the entries for the select field.

2

The handler attribute of on-execute tag specifies the "style-sheet" handler for this dialog.

3

The style-sheet-file tag specifies the XSL file to be used for transformation. In the above example, this value is obtained from the style-sheet-file field of the dialog.

Transform File

This page contains an example of a dialog which has a handler that will display output from a XSL style sheet transformation upon execution of the dialog.

Figure 32. Sample Page for XSL Transformation

Sample Page for XSL Transformation

This dialog asks for a source XML or XSL file to be converted. The XSL to be applied can also be selected using the Stylesheet File select field in the dialog. Select the XML test-transform.xml file as the Source File and click the OK button. The transformed XML is displayed (as shown below):

Figure 33. Transformed XML File

Transformed XML File

You may also test the transformation of the XSL source file itself by selecting it as the source file. The transformed XSL file is displayed (as shown below):

Figure 34. Transformed XSL File

Transformed XSL File

The XML Code for this example is given below:

Example 11. XML Code for Using the Style-Sheet Handler (Transform File)

<project>
...
 <dialog type="exec-sample" name="transform-xslt-file" loop="prepend" 
                                                       allow-multiple-executes="yes">
    <frame heading="XSLT Handler Example"/>
    <field type="select" name="source-file" caption="Source File" required="yes" 
           choices="filesystem-entries:servlet-context-path:/form/exec,\.x[sm]l$,yes"/>
    <field type="select" name="style-sheet-file" caption="Stylesheet File" 
           required="yes" 
           choices="filesystem-entries:servlet-context-path:/form/exec,\.xsl$,yes"/>

    <on-execute handler="style-sheet">
        <source-file>dialog-field:source-file</source-file> 1
        <style-sheet-file>dialog-field:style-sheet-file</style-sheet-file>
    </on-execute>
 </dialog>
...
</project>
1

The source-file tag specifies the file on which XSL transformation is applied.

Inheritance

This page demonstrates the inheritance model for defining custom logic or action for different stages of a dialog. This model should only be used for the most complex cases where you need to override the default behavior of the dialog. By extending the default dialog class, com.netspective.sparx.form.Dialog, you have full control over the dialog and its behavior.

Exec 1 A

This page contains a dialog which has a custom dialog class that overrides only the default execution behavior of the dialog.

Figure 35. Sample Page for Handling Dialog 1A (through Inheritance)

Sample Page for Handling Dialog 1A (through Inheritance)

Enter a value for Full Name field and click the OK button. The custom Java class (SampleExecuteDialog in this case) displays a Welcome message along with the supplied name (as shown below):

Figure 36. Welcome Message Generated by the Custom Class

Welcome Message Generated by the Custom Class

The welcome message also displays the link to the custom class being used as the dialog handler.

The XML Code for this example is given below:

Example 12. XML Code for Using Custom Handler (Inheritance)

<project>
...
 <dialog type="exec-sample" name="exec1a" 
                            class="app.form.exec.inheritance.SampleExecuteDialog"> 1
    <frame heading="Inheritance Execute Sample 1a"/>
    <field type="text" name="full_name" caption="Full Name" required="yes"/>
 </dialog>
...
</project>
1

the class attribute of the dialog tag specifies the custom class (SamplerExecuteDialog in this case) to be used as the handler for this dialog

You may view the code for custom Java class using the link provided in the welcome message. This opens the Java source code in the Console (as shown below):

Figure 37. Source File for Custom Class (Inheritance)

Source File for Custom Class (Inheritance)

Example 13. Custom Dialog Handler Class (using Inheritance)

package app.form.exec.inheritance; 1

       2
import java.io.Writer;
import java.io.IOException;

import com.netspective.sparx.form.Dialog;
import com.netspective.sparx.form.DialogContext;
import com.netspective.sparx.form.DialogExecuteException;
import com.netspective.sparx.form.DialogsPackage;
import com.netspective.sparx.Project;
  
public class SampleExecuteDialog extends Dialog 3
{
    public SampleExecuteDialog(Project project)
    {
        super(project);
    }

    public SampleExecuteDialog(Project project, DialogsPackage pkg)
    {
        super(project, pkg);
    }

    public void execute(Writer writer, DialogContext dc) 
                      throws IOException, DialogExecuteException 4
    {
      writer.write("Welcome to NEFS <b>" + 
            dc.getFieldStates().getState("full_name").getValue().getTextValue() + 5
            "</b>. ");
      writer.write("You are running the dialog called <b>"+ dc.getDialog().getName() 
            +"</b> in package <b> "+
            dc.getDialog().getNameSpace().getNameSpaceId() +"</b>.");

      if(dc.getDialog().getQualifiedName().equals("form.exec.inheritance.exec1b")) 6
          writer.write("<p>You are <b>"+ 
                        dc.getFieldStates().getState("age").getValue().getIntValue() 
                        + "</b> years old."); 

      writer.write("<p>");
      writer.write("This code demonstrated how you can take two pieces of data and " +
                   "execute an arbritrary class by setting the 'class' attribute of "+ 
                   "the dialog. ");
      writer.write("This method of execution is called <i>Dialog Inheritance</i>. ");

      String relativePath = 
             /WEB-INF/classes/app/form/exec/inheritance/SampleExecuteDialog.java"; 7
      String sourceFileLink = dc.getConsoleFileBrowserLinkShowAlt(dc.getServlet().getServletConfig().getServletContext().getRealPath(relativePath),
                  relativePath); 8
      writer.write("You may review the code at " + sourceFileLink + ".");
      writer.write("<p>");
      writer.write("<a href=\""+ dc.getNavigationContext().getActivePage().getName() +
                   "\">Clear the dialog</a>"); 9
    }
}
1

Declaring the package for this class.

2

Importing other required classes.

3

Extending the Dialog class to provide custom implementation.

4

Declaring the dialog execute method which is called as soon as all dialog data is entered and validated.

5

Retrieving the value of the dialog field named full_name from the dialog context and sending it to the writer.

6

Checking the dialog name after retrieving it from the dialog context. If the dialog name is exec1b, the Age related message is also displayed in the output HTLML.

7

Declaring a variable containing the relative path of this Java file.

8

Getting the link to the source file of custom dialog handler class (SampleExecuteDialog.java in this case). The getConsoleFileBrowserLinkShowAlt method shows the name of the file that is passed into the first parameter. If the second parameter is also passed, the URL (anchor) reference shows an alternate text within the anchor.

8

Retrieving the current page's name from the Navigation Context.

[Note]Note

This custom dialog handler class takes care of exec1A and exec2a both, in case of Sampler App.

Exec 1 B

This page contains a dialog which has a custom dialog class that overrides only the default execution behavior of the dialog.

Figure 38. Sample Page for Handling Dialog 1B (through Inheritance)

Sample Page for Handling Dialog 1B (through Inheritance)

Enter a value for Full Name and Age fields and click the OK button. In the Sampler App, the custom Java class SampleExecuteDialog handles this dialog as well. Note the message about the supplied age (as shown below):

Figure 39. Welcome Message Generated by the Custom Class

Welcome Message Generated by the Custom Class
Validation

This page contains a dialog which has a custom dialog class that overrides the default population, validation, and execution behaviors of the dialog.

Figure 40. Sample Page for Validation using Custom Class (through Inheritance)

Sample Page for Validation using Custom Class (through Inheritance)

Enter the values for the dialog fields and click the OK button (as shown in the image above). The custom validation class (SampleValidateDialog in this case) checks the entered values and displays the validation messages, if any (as shown below):

Figure 41. Validation Messages Generated by Custom Class

Validation Messages Generated by Custom Class

The XML Code for this example is given below:

Example 14. XML Code for Validation Custom Class (Inheritance)

<project>
...
 <dialog type="exec-sample" name="validate" 
         class="app.form.exec.inheritance.SampleValidateDialog" 
         generate-dcb="yes"> 1
    <frame heading="Inheritance Validate Sample"/>
    <field type="text" name="full_name" caption="Full Name" required="yes"/>
    <field type="date" name="birth_date" caption="Birth Date" required="yes" 
                                                              max="today"/>
    <field type="integer" name="age" caption="Age" required="yes" min="1" max="150"/>
 </dialog>
...
</project>
1

Declaring the custom class handling the dialog (form) validation. The generate-dcb attribute specifies the generation of auto-generated Dialog Context Bean (DCB).

The code for custom validation class is given below. Note that this class extends the Dialog class to provide custom implementation.

Example 15. Custom Dialog Validation Handler Class (using Inheritance)

package app.form.exec.inheritance; 

import java.io.Writer;
import java.io.IOException;
import java.util.Date;
import java.util.Calendar;
import auto.dcb.form.exec.inheritance.ValidateContext;

import com.netspective.sparx.form.Dialog;
import com.netspective.sparx.form.DialogContext;
import com.netspective.sparx.form.DialogExecuteException;
import com.netspective.sparx.form.DialogsPackage;
import com.netspective.sparx.form.field.DialogField;
import com.netspective.sparx.Project;

public class SampleValidateDialog extends Dialog 
{
  public SampleValidateDialog(Project project)
 {
     super(project);
 }

 public SampleValidateDialog(Project project, DialogsPackage pkg)
 {
     super(project, pkg);
 }

 public void populateValues(DialogContext dc, int formatType) 1
 {
     super.populateValues(dc, formatType);

     if(dc.getDialogState().isInitialEntry() && 
        formatType == DialogField.DISPLAY_FORMAT) 2
     {
         ValidateContext validateContext = new ValidateContext(dc); 3
         Date birthDate = validateContext.getBirthDate().getDateValue();
         if(birthDate == null) 
         {
             Calendar cal = Calendar.getInstance();
             // assume we're 25 years old  
             cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - 25); 

             validateContext.getBirthDate().setValue(cal.getTime());
         }
     }
 }

 public boolean isValid(DialogContext dc) 4
 {
     if(! super.isValid(dc)) 5
         return false;
      ValidateContext validateContext = new ValidateContext(dc);
      Date birthDate = validateContext.getBirthDate().getDateValue();
      int age = validateContext.getAge().getIntValue();
                    
                    6
      Calendar cal = Calendar.getInstance();
      int currentYear = cal.get(Calendar.YEAR);
      cal.setTime(birthDate);
      int yearOfBirth = cal.get(Calendar.YEAR);

      if(currentYear - yearOfBirth != age) 
      {
       dc.getValidationContext().addError("The Age and Birth Date fields "+
                                              "do not match."); 7

                                 8
       validateContext.getBirthDateField().invalidate(dc, "If you want the age to be "+ 
                age + " then birth date should be in year " + (currentYear - age));
       validateContext.getAgeField().invalidate(dc, "If you want the birth year to be "+ 
                yearOfBirth +" then age should be " + (currentYear - yearOfBirth));

       return false; 9
      }

      return true;
 }

 public void execute(Writer writer, DialogContext dc) 
                                        throws IOException, DialogExecuteException 10
 {
  writer.write("Congratulations <b>" 
                + dc.getFieldStates().getState("full_name").getValue().getTextValue() + 
                "</b>! ");
  writer.write("It seems that your birthdate and ages match correctly.");
  writer.write("<p>");
  writer.write("This code demonstrated how you can take two three pieces of data, "+
              "have Sparx individually validate the general fields such as text, "+
              "date, and integer but add your own custom validator some other logic"+
              " by overriding the isValid() method of the "+
              "com.netspective.sparx.form.Dialog class.<p>");

  String relativePath = "/WEB-INF/classes/app/inheritance/SampleValidateDialog.java";
  writer.write("You may review the code at " + dc.getConsoleFileBrowserLinkShowAlt(dc.getServlet().getServletConfig().getServletContext().getRealPath(relativePath), relativePath));
  writer.write("<p>");
  writer.write("<a href=\""+ 
  dc.getNavigationContext().getActivePage().getName() +"\">Clear the dialog</a>");
 }
}
1

This method is called each time the dialog is displayed to the user and fields need their values populated. By default, Sparx handles populates almost all the value population. But, sometimes, you may want to populate something programmatically.

2

Only put data into the fields if we're displaying the data for the first time. If it's not the initial entry, it means that there's an error on the screen and the fields need to be populated with the data entered by the user.

3

Using the auto-generated dialog context bean (DCB) for user data retrieval. DCB is a type-safe wrapper around the general-purpose DialogContext. Declaring a validation context for current user's dialog.

4

The isValid method is called right before execute to validate the dialog. If you need to perform any validation that the fields can't perform on their own (such as cross-field validation), you should perform it here. The dc parameter contains reference to the DialogContext containing the field values and states.

5

Check if any of the default validation failed. If yes, leave this method.

6

Find out the current year and the year of birth entered by the user.

7

Add an error message, at the dialog level, if the custom validation condition fails. The error message is added to the validation context of the dialog context.

8

In case of failure, add error messages to each field as well.

9

Return "false" so the dialog does not go into execute mode until you have valid data.

10

The dialog execute method is called as soon as all data is entered and validated. This method is guaranteed to be called only when all fields' data is valid.

[Note]Note

This custom dialog validation handler class (using inheritance) takes care of exec1A and exec2a both, in case of Sampler App.

Delegation

This page demonstrates the delegation model for defining custom logic or action for different stages of a dialog. The Framework allows definition of various listeners for different stages of a dialog. By implementing the listener interfaces and then assigning the custom listeners to a dialog, these listeners will get executed.

[Note]Note

Inheritance is used for large-scale customizations and enhancing the framework itself while delegation is used to implement listeners and event processing customizations. Although both methods are supported, the delegation model is recommened to help ensure that changes in the NEF APIs do not affect your code.

Exec 1 A

This page demonstrates an execution listener for the delegation model. An execution listener implements the com.netspective.sparx.form.handler.DialogExecuteHandler interface.

Figure 42. Sample Page for Handling Dialog 1A (through Delegation)

Sample Page for Handling Dialog 1A (through Delegation)

Enter a value for Full Name field and click the OK button. The custom Java class (SampleExecuteHandler in this case) displays a Welcome message along with the supplied name (as shown below):

Figure 43. Welcome Message Generated by the Custom Class

Welcome Message Generated by the Custom Class

The XML Code for this example is given below:

Example 16. XML Code for Using Custom Handler (Delegation)

<project>
...
 <dialog type="exec-sample" name="exec1a">
    <frame heading="Delegation Execute Sample 1a"/>
    <field type="text" name="full_name" caption="Full Name" required="yes"/>

    <on-execute class="app.form.exec.delegation.SampleExecuteHandler"/> 1
 </dialog>
...
</project>
1

the class attribute of the on-execute tag specifies the custom class (SampleExecuteHandler in this case) to be used as the listener for this dialog.

You may view the code for custom Java class using the link provided in the welcome message. This opens the Java source code in the Console (as shown below):

Figure 44. Source File for Custom Class (Delegation)

Source File for Custom Class (Delegation)

Example 17. Custom Dialog Handler Class (using Delegation)

package app.form.exec.delegation; 1

    2
import java.io.Writer;
import java.io.IOException;

import com.netspective.sparx.form.handler.DialogExecuteHandler;
import com.netspective.sparx.form.DialogContext;
import com.netspective.sparx.form.DialogExecuteException;

public class SampleExecuteHandler implements DialogExecuteHandler 3
{
    public void executeDialog(Writer writer, DialogContext dc) 
                              throws IOException, DialogExecuteException 4
    {
      writer.write("Welcome to NEFS <b>" + 
       dc.getFieldStates().getState("full_name").getValue().getTextValue() + "</b>. ");5
                     
      writer.write("You are running the dialog called <b>"+ dc.getDialog().getName() +
        "</b> in package <b>"+ dc.getDialog().getNameSpace().getNameSpaceId() +
        "</b>.");

      if (dc.getDialog().getQualifiedName().equals("form.exec.delegation.exec1b")) 6
        writer.write("<p>You are <b>"+ 
                     dc.getFieldStates().getState("age").getValue().getIntValue() 
                     + "</b> " + "years old.");

        writer.write("<p>");
        writer.write("This code demonstrated how you can take two pieces of data and "+
                     "execute an arbritrary class by supplying an &lt;on-execute&gt; "+
                     "tag in the &lt;dialog&gt;. ");
        writer.write("This method of execution is called <i>Dialog Delegation</i> "+
                     "because a class separate from the Dialog class handles the "+
                     "execution.<p>");

        String relativePath = 
               "/WEB-INF/classes/app/form/exec/delegation/SampleExecuteHandler.java"; 7
        String sourceFileLink = dc.getConsoleFileBrowserLinkShowAlt(dc.getServlet().getServletConfig().getServletContext().getRealPath(relativePath),
                      relativePath); 8
        writer.write("You may review the code at " + sourceFileLink + ".");
        writer.write("<p>");
        writer.write("<a href=\""+ dc.getNavigationContext().getActivePage().getName() 
                       +"\">Clear the dialog</a>"); 9
    }
}

 
 
1

Declaring the package for this class.

2

Importing other required classes.

3

Implementing the DialogExecuteHandler interface.

4

Declaring the dialog executeDialog method which is called as soon as all dialog data is entered and validated.

5

Retrieving the value of the dialog field named full_name from the dialog context and sending it to the writer.

6

Checking the dialog name after retrieving it from the dialog context. If the dialog name is exec1b, the Age related message is also displayed in the output HTLML.

7

Declaring a variable containing the relative path of this Java file.

8

Getting the link to the source file of custom dialog handler class (SampleExecuteHandler.java in this case). The getConsoleFileBrowserLinkShowAlt method shows the name of the file that is passed into the first parameter. If the second parameter is also passed, the URL (anchor) reference shows an alternate text within the anchor.

9

Retrieving the current page's name from the Navigation Context.

[Note]Note

This custom class takes care of exec1A and exec2a both, in case of Sampler App.

Exec 1 B

This page demonstrates an execution listener for the delegation model. An execution listener implements the com.netspective.sparx.form.handler.DialogExecuteHandler interface.

Figure 45. Sample Page for Handling Dialog 1B (through Delegation)

Sample Page for Handling Dialog 1B (through Delegation)

Enter a value for Full Name and Age fields and click the OK button. In the Sampler App, the custom Java class SampleExecuteHandler handles this dialog as well. Note the message about the supplied age (as shown below):

Figure 46. Welcome Message Generated by the Custom Class

Welcome Message Generated by the Custom Class

You may view the code for custom Java class using the link provided in the message. This opens the Java source code in the Console.

Figure 47. Source File for Custom Class

Source File for Custom Class
Validation

This page contains a dialog that demonstrates validation, population, and execution listeners for the delegation model. A listener class can implement various listener interfaces to define custom business logic for various dialog stages.

Figure 48. Sample Page for Validation using Custom Class (through Delegation)

Sample Page for Validation using Custom Class (through Delegation)

Enter the values for the dialog fields and click the OK button (as shown in the image above). The custom validation class (SampleValidateDialog in this case) checks the entered values and displays the validation messages, if any (as shown below):

Figure 49. Validation Messages Generated by Custom Class

Validation Messages Generated by Custom Class

The XML Code for this example is given below:

Example 18. XML Code for Validation Custom Class (Delegation)

<project>
...
 <dialog type="exec-sample" name="validate" generate-dcb="yes"> 1
    <frame heading="Delegation Validate Sample"/>
    <field type="text" name="full_name" caption="Full Name" required="yes"/>
    <field type="date" name="birth_date" caption="Birth Date" required="yes" 
                                                              max="today"/>
    <field type="integer" name="age" caption="Age" required="yes" min="1" max="150"/>

    <listener class="app.form.exec.delegation.SampleValidateHandler"/> 2
 </dialog>

...
</project>
1

The generate-dcb attribute specifies the generation of auto-generated Dialog Context Bean (DCB).

2

The class attribute of the listener tag declares the dialog listener to be used for custom validation.

The code for custom validation class, using delegation, is given below. Note that this class implements the DialogValidateListener, DialogPopulateListener and DialogExecuteHandler interfaces to provide custom implementation.

Example 19. Custom Dialog Validation Handler Class (using Delegation)

package app.form.exec.delegation;

import java.io.Writer;
import java.io.IOException;
import java.util.Date;
import java.util.Calendar;

import auto.dcb.form.exec.delegation.ValidateContext;

import com.netspective.sparx.form.DialogContext;
import com.netspective.sparx.form.DialogExecuteException;
import com.netspective.sparx.form.DialogValidationContext;
import com.netspective.sparx.form.handler.DialogExecuteHandler;
import com.netspective.sparx.form.listener.DialogValidateListener;
import com.netspective.sparx.form.listener.DialogPopulateListener;
import com.netspective.sparx.form.field.DialogField;

public class SampleValidateHandler implements DialogValidateListener, 
                                              DialogPopulateListener, 
                                              DialogExecuteHandler 
{
 public void populateDialogValues(DialogContext dc, int formatType) 1
 {
  if(dc.getDialogState().isInitialEntry() && formatType==DialogField.DISPLAY_FORMAT) 2
  {
    ValidateContext validateContext = new ValidateContext(dc); 3
    Date birthDate = validateContext.getBirthDate().getDateValue();
    if(birthDate == null)
    {
     Calendar cal = Calendar.getInstance();
     // assume we're 25 years old
     cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) - 25); 
     validateContext.getBirthDate().setValue(cal.getTime());
    }
  }
 }

 public void validateDialog(DialogValidationContext dvc) 4
 {
   ValidateContext validateContext = new ValidateContext(dvc.getDialogContext());
   Date birthDate = validateContext.getBirthDate().getDateValue();
   int age = validateContext.getAge().getIntValue();
 
              5
   Calendar cal = Calendar.getInstance();   
   int currentYear = cal.get(Calendar.YEAR);
   cal.setTime(birthDate);
   int yearOfBirth = cal.get(Calendar.YEAR);

   if(currentYear - yearOfBirth != age)
   {
    dvc.addError("The Age and Birth Date fields do not match."); 6
    validateContext.getBirthDateField().invalidate(dvc.getDialogContext(), "If you "+
                 "want the age to be "+ age +" then birth date should be in year " + 
                  (currentYear - age)); 7
    validateContext.getAgeField().invalidate(dvc.getDialogContext(), "If you want "+
                 " the birth year to be " + yearOfBirth +" then age should be " + 
                  (currentYear - yearOfBirth));
   }
 }
 public void executeDialog(Writer writer, DialogContext dc) 
             throws IOException, DialogExecuteException 8
 {
   writer.write("Congratulations <b>" + 
                 dc.getFieldStates().getState("full_name").getValue().getTextValue() 
                 + "</b>! "); 
   writer.write("It seems that your birthdate and ages match correctly.");
   writer.write("<p>");
   writer.write("This code demonstrated how you can take two three pieces of data, "+
                "have Sparx individually validate the general fields such as text, "+
                "date, and integer but add your own custom validator some other "+
                "logic by creating listeners for various events such as population,"+
                " validation, and execution.<p>");

   String relativePath = 
              "/WEB-INF/classes/app/form/exec/delegation/SampleValidateHandler.java";
   writer.write("You may review the code at " + dc.getConsoleFileBrowserLinkShowAlt(
    dc.getServlet().getServletConfig().getServletContext().getRealPath(relativePath), 
                                                           relativePath));
   writer.write("<p>");
   writer.write("<a href=\""+ dc.getNavigationContext().getActivePage().getName() 
                +"\">Clear the dialog</a>");
 }

}