Tag Library

To make writing applications as simple as possible we have made a tag library, which provides support for most of the needs you will have when you write your application.

The idea behind these tags is that you can create applications without any knowledge of jsp or java, so you will find documentation on how to create input fields, validation run specific functions, etc. but if you are new to Agillic applications you should read this introduction to understand how the applications work.

The documentation of the tags is divided into a number of subsections:

  1. Basic tags: The basic input tags and the action and render tags
  2. Validation: Adding validation to the input tags.
  3. Functions: Using the built-in functions to update data
  4. Various: Tags for making links, including text and images etc

If you do not want to read all the details of all tags, you can look at a couple of annotated examples, where we create a few applications in steps explained during the process. This can be a good place to start when you are about to write your first application and does not want to be overloaded by all the details.

In addition to the written documentation here, a javadoc like documentation of the tags is also available for download in your particular instance, see the tools section for further details.

Life-Cycle after Submit

Anytime a form is submitted in an application the following steps are executed.

  1. Submit form
  2. Apply transformers
  3. Run validators – If failed return to page where form was submitted
  4. If next points to a page in the application – then execute the action phase on that page
  5. If a function was defined in the form then execute it – If the function did a redirect (e.g signupLogin) then stop
  6. Either render the next page, or go to the menu item/external link based on the settings in the form

How do Applications work

Action and Render

The first thing to understand is the concepts RENDER and ACTION. Agillic applications are in fact portlets following the first portlet specification, this is where those two concepts come from.

Basically the principle is that any application starts with a RENDER phase, any click or other form submits will result in an ACTION phase followed by a RENDER phase. If you have two applications on a page and submit a form in one then a RENDER phase is run in both applications. The ACTION phase is only run once.

In the taglibrary you will have two tags RENDER and ACTION which mark what should be done in the two phases, you do not have to have both tags on all pages, only the one you need.

If your application have two pages INDEX.JSP and RECEIPT.JSP and a form on INDEX sends you to RECEIPT then the ACTION phase for the form submit on INDEX must be written on the RECEIPT page.

The ACTION tag is only really relevant if you are going beyond using the standard tags, documentation relevant for this type of situation is in the JSP section.

The intial page

The first page in your application must be called index.jsp.

Basic tags

These tags are the most basic building blocks for creating applications, it is very unlikely that your application will not use at least some of these.

The ACTION and RENDER tags control what content is included in the render and action phases. They also expose a number of variables that can be used if you are writing your own jsp code, otherwise you can skip this section and read the input documentation.

Common variables

Name Description
jsplog The logger that can be used for writing messages to the log file
api The CLMUserApi
web The WebHelper
advisorapi The Advisor api
attrs A map containing all Person Data for the current recipient (empty if no recepient is found)
userid The internal id of the logged in user (null if no user is logged in)
flow The flow representing the current application
userkey The value of the person data marked as user_id in the system (null if no user is logged in)
settings The json object representing the settings for this application, as set in the editor
spring The application context for the apps module
action

Include the content inside the tag if you are in an action phase.

Additional variables:

Name Description
portletRequest The underlying action request
portletResponse The underlying action response
render

Include the content inside the tag if you are in a render phase.

Additional variables:

Name Description
renderRequest The underlying render request
renderResponse The underlying render response
preview Has this been called from inside the content designer (“true”/”false”) – only relevant for the index page.

Event

Register an Event to be achieved, for example, a submit or click on a link. The Events are batched and executed when executing a function set on a form. The function does not have to be on the same page as where you define the event. If no function is set on any page this tag is fairly pointless.

Attributes:

Name Description Required
renderRequest The underlying render request User created

Input tags

The input tags are for creating forms with input. The different tags generate as simple markup as possible, and will accept any normal html attributes, so you can style them the same way you would style a normal input tag in html.

You can set the id attribute on any input field, if you do not then we automatically set the value of the name attribute (or clmAttribute if the name attribute was not set) as the id.

Please note that there is no submit tag, to create buttons and similar you should simply use a normal html input tag of type submit or button or javascript to submit the form.

Form

Create a form with the necessary values for the Agillic system to find the next page in the application etc.

Attributes:

