Xoetrope

 Wiki : XPojoPanel

HomePage :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register
XUI 4.0

XPojoPanel


XPojoPanel is a panel that takes a reference to a POJO and constructs a user interface for that component based upon the POJO's public properties and methods. The panel configures the data bindings and event handlers for the UI automatically. In declaring an instance of the panel it is possible to provide layout hints for things like the number of columns, spacing, field order, exclusion of fields and more.

The XPojoPanel can be used with POJOs from both Hibernate and Spring as well as other sources.

For example the following code binds to a POJO:

<?xml version="1.0" encoding="UTF-8"?>
	<XPage w="1016" h="734" class="com.myproject.MyController">
	    <Components>
	        <Panel title="My Form" border="0" layout="border">
	          <PojoPanel 
	              name="myForm" 
	              constraint="center" 
	              style="base" 
	              pad="6" 
	              spacing="4" 
	              numCols="2" 
	              dataPath="pojo/myModel/myDataObject" 
	              alwaysDirty="true" 
	              methods="save"
	              fieldValidationRule="MyValidationRule"
	              class="com.myproject.transfer.MyDataObject"
	              fieldOrder="a,c,d,b,f"/>            
	          <Panel constraint="south" layout="flow" align="center" style="base" hgap="6" vgap="6">            
	            <Button name="saveBtn" content="Save"/>            
	          </Panel>
	        </Panel>
	    </Components>
	    <Events>
	      <Event target="saveBtn" method="${pojo/myModel.saveStuff(pojo/model/myDataObject)}" 
	                 type="com.xoetrope.pojo.SaveBeforeActionHandler"/>
	    </Events>
	        <Validations>
	            <Validation rule="MyValidationRule" target="myForm" dataPath="pojo/myModel/myDataObject"/>
	        </Validations>
   </XPage>


where the page is setup as normal and the class com.myproject.MyController is the normal XPage implementation. The key component is the PojoPanel declaration. Here the fields have the following roles:


Building the Panel

In populating the panel the PojoPanel inspects the POJO looking for properties (as defined by the Java Bean specification) and methods (like the save method above). If a method with just a getter is found then it is assumed to be read-only.

Data Binding

When a property is found the PojoPanel sets up the data bindings to the appropriate POJO getter and setter methods. In addition the PojoPanel checks to see if a vocabulary has been defined for the field by checking for the existence of a model node at vocab/<<[field name]>>. If such a vocabulary is found it is assumed that the field value is part of a pick list and a drop down list/combo is displayed for that component. The PojoPanel also inspects the type of each property and tries to assign input fields of the appropriate type, for example a XDateEdit input is created for a date property.

The alwaysDirty attribute controls how the paths are evaluated. Normally the XPojoModel nodes cache their data and do not invoke the POJO method each time they are accessed. If you are trying to binding to a value that might change, such as a current user or a details node in a master-detail relationship then the underlying object might change and therefore the cache becomes out of sync. Setting the alwaysDirty attribute means that the POJO method is always evaluated and it should therefore return the correct value in such a case.

Event Handling

The event handling follows a similar rationale with the method being declared as an evaluated attribute. XUI 4.0 introduces new evaluated attribute support whereby the data model nodes can be referenced and the methods of those objects invoked. In the above setup the saveStuff method of the data model object at the path pojo/myModel is invoked. The method takes one argument and again this is a data model object - in the example it corresponds to the POJO used by the PojoPanel. The event adapter SaveBeforeActionHandler simply calls saveBoundComponentValues beofre the POJO's method is invoked.

Localization

Generally the field or property name is not appropriate for display as a label or prompt and therefore the PojoPanel looks up the language files for a translation of the property name.

Validation

The input fields can be validated on a field by field basis, or for the POJO as whole. If the #fieldValidation attribute of the panel is defined then a field validation is added for each input field and the user input is validated when the input loses focus. If the appropriate styles are configured then the background colour for the inputs will reflect the validation status of the fields.

If a validation rule is specified for the panel as a validation element then the POJO is validated as a whole, that is all fields are validated. It is possible to have both styles or validations or one or the other.

The validation rule used for POJOs should map to a validation that implements the
PojoValidator interface. The interface provides two methods

  /**
   * Validate the pojo
   * @param obj
   * @return the validation result
   */
  public Object validate( Object obj );
	  
  /**
   * Validate a field/property of the pojo
   * @param obj
   * @param fieldName
   * @return the validation result
   */
  public Object validate( Object obj, String fieldName );


The
XPojoValidator is a basic implementation of this interface. Using this object is possible to wrap third party validation frameworks, as during the validator setup the XPojoValidator instance is passed the dataPath attribute, and using the attribute value the validator looks up the POJO upon which it will operate prior to performing the validations.

An example

The above example is rendered as:

wikka logo

Later we will add an additional configuration file to control how the panel is rendered. The configuration will be based upon the options available within the XuiPro editor when creating panels from POJOs with drag and drop.

There are no comments on this page. [Add comment]

Page was generated in 0.1899 seconds