Standard Applications
Page Contents
Any Agillic environment comes with a set of standard applications. These are built using only standard API features, and can therefore also serve as examples of how you can create your own applications.
Agillic contains the following applications:
You are welcome to download the code and modify it, however, please create a copy of the application with a different name before doing so.
All Agillic standard applications are built to use configuration to control how it works. These settings are configured using an editor and read at runtime.
Style
All standard applications allow you to select one of a number of different styles. This is achieved by looking at the main stylesheet for the particular application (normally it has the same name as the application itself) and finding all classes that matches a particular pattern (.<applicationname>.<stylename>
). Normally, we implement the styling for each of the possible styles in separate .css files which the main .css file include. If you want to add your own styling to any of our applications you can edit the main .css file and add your own styles there in the same manner (the .css files are never overwritten when we update an application).
On runtime, we set the select style as a class name on the top html element in the application, so you should simply start your .css rules with .<stylename>
to ensure they are only applied when a particular style is selected.
Quickpoll
Quick polls consist of a question, and a number of answer options. Users can easily vote and instantly view the results of the poll, which are displayed in a graphical bar chart. The actual votes are not recorded as Person Data but in a separate table, which means you can place it on anonymous pages and it will still work, even if the user who cast the votes is not in Agillic. It can also be configured to save the value as Person Data and/or achieve an Event (if the user was already known).
The poll uses a specially designed API and taglib to achieve much of the functionality.
Because of the things mentioned above, the quick poll is not a good example of how to do more standard Agillic interaction (creating and updating users), but the code is quite simple and does provide a fairly good overview of how to read configurations and how to create an editor.
Runtime
The index.jsp page which contains all the logic is fairly well documented so it should be fairly easy to read this page and understand what it is we are doing.
The poll taglib is designed to work on more or less the same principle as the render and action tag. It will decide if it should show the question or the answer page based on whether you have answered the poll already or not. This decision is made by looking for a cookie in our browser with the name MARKER.<pollname>
.
The poll form tag is just an extension of the normal form tag in the sdk taglib, but with all of the attributes hardcoded.
The poll uses a built in function called poll.vote which uses the poll API to record your vote and is also checking if events or person data should be recorded.
Editor
The editor consist of two files:
index.html – this defines the html markup for the editor as well as includes the relevant javascript and css files. This particular editor splits the screen into two – the left side is the editor and the right side is a preview of how the final quick poll will look.
quickpollEditor.js – which contains all the logic of the editor. The editor includes the portletEditor.js javascript file which contains the basic functionality provided by Agillic to an editor programmer.
There is a lot of jquery and jquery validation functionality in this editor, which we will not discuss in details, if you find something interesting you wish to talk to us about, you are welcome to contact Agillic Partner Support with your question.
The interesting things to take from this file, if you want to write your own editor, are described below.
Serializing and deserializing
In the bottom of the file, you will find a call to PortletConfigurator.initialize the PortletConfigurator is the js object you get when including portletEditor.js and this is the object which hooks into Agillic.
The configurator provides default serialization and deserialization features which simply finds the form in your html and traverse all input fields and for each of them create a value in the json object which defines the configuration. Since the quick poll has a dynamic table this particular approach is not enough here so we overwrite these functions ourselves. We start both methods by calling the built-in functions to do the main part of the serialization, for serialization this is done with the call PortletConfigurator.defaultOptions.serialize().
Events and Person Data
To create autocomplete drop downs for selecting Person Data and Events we use the following code:
$("#persondata").personDataSelectorCreator({
defaultText:"Select Person Data",
types:["STRING","NUMBER","BOOLEAN"],
typeHolder:$(".typeHolder"),
createButton:$("#persondatacreate")
});
$("#event").eventSelectorCreator({
defaultText:"Select Event",
createButton:"#eventcreate"
});
And the following html:
You can do exactly the same, and the system will automatically serialize and deserialize the selections as well as create the relevant drop downs.
Selecting a style sheet
As described in the section on how to create your own editor. Here is a concrete example:
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if (/.*quickpoll.css$/.test(sheet.href)) {
var themeMatcher = /.*.quickpoll\.([Quickpoll application^ .]+)$/;
var cssRules = sheet.cssRules;
// IE represents css rules differently so adjust accordingly
if (sheet.rules) {
themeMatcher = /.*\.([Quickpoll application^ .]+)\.quickpoll$/;
cssRules = sheet.rules;
}
var themes = {};
jQuery.each(cssRules, function() {
var matches = themeMatcher.exec(this.selectorText);
if (matches) {
var themeName = matches[1];
if (!themes[themeName]) {
themes[themeName] = true;
$("<option></option>").val(themeName).text(themeName).appendTo($("#pollStyle"));
}
}
});
}
}
For this to work, we must also remember to include the .css file in the html:
<link type="text/css" rel="stylesheet" href="../quickpoll.css">
Keep alive and unsaved changes
Since all editing is ajax based, we make calls to ensure that your session does not time out while editing. In the quick poll these calls are made when the method updatePreview is called (all actions in the editor result in an update of the preview, which is handled by that method). The calls themselves are quite simple:
PortletConfigurator.keepAlive();
if (initialized){
PortletConfigurator.showDirtyMessage();
}
The navigation application displays the relevant navigation on a portal page, allowing the users to select the pages they wish to visit.
Runtime
We have generated the navigation to be a list, which should allow most developers to simply add their own stylesheet to get the navigation they want. Look at http://css.maxdesign.com.au/listamatic/ for examples.
The application uses the API methods to get the navigation root item and the name of the portal:
MenuItem menuItem = web.getRootMenuItem();
String portalName = web.getPortalName();
The rest of the code is simply recursively rendering the menu item structure.
Editor
The editor is a bit special in that it does not really allow you to edit the runtime settings (except to control if a logout button should be shown). Instead, it lets you configure preview settings.
The idea is that when you preview a navigation you would probably like to have the navigation items that match the portal and whether you are logged in or not. To achieve this, the system will try to detect these pieces of information (if you are editing a page it will look at all menu items pointing to that page, if you are editing it in the library, it will find all pages that link to that library item and look at their menu items).
These pieces of information are then passed to the previewer that will overwrite the normal API method for getting the menu item structure, with one that loads the one which was resolved by the editor. All of this happens 100% automatically and you do not have to do anything for this to work.
In the cases where it was not possible to uniquely find a portal and a navigation (because the same navigation application is used for both anonymous and logged in pages) you can tell the previewer which portal and navigation you want it to use. This is done by setting the values previewportal and previewnavigation in the configuration object, and that is exactly what the editor for the standard navigation allows the users to do.
In the case that the values could not be found, and no values were specified in the configuration, the system will choose the web portal and the user navigation.
Login
The standard Agillic login application allows you to configure it so it works on both user and advisor portals, and both based on Person Data or special username/password credentials for logging in. If you look at the code for this portlet you can of course see how we do the login logic, but this is also a fine example of how to write an action phase and read the submitted data.
Runtime
Checking if someone is logged in
The login application is made so that you can place it on a page which is referenced as both anonymous and logged-in. In the latter case, we include a special page instead – which can show a message instead of the login box.
The way we check if you are logged in is:
<%
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
%>
<jsp:include page="loggedin.jsp"/>
<%
} else {
%>
...
Knowing that the page was loaded from preview
In the inline editor of pages, we started to load the start page of any application that was inserted into the page being edited. Since it may be that the logic of a particular page should be slightly different if the page was being previewed rather than being accessed for real, we set a marker in the tags so you check which mode a page is in.
This is used in the login application, since the above shown code to tell if you are logged in actually incorrectly believes you are not logged in – and therefore shows the logged in text instead of the login box (which is why you do not see that code in the actual application, it was simplified in that section).
The actual check looks like:
<%
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null && !"true".equals(preview) ) {
%>
<jsp:include page="loggedin.jsp"/>
<%
} else {
%>
...
Reading submitted values in the action phase
Often the built in functions is all you need, but other times you might need to handle the logic yourself – and in such a situation you will probably need access to the submitted values. In the login application we do this exact thing, so below you can see how we get the username and password that was submitted.
Map<String, String> map = flow.getEnteredValues();
String username = map.get("username");
String password = map.get("password");
The input fields were created in the render phase using our normal input tags (but without specifying person data).
<input:text name="username" class="required">
...
</input:text>
Logging users in
There are two different login methods in the API, one for logging in with username/password and one with the internal Agillic id. The login application supports both, and checks the configuration for which type it is.
The main difference between them is that if you use username/password you leave it for the the API to validate the legality of the entered values, whereas in the other the login will always be successful so the validation should be done in finding the id.
Questionnaire
The standard questionnaire is a complex application with an editor guiding the configurator. While the editor is documented, the code behind the is not. Should you wish to copy the application to make changes, you are welcome to do so, but in most cases customers are instead custom coding questionnaire type formulars. Please contact Agillic Support for advise on how to proceed.