Cmobilecom AF 5.19 Developer Guide

7.3 Property Annotations

An entity view consists of the view components of its properties. A property annotation describes which view components will be used to render the property and how it will interact with user.

Properties are annotated on the hasPropertyAnnotations() method of its EntityBackingBean. For example,


	@Properties({
		@Property(name="phones", entityPropertyType=EntityCollectionProperty.class,
			memberType=String.class, view={ViewType.ALL}),
			
		@Property(name="expense", view={ViewType.ALL}, 
			renderStyle=@RenderStyleDef(size=8,
				number=@NumberDesc(type=NumberDescriptor.Type.CURRENCY)), 
			partialBehavior=@PartialBehaviorDef(event=PartialBehavior.EVENT_CHANGE, 
				execute=VisitTarget.THIS, mode={ModeType.CREATE, ModeType.EDIT}),
			column=@Column(styleClass=EntityProperty.CSS_ALIGN_RIGHT),
			query=@Query(entityPropertyType=RangeEntityProperty.class, orderByProperty=true))		
	})
	public boolean hasPropertyAnnotations() {
		return true; 
	}
see the javadoc for complete annotation options.

Property Grouping

A number of properties can be grouped. A group of properties will be rendered as one property within its parent view container. For example, one row in entity grid view(property name/value for each row), and one column in entity list tabular view.

For the example below, the property "type" and "number" is grouped under the group named "typeNumberGroup". Its member layout can be FLOW, GRID, TABLE, or TAB VIEW.


@Properties({
    @Property(name="typeNumberGroup", visibleName="TypeAndNumber", 
    	grouping=true, userDefined=true,
        renderStyle=@RenderStyleDef(showMemberNames=false, layout=Layout.FLOW, memberSeparator=","),
        view={ViewType.ENTITY, ViewType.QUERY}), 

    @Property(name="type", view={ViewType.ALL}, group="typeNumberGroup",
    		renderStyle=@RenderStyleDef(style=RenderStyle.SELECT_ONE_MENU),
    		query=@Query(orderByProperty=true, groupByProperty=true)),

	@Property(name="number", view={ViewType.ALL}, group="typeNumberGroup",
			renderStyle=@RenderStyleDef(size=2),
			query=@Query(orderByProperty=true))
})			
The grouping is enabled only in ENTITY and QUERY view. In entity list view, the grouping is disabled. The group is user defined and does not belong to the entity type.

Member separator can be a plain or HTML text such as <br/>.

If a parent property has a number of child properties, the parent property can be rendered as a grouping of its child properties.


@Properties({
	@Property(name="address", grouping=true, 
		renderStyle=@RenderStyleDef(showMemberNames=false, layout=Layout.FLOW, memberSeparator="<br/>"),
		view={ViewType.ENTITY, ViewType.QUERY}), 

	@Property(name="address.street", view={ViewType.ALL},
		renderStyle=@RenderStyleDef(size=50)),

	@Property(name="address.city", view={ViewType.ALL}, 
		renderStyle=@RenderStyleDef(size=30),
		query=@Query(orderByProperty=true))
})			

Hidden Parent Property

For a property with multi-level name path, its parent properties will be automatically created if they are not found in annotations, but they are not visible.

@Properties({
    @Property(name="address.street", view={ViewType.ENTITY, ViewType.QUERY},
    		renderStyle=@RenderStyleDef(size=50)),

	@Property(name="address.city", view={ViewType.ENTITY, ViewType.QUERY},
			renderStyle=@RenderStyleDef(size=30),
			query=@Query(orderByProperty=true))
})			
Hidden property "address" will be created for view Type ENTITY and QUERY.

Custom Property

A customer property is not a property of the entity type, and so its name can be any name.

@Properties({
  	@Property(name="level", dynamicValue=true, custom=true,
  		type=Integer.class,
  		view={ViewType.ALL}, mode={ModeType.VIEW, ModeType.QUERY},
  		renderStyle=@RenderStyleDef(size=2))
})			
The type attribute specifies the value type of the custom property.

Re-type

Re-type is used for a property whose value needs to input twice and two values need to be validated to be equal. For example, input password twice during registration.

@Properties({
	@Property(name="password", retype=true,
		minLength=6, maxLength=18,
		view={ViewType.ENTITY}, mode={ModeType.CREATE, ModeType.EDIT},
		renderStyle=@RenderStyleDef(style=RenderStyle.INPUT_SECRET, feedback=true),
		help=@HelpDef(message="InputPasswordHelp", popup=true)),
})			
Re-type will create two EntityProperty(s) and their value equality will be validated.

Hierarchical Select

EntityHierarchyProperty is used for multiple level selection of a hierarchy entity. For example, if Department is defined as Hierarchy, then selecting the department for an employee can be multiple-level selection.

