Some ifw2 terms:
There can be more than one per Flow.
Can be a multi-part form if used to upload files.
Not multi-part forms can be nested, this greatly simplifies rendering decomposition.
They are also usable to update fields content when other fields changes.
First you have to choose between three default implementations of the IForm interface which are:
Then you have to make the form accessible by your ABndsFlow or BndsFlow, ie. register the form in case of a BndsFlow.
... public class AskForVersionLblDlg extends BndsFlow { private final Form ivForm; ... public AskForVersionLblDlg() { super(new JSPRenderer("/WEB-INF/jsp/dyna/ent/AskForVersionLbl.jsp")); ivForm = new Form(); registerForm("form", ivForm); ...
Register any field you need choosing between provided IField implementations:
And set any property or constraint you require.
If the form is a PojoForm and the field is binded to a pojo-property then some constraints are "automatically" discovered by looking at the javax.persistence.Column annotation of the get method, if any.
... ivForm.registerField("tagLabel", new TextField().setMaxLength(20).setMandatory(true).setLabel("Tag label")); ...
Register any required actions.
There are three types of actions:
Can switch the flow state on execution.
They can be triggered by keys/mouse gestures or by a timer.
Cannot switch the flow state on execution
For a sample usage see net.infordata.ifw2.web.form.CalendarAction.
In this example, since the flow will be used as a dialog we register two form actions, one to cancel and one to confirm the inputed data, each of them will cause a state switch on the flow which will, in turn, causes the dialog to close since new states are IFlowEndState.
For another example see: How to open a modal dialog.
... registerFlowState(new FlowState("one"), true); // The beginning flow state registerFlowState(DialogResultEnum.CANCEL); // Predefined IFW2 IFlowEndState registerFlowState(DialogResultEnum.OK); ... // DialogResultAction is a predefined form action which will switch the flow // to the given state ivForm .registerAction("cancel", new DialogResultAction(DialogResultEnum.CANCEL)) .registerAction("ok", new DialogResultAction(DialogResultEnum.OK) { private static final long serialVersionUID = 1L; @Override public boolean onBeforeExecute(ActionInfo action) { return ivForm.validate(null); // validate the form before proceeding } }); ...
Register any stroke you require.
A Stroke is a way to define action triggers directly into your java code without using jsp tags.
... ivForm.getStrokes() .registerStroke(new Stroke("ok")), "okAction") // the ok buttom .registerStroke(new Stroke(KeyEnum.ENTER, true), "okAction"); // the enter key triggers the okAction ivForm.getStrokes() .registerStroke(new Stroke("cancel"), "cancelAction") .registerStroke(new Stroke(KeyEnum.ESC, true), "cancelAction"); ...
Add any IFormValidator you need (better to use IFormValidator2 or APojoFormValidator if you are dealing with a PojoForm).
... ivForm.addValidator(new Validator()); ivForm.validate(null); // trigger a validation immediately ...
Implement your validators, in this example it is an inner class.
... private static final String[] FIELDS = new String[] { "tagLabel" }; private static enum MTPV implements IMessageToken { UNIVOCITY }; protected class Validator implements IFormValidator2 { private static final long serialVersionUID = 1L; @Override public String[] getFieldNames() { return FIELDS; } @Override public boolean isApplicable() { return true; } ... @Override public void validate(IFormView form, String... fieldsToValidate) { AFormField<String> labelField = form.getField(String.class, "tagLabel"); // String value = labelField.getValue(); if (value == null) return; EntityManager em = JpaUtil.getCurrentEntityManager(); EntityTransaction trans = em.getTransaction(); trans.begin(); try { Query query = em.createQuery( "select xx.IId from DynaEntity xx " + " where xx.tagOf=:dynaEntity and" + " xx.tagLabel=:tagLabel") .setParameter("dynaEntity", ivDynaEntity) .setParameter("tagLabel", value); query .setMaxResults(1) .setHint("org.hibernate.readOnly", true); List<?> res = query.getResultList(); if (res.size() > 0) { labelField.setMessage(MTPV.UNIVOCITY, new SimpleMessage("Duplicate value")); } } finally { if (trans.isActive()) trans.rollback(); } } } ...
Finally write your jsp (/WEB-INF/jsp/dyna/ent/AskForVersionLbl.jsp).
Notice the usage of the ifw2:bnd-action-group tag which must surround any action triggering tags but ifw2:bnd-a. It is used also to place action triggers defined in java code via strokes.
<%@ page language="java"%> <%@ taglib uri="http://www.infordata.net/taglibs/ifw2" prefix="ifw2"%> ... <ifw2:bnd-form bind="form"> <table> ... <tr> <td><ifw2:bnd-label bind="tagLabel"/>:</td> <td> <ifw2:bnd-text size="20" bind="tagLabel" focused="1"/> </td> </tr> <tr> <td colspan="2" valign="bottom" align="left"> <ifw2:bnd-action-group id="a" keepFormStrokes="true"> </ifw2:bnd-action-group> </td> </tr> </table> </ifw2:bnd-form> ...