Tuesday, February 9, 2010

Customization of webflows

With the new 1.7 release of sculptor the possibilities to customize flows for the web client is much better.
With our Library example here is what you can do.
For example, lets say you want to implement filter functionality for the library list feature. Here is the steps to do that:

1) Specify that you want gap-files for the list library feature, so in your model.guidesign:

gui Library for Library {
Module for media {
ListTask for Library {
gap
}
}
}

Now you have a bunch of files for the feature:
  • src/generated/java/org...library/ListLibraryActionBase.java
  • src/main/java/org...library/ListLibraryAction.java -> gap
  • src/generated/java/org...library/ListLibraryForm.java
  • src/WEB-INF/generated/flows/media/listLibrary/listLibrary-base.xml
  • src/WEB-INF/generated/flows/media/listLibrary/list_include.xhtml
  • src/WEB-INF/flows/media/listLibrary/listLibrary-flow.xml -> gap
  • src/WEB-INF/flows/media/listLibrary/list.xhtml -> gap

2) Edit the media/listLibrary flow:


<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:ns0="http://www.w3.org/2001/XMLSchema-instance"
ns0:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
parent="media/listLibraryBase">
<view-state id="list">
<transition on="filterLibrary" to="listByFilter" />
</view-state>
<view-state id="listByFilter" model="listLibraryForm"
view="/WEB-INF/flows/media/listLibrary/list.xhtml" parent="media/listLibraryBase#list">
<on-render>
<evaluate
expression="listLibraryAction.findByFilter(flowRequestContext)" />
</on-render>
</view-state>
</flow>

3) Edit the ListLibraryAction, add the method:


public String findByFilter(RequestContext ctx) {
getRepository().clear();

List<library> allLibraries = getLibraryService().findAll(ServiceContextStore.get());
List<library> filtered = new ArrayList<library>();
String filter = ctx.getRequestParameters().get("libraryFilter");
for (Library library : allLibraries) {
if (library.getName().startsWith(filter)) {
filtered.add(library);
}
}
formObject(ctx).setAllLibraries(filtered);
return "success";
}

4) Add a simple form with a text field and a button to the media/listLibrary/list.xhtml-file:


<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core" xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:h="http://java.sun.com/jsf/html" xmlns:c="http://java.sun.com/jstl/core"
xmlns:a="ApplicationTaglib">
<body>
<ui:composition template="/WEB-INF/common/template.xhtml">
<ui:define name="content">
<h1>
<h:outputFormat value="#{msg['list.header']}">
<f:param
value="#{msgMedia['model.DomainObject.Library.plural']}" />
</h:outputFormat>
</h1>
<h:form xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:h="http://java.sun.com/jsf/html" xmlns:c="http://java.sun.com/jstl/core"
xmlns:a="ApplicationTaglib">
<div>
<label for="_libraryFilter">#{msgMedia['model.DomainObject.Library.filter']}: </label>
<input type="text" value="#{requestParameters.libraryFilter}" name="libraryFilter" id="_libraryFilter"/>
<h:commandButton value="#{msgMedia['model.DomainObject.Library.filterButton']}" action="filterLibrary" />
</div>
</h:form>
<ui:include
src="/WEB-INF/generated/flows/media/listLibrary/list_include.html" />
</ui:define>
</ui:composition>
</body>
</html>

Note that the default generated table showing the list result is used by including the generated file. In case you need to modify the generated content you can either overwrite the code generation templates in WebSpecialCases.xpt or simply copy the generated file and maintain it manually

That's it.

No comments:

Post a Comment