@Properties({
	@Property(name="department",
		entityPropertyType=EntityHierarchyProperty.class,
		renderStyle=@RenderStyleDef(style=RenderStyle.SELECT_ONE_MENU,
			pathShowStyle=PathShowStyle.NAME_PATH),
		view={ViewType.ALL},
		query=@Query(orderByProperty=true))
})    		
A property value can be rendered as a command link so that it can be clicked to trigger partial behavior action event.

@Properties({
	@Property(name="name", view={ViewType.ALL},
		column=@Column(renderStyle=@RenderStyleDef(
			actionOnClick=ActionOnClick.SHOW_ENTITY, 
			style=RenderStyle.COMMAND_LINK, openDialogOnShowResults=true)), 
		query=@Query(orderByProperty=true)),
})		
The attribute openDialogOnShowResults specifies whether to open a dialog to show the action results.

The value of actionOnClick can be SHOW_ENTITY, SHOW_PROPERTY_VALUE, SHOW_PARENT_PROPERTY_VALUE, CUSTOM. For CUSTOM, its action needs to be handled in the EntityBackingBean. For example, show a message onclick:


public class MyTypeBean extends EntityBackingBean<MyType> {
	@Override
	public PageNavigation clickPropertyValue(PersistenceDataBackingBean<MyType> backingBean, 
  			MyType entity, EntityProperty<MyType> property,
  			ContainerRenderRegions containerRenderRegions) throws SystemException {
		if (property.getName().equals("name")) {
			// show a message
  			ContainerBean containerBean = containerRenderRegions.getTargetContainerBean();
  			MapEntityBean<MapEntity> textBean = MapEntityBean.createTextBean(property,  
  				new ParameterizedMessage("Info", true, null),
  				"I am clicked<br/>" + new Date(), true, null, containerBean);
  			return containerBean.showBean(textBean, containerRenderRegions.getRenderRegions(), true);   		
		}
  	
		return super.clickPropertyValue(backingBean, entity, property, containerRenderRegions);
	}
}

Partial Behavior

see Partial Behavior on property value change.

DOM Events For Web


@Properties({
    @Property(name="name", view={ViewType.ALL},
    	domEvent={DomEventDef(event=DomEventSupport.EVENT_CHANGE, 
    		handler="alert('changed')", mode={ModeType.EDIT})})
})			
If a property DOM event handler is dynamic, for example,

	DomEventSupport domEventSupport = property.getDomEventSupport(true);
	domEventSupport.setDynamic(DomEventSupport.EVENT_CHANGE, true);		
its EntityBackingBean needs to provide handler by overriding:

	public String getDomEventDynamicHandler(PersistenceDataBackingBean<T> backingBean,
  		T entity, EntityProperty<T> property, MenuNode menuNode, String event) throws SystemException;

Insert and Define

Property annotations that are defined in a superclass can be overridden by its subclasses. For example,

@Properties({
	@Property(name="period", uiInsert="ui_insert_period", 
    		view={ViewType.ALL}, 
    		converter=PeriodConverter.class, 
    		renderStyle=@RenderStyleDef(size=10)),
 	  		   		
	@Property(name="", uiInsert="ui_insert_more_properties")
})
The "period" property defined as uiInsert which can be overridden by subclass @UIDefine annotation. The next property with an empty name defines a placeholder and subclass can define more properties. A property with an empty name will be ignored if not overridden.

	@UIDefines({
		@UIDefine(name="ui_insert_more_properties", value={
			@Property(name="groupBy", view={ViewType.ALL},  
				renderStyle=@RenderStyleDef(style=RenderStyle.SELECT_ONE_MENU)),
		  				        
			@Property(name="employee", view={ViewType.ALL}),
			@Property(name="code", view={ViewType.ALL})
		})
	})
	public boolean hasPropertyAnnotations() {
		return true; 
	}
A subclass can define uiInsert properties inside the @UIDefine and they can be overridden by its subclasses. Subclasses here mean all descendant classes, not only direct subclasses.

Render Style

A render style is mapped to a UI view component type Select One Menu.

Style numbers are defined in RenderStyle class: constants and their values in parentheses.

Style numbers for new view components can be defined. see Extensions.

EntityProperty

The following are the list of built-in EntityProperty(s): In addition to property annotations, EntityProperty(s) can be created programmatically and added to its backing bean. For example,

	EntityBackingBean entityBackingBean = ...
	EntityProperty property = new EntityProperty(...);
	entityBackingBean.getEntityProperties().add(property);
Users can define their own EntityProperty subclasses. see Extensions.
Entity List Backing BeanForm DesignFrames / No Frames