Name Description Required Example
function The function to execute when the form is submitted. Available values can be found in the Functions sections No signup
next The page to go to after this. Can also be link to a menu item or an external page Yes Another jsp page (nextpage.jsp) in the same application: nextpage A menu item in Agillic: menu://uri (assumes same portal and type (user/anon) as the current page is) External url: (http://www.company.com)
Text

Create an input tag of type text.

Attributes:

Name Description Required Example
clmAttribute The name of the Person Data to bind the input field to No FIRSTNAME
name The name of the input field No (if not specified the name will be the value of the clmAttribute attribute) MyField
transformer Specification on how to transform the data in the input field when submitted. You can specify more than one by writing a comma separated list of transformers Possible values: trim, upper, lower and none. All names should be pretty self-explanatory No – default is trim Upper case the input: upper Trim and lower case the input: trim,lower
value The default value to show. If clmAttribute attribute is specified on tag, and user already has value, value is ignored No Your name
errorPlacement Overwrite where the error message (validation) is shown, for more on the use of this field please have a look at the Validation section. Possible values are:after, before, none – the position is relative to the input tag. No – default is trim before
Date

Creates input field with special serverside logic for storing Person data of type Date. All attributes available for the text tags is available here as well.

Attributes:

Name Description Required Example
format The display/input format of the value – (see Java docs – Simple Date Format). This format can be different than the date format used inside Agillic. Transformation between the two formats are done automatically Yes dd/MM/yyyy
Textarea

Creates textarea tag. All attributes available for the text tags is available here as well.

Select

Creates select tag. All attributes (except value) available for the text tags is available here as well.

If you set the clmAttribute attribute and use the option tag the system will automatically select the option that the matches the Person Data for the current user.

Option

Creates option tag. If you want to add a default blank valued option we suggest you use the normal html option tag and not this tag – the taglib can handle both without any problems.

Attributes:

Name Description Required Example
name The name of the option. This is the value that will be stored in the system Yes Female
Default options

If you want to have a “Please select” or an “Other” option in your list you can either use the tag or simply insert a normal tag. Please note that some browser will submit the display value if no value is provided so you need to write <option value="">Other</option> rather than simply <option>Other</option> if you want a blank value to be submitted to the validations and stored.

Radiogroup

