Property Annotations

Property annotations use 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 related properties can be grouped. A group of properties will be shown as one row in table layout of entity/query view and as one column in entity list view.

For the example below, the property "type" and "number" is grouped under typeNumberGroup. Its member layout can be FLOW, 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

If a parent property has a number of child properties, the parent property can be hidden so that its child properties will be shown at the top level.

@Properties({
    @Property(name="address", hidden=true, 
        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))
})			
The address property is required for their children to be visible, but it can be hidden. The street and city are two top-level properties. Note that the street and city will not be visible in entity list view since their parent address property is not visible.

Custom Property

A customer property is not a property of the entity type, 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 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

EntityCategoryProperty is used for multiple level selection of a hierarchy entity. For example, if Deparment is defined as Hirarchy, then setting the department for an employee can be multiple-level selection.

@Properties({
	@Property(name="department", userDefined=true,
		entityPropertyType=EntityCategoryProperty.class,
		renderStyle=@RenderStyleDef(style=RenderStyle.SELECT_CATEGORY, pathShowStyle=PathShowStyle.NAME),
		view={ViewType.ALL},
		query=@Query(orderByProperty=true))
})    		

Command Link

A property value can be rendered as a command link so that it can be clicked to trigger ajax 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 Behaviors

see Partial Behavior.

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 place holder 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

Render style describes how the property will be rendered on devices and how it will interact with users.

Style numbers: constants and their values in parenthesis.

New styles 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.