Simple wrapper for radion buttons so that clmAttribute, name, errorplacement doesn’t have to be specified on every nested radiobutton tag. This tag will only generate markup if a validation error has occured (and the errorPlacement is not set to none. All attributes (except default) available for the text tags is available here as well.

Radio

Creates input tag of type radio. All attributes (except value) available for the text tags is available here as well. For ease of you please look at the radiogroup tag.

Atrributes:

Name Description Required Example
value The value of the radio button Yes Female
Checkbox

Creates input tag of type checkbox. Submitted value is either “true” or “false”, making it easy to bind to person data of type Boolean.

A common issue with checkboxes is that they are not submitted if they are not checked, which can make it difficult to detect changes from “checked” to “unchecked” – this is not an issue with these tags as the taglib keeps track of all checkboxes on the page and ensures that any checkbox not submitted will get the value “false”.

Attributes:

Name Description Required Example
value The value of the radio button Yes Female
Password

Creates input tag of type password. The only difference from a text tag is the type on the generated input field. All attributes available for the text tags is available here as well.

Hidden

Creates input tag of type hidden. The only difference from a text tags is the type on the generated input field. All attributes available for the text tags is available here as well, though putting validations and errorMarkers on a hidden field is usually not a good idea.

Validation

All built-in validators can be enabled by setting either classes or attributes on the tag or adding sub-tags to the tag.

Class based validations

Settings the below mentioned names as classes will enable that particular validation.

Class name Description Example
value The field must not be blank. Validates that the value is not empty (so an empty option in a drop down can also trigger a required validation error) class=”required”
email Validates that the input is an email. Please check the “Things to be aware of” section for a few details on how it validates class=”email”
digits Only number allowed class=”digits”
unique Validates that value is unique for the specified Person Data (only makes sense if the clmAttribute attribute is set. Please check the “Things to be aware of” section for a few details on how it validates class=”unique”
exists Validates that value exists as a value for the specified Person Data (only makes sense if the clmAttribute attribute is set. Please check the “Things to be aware of” section for a few details on how it validates. class=”exists”

Attribute based validations

You can set the following attribute to make some basic value validations.

Attribute name Description Example
max The number must be less than or equals the specified value. Should be used in conjuction with the digits class max=”10″
min The number must be greater than or equals the specified value. Should be used in conjuction with the digits class min=”10″
maxlength The length of the input must be less than or equals the specified value. Makes most sense with text or textarea tags maxlength=”5″
minlength The length of the input must be greater than or equals the specified value. Makes most sense with text or textarea tags minlength=”5″

Subtags

A few of the validations require a bit that just a name or a simple value. So you need to use the subtags for those.

regexp

Validates that the input matches the regular expression. You can see a basic example here, for more examples please check the examples section.

Attributes:

Name Description Required Example
errorKey The identification code for error messages. Please read the Error messages and error placement section for more details Yes “danishPostcode”

Example:

<inp:text clmAttribute="CUSTOMER_ID">
<!-- our customer id is 2 characters, 4 digits and 5 characters, validate that the input is that -->
<inp:regexp key="non_cid">[a-z]{2}[0-9]{4}[a-zA-Z]{5}</inp:regexp>
</inp:text>
  • customvalidator*
  • > Description fully in its own section below. This tag requires a bit of coding knowledge to use as you are writing your own validation code

Error messages and error placement

Placing the error message

On all input fields there is an attribute called errorPlacement, it can have one of three values before, after, none and control where the error message is shown (relative to the input field) – the default value is after.

We generate the following markup:

<label class="error" for="<field_id>" generated="true">the message</label>

If you use none the message is not shown near the field, but you can still place an error anywhere else on the page, by using the fielderror tag.

Fielderror

The fielderror tag lets you place an error message anywhere on the page. If no error was found for the given input field then this tag will do nothing.

The content that the tag writes can be one of two:

  1. If the tag has body content then that is printed – good if you want to create your own markup rather than use the standard label
  2. If not then the message is the content shown above – good if you just want to place the error a different place

If you use body content we expose a number of fields you can use when generating the content:

Name Description Example
errorcode The errorKey of the failed validation class=”required”
enteredvalue The value the user entered test@agillic.com
arguments An array of arguments given to the validator (e.g the min/max value) maxlength=7
message The evaluated message, i.e the content we shown in the labels we generate Please enter a valid email

For most people the message attribute will be more than enough.

Attributes:

Name Description Required Example
for Identifies the field for which the error message is shown Yes FIRSTNAME

Examples:

Wrap the label in a span, but do nothing to the content.

<span>
<inp:fielderror for="FIRSTNAME"/>
</span>

Drop the label and use a div instead.

<span>
<inp:fielderror for="FIRSTNAME">
<div class="myerror">
<%= message %>
</div>
</inp:fielderror>
</span>

Resolving the message

There are two different ways to set the error message content for a particular input field and error:

  • explicit: use a tag to define the message
  • implicit: load the message from a resource bundle
Explicit

Use the tag errormsg

Place it inside an input field to use that particular message for that particular input field. The content of the tag is the message that will be show. This option is nice if you are building dynamic forms and have dynamic validations and error message for each field. It is used extensively in the built-in {questionnaire}} application. You do not have to map all possible errors explicitly, if no explicit tag is set for a particular errorKey the system will find the errorKey implicitly

Attributes:

Name Description Required Example
errorKey The type of error to show the message for Yes required

Example:

<inp:text clmAttribute="FIRSTNAME">
<inp:errormsg errorKey="required">Please supply your first name</inp:errormsg>
</inp:text>
Implicit

If the validation fails the system will try and locate an error message in the resource bundle that matches this error. This is done by a number of look-ups until a message is found. The order of look-ups is as follows:

  1. <fieldid>.<errorkey>
  2. <fieldid>
  3. <errorkey>
  4. fieldValidation.defaultError

I.e if you have:

<inp:text clmAttribute="EMAIL" class="required"/>
and the user has not entered any value the system will do the following look-ups
  1. EMAIL.required
  2. EMAIL
  3. required
  4. fieldValidation.defaultError

The errorkey is always the class/attribute name, for regexp and customvalidation you specify the validation yourself.

Creating messages

To create your own messages you should place a properties file called resources.properties in the folder for your portlet:

webapps
    apps
        yourapp
            resources.properties

A properties file follows a simple key value format separated by newlines. I.e.

required: This field is required

email: Please enter a valid email address

Default messages

If you do not provide a resources.properties file, the following default file is used.

**Default validation messages for resource.properties:**

required: This field is required.
email: Please enter a valid email address.
digits: Please enter only digits.
maxlength: Please enter no more than {0} characters.
minlength: Please enter at least {0} characters
max: Please enter a value less than or equal to {0}.
min: Please enter a value greater than or equal to {0}.
unique: This value is not unique.
exists: The value was not found.
afterdate: Please enter a date after {0}.
beforedate: Please enter a date before {0}.
date: Please enter a valid date in the format {0}.
time: Please enter a valid time in the format {0}.
list: Please enter one of the following values: {0}.
boolean: Please enter 'true' or 'false'.
fieldValidation.defaultError: The value did not validate

Javascript

By default we do not add any javascript validation, but the way to set validators have been taken from the jQuery validate plugin. So if you include this validation script and follow the documentation you should get javascript validation out of the box (excluding regexp, unique and exists).

Custom validators

While the buildin validators help a lot, there are cases where custom logic is needed. Some examples

  • Crossvalidation – i.e. Field A is checked, so field B must be filled with a number
  • Performing checksum calculation on danish social security number.

The input tags allow you to nest a customvalidator, which allows you to hook up a CustomValidator:

You Email address
<inp:text clmAttribute="email" class="required email">

Please repeat you email
<inp:text name="emailrepeat" class="required">
 <inp:customvalidator>
  <%
    field.addValidator(new CustomValidator("emailRepeat") {
      // simple cross validation of email and repeat email value
      public boolean validate(String fieldVal, CLMUserApi clmUserApi, Map allEnteredValues) {
         return fieldVal.equals((String)allEnteredValues.get("email"));
      }
    });
   %>
</inp:customvalidator>

The method CustomValidator.validate should simply returns a boolean to indicate if the validation passed.

Automatically added

If any of the tags have been connected to a Person Data the tag will automatically look at the type of field and add a validation that the input is of that type (numbers and dates).

If there have been made a restriction in the Data Manager on the Person Data that restrcition will automatically be added as a validator.

This means that you do not have to manually add these restrictions when setting up your form.

Things to be aware of

There are a few things related to the Agillic validators which can be a bit tricky to understand. There are explained here, which hopefully should make it even more clear.

Validators and empty values

All validators (except required) will pass if the value is empty. So if you want to prevent empty values then you should also add required to the field.

Email validator is somewhat “loose” in it’s validation

The built-in email validator validates that the email address is a valid email according to the JavaMail interpretation of the specification. This means that an input of type test@test will be accepted (since it follows the spec). Often this is not what you want, and if you want a more standard email validation we suggest you add a regexp validation. For good examples of email regular expression have a look here, or check out the examples where we also have one with a email validation using regular expression.

How exactly does unique work ?

unique ensures that the value entered is unique in the database (i.e no non-deleted user has that value). There is an exception to this rule: If we have identified a user (e.g because the user is logged in), then unique will allow the value to be used by the identified user.

The idea behind the behaviour is to support the case where you have a form where you can update you email and phone number. In such a case you will probably want to ensure uniqueness on both, but it should still be possible to change your email without getting an error that the phone number is not unique.

How exactly does exists work – and where does it make sense ?

exists is the opposite of unique – i.e it ensure that the value is actually present in the system.

This validation is generally not used that much, but makes sense if you have an anonymous page where people are to finish a signup – there it makes sense to ensure that the data you will match on is actually already present in the database.

Examples

Using class and attribute based validation, setting errorPlacement before:

Using regular expression validators. Here you can see an example of an alternative email validator

An example of using a custom validator

Different ways of doing error placement

Functions

To make it easy to do standard logic such as create a new user based on the input or updating a user based on input Agillic provide a set of functions you can set on the form tag to control what happens when the form is submitted.

Below you will see the list of them along with a description of how they work.

signup

Create a new user based on the given input.

This method requires that you have specified an input tag that is linked to the Person Data defined as user_id in the system. If this is not the case it will fail with a NullPointerException

The method does the following:

  1. Create a person with all the Person Data submitted by the form
  2. If any events have been registrede achieve these for the user
  3. Calls web.storeIdInSession with the create internalId
  4. Sets the Agillic identifier cookie to point to the created user in the browser. More on cookies in the Cookies section.

signupLogin

Does the same as signup. If the signup was a success then it will redirect the user to the menu item identified in the next attribute (the menu item must be in the user part of the navigation).

events

Achieve the Events registered using the event tag. This method assumes that either the user is logged in or a call has been made to web.storeIdInSession with the internalId of the user to achieve the Events for.

login

Logs in the user that has been identified by a call to web.storeIdInSession. Generally this function is not that all that useful and it is often better to look at the Login application for examples of how you log people in, or use signupLogin for logging in new people.

update

Updates the submitted Person Data and achieves any events identified by the event tag. This method assumes that either the user is logged in or a call has been made to web.storeIdInSession.

updateByKey

Updates the user (same as the update method identified by the value in the input field that is linked to the Person Data marked as user_id, therefore that person data must be linked for this method to work. This mainly makes sense for anonymous pages to finish a registration or similar. This is a good example of where the exists validation makes sense.

signupOrUpdate

This function is designed to help you create forms that are both available to logged in and not logged in users. It will basically call either signup, update or updateByKey. The decision is made the following way:

  1. If the user is logged in: use update
  2. Check for the entered value in the input field linked to the user_id (fail if field not set), if the value is in use call updateByKey
  3. Call signup

This method can be quite useful, but also slightly dangerous – in many cases the validations are difficult to manage and to get to work for both logged in and anonymous cases. So in many cases it might be smarter to create two applications one for each case instead.

Examples

SignupLogin example

Signup – but failing because the user_id was not specified

Update

Various

There is a set of tags which can help you create links or include content in the application. Most people does not need these, but they can come in handy from time to time.

link

Creates link URLs. These can either be printed or stored in a variable for later use. Please note that using this link will go to the specified page, but not run the action phase on that page, only the render phase.

Attributes:

Name Description Required Example
value What should we link to, can both be an external site, a menu item or another page in the application. See examples for the different syntax Yes A. Link to a menu item: menu://menuuri B.Link to an external page: http://www.company.com C. Link to the receipt.jsp page in this application: receipt
var Name of attribute to store the generated url in No, if not specified it is printed directly backline

Examples:

Link to a Menu Item:

<sdk:link value="menu://login var="loginpage"/>
<a href="<%=loginpage%>">Go to login</a>

Link to the receipt.jsp page in the application (actully it does not link but just prints in):

<div style="display:none">
<sdk:link value="receipt"/>
</div>

param

Used along with the link tag – adds parameters to the link.

Attributes:

Name Description Required Example
name The name of the parameter Yes email
value The value of the parameter Yes test@agillic.com

Examples: Create a link to signup with two parameters, one with a hardcoded value and one with a dynamic (but somewhat silly) value:

<sdk:link value="menu://signup" var="thelink">
<sdk:param name="source" value="front"/>
<sdk:param name="random" value="<%=Math.random()%>"/>
</sdk:link>
<a href="<%=thelink%>">Go to signup</a>

resource

Create a URL to the given resource in the media browser.

If ‘var’ attribute is omitted the resource link is printed to out.

Attributes:

Name Description Required Example
resource The resource to link to – relative to the root of the resource folder in the media browser Yes forms/images/button.gif
var Name of attribute to store the generated url in No, if not specified it is printed directly image

Example:

<sdk:resource resource="forms/images/button.gif" var="image"/>
<img src="<%=image%>">

html

Gets the content of a textual resource (HTML,TEXT) from the media browser.

If ‘var’ attribute is ommitted the content printed to out.

Please note any Person Data in the content will not be expanded.

Attributes:

Name Description Required Example
resource The resource to link to – relative to the root of the resource folder in the media browser Yes forms/images/button.gif
var Name of attribute to store the generated url in No, if not specified it is printed directly image

Examples:

<div>
<sdk:html resource="forms/html/generic header.html"/>
</div>

Annotated examples

In this sesction you will find a few full cycle examples of how to create applications. During the process we explain what is done and what it means.

  • signup: Create a signup form
  • update: Create a form for updating your data
  • signup: Create a signup form – Advanced

The two first examples are very basic, but will probably help you get started. The last example is also a signup – in this we will introduce a bit more complexity to cover more of what is available for users. The steps here will be a bit bigger, so you should probably read the first signup example before looking at the last example.

Signup

In this example we will create a signup form over two pages. The final code is attached to this page.

1. Create the first page

First we create the index.jsp page. The name index is required for the first page in any application. We also give it the default skeleton:

<%@ taglib prefix="sdk" uri="http://agillic.com/jsp/sdk/1.0" %>
<sdk:render>
    Your form will go here
</sdk:render>

The render tag ensures that this block is shown during the render phase.

2. Add a form

Ok, nice first page but a bit blank we will now add a form. We use the agillic taglib form so we get all the Agillic logic for free. Let’s also create an input field for the EMAIL address.

<%@ taglib prefix="sdk" uri="http://agillic.com/jsp/sdk/1.0" %>
<%@ taglib prefix="inp" uri="http://agillic.com/jsp/sdkinput/1.0" %>
<sdk:render>
    <inp:form>
        <label>Email</label>
        <inp:text clmAttribute="EMAIL"/>
    </inp:form>
</sdk:render>

The text tag creates an input tag of type text.

3. Adding a few more fields and a button

We also want to prompt the user for first and last name so let’s create inputs for those – along with a checkbox that user accepts the terms and conditions.

...
<label>Firstname</label>
<inp:text clmAttribute="FIRSTNAME"/>

<label>Surname</label>
<inp:text clmAttribute="LASTNAME"/>

<inp:checkbox clmAttribute="TCACCEPTED"/>
<label>I accept the terms and condition</label>

<input type="submit" value="Next">
...

Notice that the input button is a “normal” html button.

4. Adding a bit of validation and transformation

Before we go on to the next page in our flow. We need to add a bit of restrictions.

We want to ensure the following:

The user has entered a value in the email field and the value is actually an email. The email entered is unique in the system – we do not want email clashes in the system The user has checked the checkbox By default all entered values are trimmed (removing leading and trailing whitespaces), but we only want emails in lowercase in our system so we will also add an extra transformation on that field.

Therefore we make the following updates:

...
<inp:text clmAttribute="EMAIL" class="required email unique" transformer="trim,lower"/>
...
<inp:checkbox clmAttribute="TCACCEPTED" class="required"/>

Setting those classes on the tag tells tag to add those validators. Setting the transformer attribute tells it do both trim and lower cases the value.

Setting required on a checkbox tells it that it most be checked to validate.

5. Going to the next page

We want to go to a page called interest.jsp after you are done with page one, we create that page using the same initial steps as when we created index.jsp. To tell the system which page to go to we make the following change:

...
<inp:form next="interest">
...

6. Creating the interest page

In the real world this page would server no purpose. It’s here to show you how to make a multi-page application, and show you how to added drop-downs and radio buttons.

<%@ taglib prefix="sdk" uri="http://agillic.com/jsp/sdk/1.0" %>
<%@ taglib prefix="inp" uri="http://agillic.com/jsp/sdkinput/1.0" %>
<sdk:render>
    <inp:form>
        <label>Favorite color</label>
        <inp:select clmAttribute="COLOR">
            <inp:option value="red">Red</inp:option>
            <inp:option value="blue">Blue</inp:option>
            <inp:option value="green">Green</inp:option>
            <inp:option value="yellow">Yellow</inp:option>
            <inp:option value="other">Other</inp:option>
        </inp:select>

        <label>Favorite color</label>
        <inp:radiogroup clmAttribute="LEASTCOLOR">
            <inp:radio value="red"/>Red<br/>
            <inp:radio value="blue"/>Blue<br/>
            <inp:radio value="green"/>Green<br/>
            <inp:radio value="yellow"/>Yellow<br/>
            <inp:radio value="other"/>Other<br/>
        </inp:radiogroup>

        <input type="submit" value="Signup">
    </inp:form>
</sdk:render>

7. Creating the user

When the user clicks the button on the second page we want to create the user and do a login (sending the user to the /welcomepage page).

To achieve this we simply add the following:

...
<inp:form next="menu://welcomepage" function="signupLogin">
...

8. Achieving an Event

We want to send an email when the user is signed up, the easiest way to do that is to trigger an Event when we execute the form so we make this final change.

...
<inp:form next="menu://welcomepage" function="signupLogin">
        <sdk:event name="signedUp"/>
...

Getting the event to send the email is all configuration issues and not covered here.

9. Making it a bit more pretty

Ok, now the functionality is in place, but it’s not all that pretty we want to style it a bit so it looks better. The changes documented here is not really a full styling only a few examples of what is possible to do.

So now the form on the first page will look like:

...
<label>Email</label>
        <inp:text clmAttribute="EMAIL" class="required email unique textinput" transformer="trim,lower"/>

        <label>Firstname</label>
        <inp:text clmAttribute="FIRSTNAME" class="textinput"/>

        <label>Surname</label>
        <inp:text clmAttribute="LASTNAME" class="textinput"/>

        <inp:checkbox clmAttribute="TCACCEPTED" style="border: 2px solid red" class="required"/>
        <label>I accept the terms and condition</label>

We have now set extra classes on all the text tags. All classes are outputted directly to the generated input tag. The validation framework will ignore any class name that is does not know.

Any attribute you set on a tag that is not one of the required values for that tag, such as the style tag on the checkbox, is also transferred directly to the outputted tag

10. Done

Your application is done, and can be uploaded.

Signup code examples

The first page of the example

The last page of the example

Update

In this example we will create a update form on one page. The final code is attached to the page.

1. Create the first page

First we create the index.jsp page. The name index is required for the first page in any application. We also give it the default skeleton:

<%@ taglib prefix="sdk" uri="http://agillic.com/jsp/sdk/1.0" %>
<sdk:render>
    Your form will go here
</sdk:render>

The render tag ensures that this block is shown during the render phase.

2. Add a form

Ok, nice first page but a bit blank we will now add a form. We use the agillic taglib form so we get all the Agillic logic for free. Let’s also create an input field for the EMAIL address.

<%@ taglib prefix="sdk" uri="http://agillic.com/jsp/sdk/1.0" %>
<%@ taglib prefix="inp" uri="http://agillic.com/jsp/sdkinput/1.0" %>
<sdk:render>
    <inp:form>
        <label>Email</label>
        <inp:text clmAttribute="EMAIL"/>
    </inp:form>
</sdk:render>

The text tag creates an input tag of type text.

3. Adding a few more fields and a button

We also want to prompt the user for first and last name so let’s create inputs for those.

...
<label>Phone</label>
<inp:text clmAttribute="MSISDN"/>

<label>Firstname</label>
<inp:text clmAttribute="FIRSTNAME"/>

<label>Surname</label>
<inp:text clmAttribute="LASTNAME"/>

<inp:checkbox clmAttribute="CONTACT_ACCEPT"/>
<label>Agillic can contact me</label>...

Notice that the input button is a “normal” html button.

4. Adding a bit of validation and transformation

Before we go on to the next page in our flow. We need to add a bit of restrictions.

We want to ensure the following:

  • The user has entered a value in the email field and the value is actually an email.
  • The email entered is unique in the system – we do not want email clashes in the system
  • Same for msisdn (not valid email but the rest)

By default all entered values are trimmed (removing leading and trailing whitespaces), but we only want emails in lowercase in our system so we will also add an extra transformation on that field.

Therefore we make the following updates:

...
<inp:text clmAttribute="EMAIL" class="required email unique" transformer="trim,lower"/>
...
<inp:text clmAttribute="MSISDN" class="required digits unique"/>
...

Setting those classes on the tag tells tag to add those validators. Setting the transformer attribute tells it do both trim and lower cases the value.

Please note that in the case where you update your own profile the unique validation will not fail if you are not changing the value in the input field.

5. Updating the user

When the user clicks the button we want to update the user.

To achieve this we simply add the following:

...
<inp:form next="index" function="update">
...

Adding next=”index” instructs the system to stay on this page.

6. Making it a bit more pretty

Ok, now the functionality is in place, but it’s not all that pretty we want to style it a bit so it looks better. The changes documented here is not really a full styling only a few examples of what is possible to do.

So now the form on the first page will look like:

<label>Email</label>
<inp:text clmAttribute="EMAIL" class="required email unique textinput" transformer="trim,lower"/>

<label>Phone</label>
<inp:text clmAttribute="MSISDN" class="required digits unique textinput"/>

<label>Firstname</label>
<inp:text clmAttribute="FIRSTNAME" class="textinput"/>

<label>Surname</label>
<inp:text clmAttribute="LASTNAME" class="textinput"/>

<inp:checkbox clmAttribute="CONTACT_ACCEPT" style="border: 2px solid red"/>
<label>Agillic can contact me</label>

We have now set extra classes on all the text tags. All classes are outputted directly to the generated input tag. The validation framework will ignore any class name that is does not know.

Any attribute you set on a tag that is not one of the required values for that tag, such as the style tag on the checkbox, is also transferred directly to the outputted tag.

7. Done

Your application is done, and can be uploaded.

Update code examples

All the code for creating an update form.

Sign up – advanced

In this example we will create a update form on one page. The final code is attached to the page.

1. Create the first page

First we create the index.jsp page. The name index is required for the first page in any application:

<%@ taglib prefix="sdk" uri="http://agillic.com/jsp/sdk/1.0" %>
<%@ taglib prefix="inp" uri="http://agillic.com/jsp/sdkinput/1.0" %>
<sdk:render>
    <inp:form next="menu://welcome" function="signupLogin">
        <label>Email</label>
        <inp:text clmAttribute="EMAIL" class="required email unique" transformer="trim,lower"/>

        <label>Phone</label>
        <inp:text clmAttribute="MSISDN" class="required digits unique"/>

        <label>Firstname</label>
        <inp:text clmAttribute="FIRSTNAME"/>

        <label>Surname</label>
        <inp:text clmAttribute="LASTNAME"/>

        <input type="submit" value="Signup">
    </inp:form>
</sdk:render>

Readers of the previous annotated examples will know that this is a simple form with four fields, that on submit will sign me up and then log me in (going to page with uri /welcome).

2. Regular expression validation

We want to add a field where people should write their subscriber id (whatever that is). We know that a legal subscriber id is 6 characters, a dash and 6 characters and want to ensure that all entered values have that format. To that end we add a regular expression validation, and have the following code:

<label>SubscriberId</label>
<inp:text clmAttribute="SUBSCRIBERID" class="required unique">
   <inp:regexp errorKey="subscriber">[a-z]{6}-[a-z]{6}</inp:regexp>
</inp:text>

In addition to the regular expression I have also added unique to ensure uniqueness of the subscriber ids and required. When you look at the regular expression you will perhaps wonder why I have added required – the expression does not accept empty strings, the reason is that all validators (except for required) will accept the empty string – so even if you have a regular expression that prevents blank strings it will be accepted.

3. Validating repeated input

To ensure that the email address is inputted correctly we want to add an extra field and ask people to enter the email twice, and then validate that the input is the same in both fields. None of the standard validators can do this, but then we will simply write our own piece of code that can make this check.

Extra import in the file (placed at the very bottom of it):

<%@ page import="com.agillic.portletsdk.CLMUserApi" %>
<%@ page import="com.agillic.sdk.flow.validators.CustomValidator" %>
<%@ page import="java.util.Map" %>

And the extra field with the validator:

<label>Repeat email</label>
<inp:text name="reemail" class="required" transformer="trim,lower">
   <inp:customvalidator>
      <%
         field.addValidator(new CustomValidator("emailRepeat") {
            // simple cross validation of email and repeat email value
            public boolean validate(String fieldVal, CLMUserApi clmUserApi, Map allEnteredValues) {
               return fieldVal.equals(allEnteredValues.get("EMAIL"));
            }
          });
      %>
   </inp:customvalidator>
</inp:text>

Notice that the input field does not have the clmAttribute set, this is because we do not want to save the value on the user just validate it. When doing custom validation you have access to the entered value, all the entered values in the flow, and the the CLMUserApi so you can make queries and similar.

4. Moving an error message

We have set the repeat validation on the repeat email field, but actually we want to show the message next to the email field. We could just have set the validation on the email field of course, but here we do something else. We change where we place the error message.

<label>Email</label>
<inp:text clmAttribute="EMAIL" class="required email unique" transformer="trim,lower"/><inp:fielderror for="reemail"/>

<label>Repeat email</label>
<inp:text name="reemail" class="required" transformer="trim,lower" errorPlacement="none">

Two things:

  • We set errorPlacemnet=”none” on the repeat field – this disables the error messagage handling on that input field.
  • We use the fielderror tag to mark where we want the error shown instead (in this case just after the email input field).

By default all entered values are trimmed (removing leading and trailing whitespaces), but we only want emails in lowercase in our system so we will also add an extra transformation on that field.

5. Done

Your application is done, and can be uploaded.

Signup code examples

The full example