1. What is custom method?
You can create custom method and attach it to defined model or view. Using this elements, you can connect defined xml to JAVA code.
To create custom method first you must create service, then implement one or more custom methods. Then you insert reference to created method in xml files.
2. Create custom methods service
2.1. service structure
Custom methods service is basically normal JAVA class. Only additional element is Spring '@Service' annotation.
import org.springframework.stereotype.Service; @Service public class ClassName { // CLASS BODY }
2.2. additional services access
In created service you can access many additional services that helps you manipulate data or view.
Access to outside service are made by Spring '@Autowired' annotation.
import org.springframework.beans.factory.annotation.Autowired; ... @Autowired private ServiceType setviceName;
2.3. additional services
2.3.1. DataDefinitionService
This service provides both information about entities model and access to database operations.
2.3.2. TranslationService
Service used to execute translation to users language.
2.3.3. SecurityService
This service allow you to access informations about current user.
3. custom methods
3.1. Custom validators
Custom validator is used by model to validate entities.
Custom validator function has structure:
public boolean validatorMethodName(final DataDefinition dataDefinition, final Entity entity) { // VALIDATOR METHOD BODY }
Where
- validatorMethodName - name of validator method
- dataDefinition - dataDefinition of validated entity
- entity - entity to validate
This method should return true if validation was successfull and false otherwise.
When validation was unsuccessfull you can also add validation message to entity field using construction:
entity.addError(dataDefinition.getField("fieldName"), "validationMessage");
Where
- fieldName - name of entity model field
- validationMessage - validation message
To attach created validator method to model xml file see 'model custom validators' section.
2.2. Model hooks
Model hooks are methods that is executed on specific model actions (defined in xml file). Model hook method has structure:
public void modelHookMethodName(final DataDefinition dataDefinition, final Entity entity) { // MODEL HOOK BODY }
Where
- modelHookMethodName - name of model hook method
- dataDefinition - data definition of hook event entity
- entity - hook event entity
To attach created model hook method to model xml file see 'custom model event hooks' section.
2.3. View hooks
View hooks are methods that is executed always where request is send to server. View hook method has structure:
public void viewHookMethodName(final ViewDefinitionState state) { // VIEW HOOK BODY }
Where
- viewHookMethodName - name of view hook method
- state - view state
To attach created view hook method to view xml file see 'view hooks' section.
2.4. View listeners
View listeners are methods that is executed when specified event is fired. View listener method has structure:
public void viewListenerMethodName(final ViewDefinitionState state, final ComponentState componentState, final String[] args) { // VIEW LISTENER BODY }
Where
- viewListenerMethodName - name of view listener method
- state - view state
- componentState - component that fired event
- args - array of event arguments
To attach created view listener method to view xml file see 'view listeners' section.
2.5. Row style resolvers
(Grid's) Row style resolvers returns set of CSS clas names for given row entity. You can use them to mark specified grid rows, e.g. whith negative balance of some arbitrary values.
Resolver method is invoked for each of row entity.
public Set<String> rowStyleResolverName(final Entity rowEntity) { // GRID ROW STYLE RESOLVER BODY }
Where
- rowStyleResolverName - arbitrary name of resolver method
- rowEntity - entity which will be shown in row
To see how to bind created resolver method with view component go to 'row style resolvers' section.
3. Example
3.1 Custom validator example
public boolean checkIfOrderHasTechnology(final DataDefinition dataDefinition, final Entity entity) { Entity order = entity.getBelongsToField("order"); if (order == null) { return true; } if (order.getField("technology") == null) { entity.addError(dataDefinition.getField("order"), "products.validate.global.error.orderMustHaveTechnology"); return false; } else { return true; } }
3.2 Model hook example:
(this particular example is used within the <onSave> tag:
public void fillOrderDatesAndWorkers(final DataDefinition dataDefinition, final Entity entity) { if (("02inProgress".equals(entity.getField("state")) || "03done".equals(entity.getField("state"))) && entity.getField("effectiveDateFrom") == null) { entity.setField("effectiveDateFrom", new Date()); entity.setField("startWorker", securityService.getCurrentUserName()); } if ("03done".equals(entity.getField("state")) && entity.getField("effectiveDateTo") == null) { entity.setField("effectiveDateTo", new Date()); entity.setField("endWorker", securityService.getCurrentUserName()); } }
3.3 View hook (preRender) example
public void checkIfCommentIsRequiredBasedOnResult(final ViewDefinitionState state) { FieldComponentState comment = (FieldComponentState) state.getComponentByReference("comment"); FieldComponentState controlResult = (FieldComponentState) state.getComponentByReference("controlResult"); if (controlResult != null && controlResult.getFieldValue() != null && "03objection".equals(controlResult.getFieldValue())) { comment.setRequired(true); comment.requestComponentUpdateState(); } else { comment.setRequired(false); } }
3.3 View listener hook example
public void checkAcceptedDefectsQuantity(final ViewDefinitionState viewDefinitionState, final ComponentState state, final String[] args) { if (!(state instanceof FieldComponentState)) { throw new IllegalStateException("component is not input"); } FieldComponentState acceptedDefectsQuantity = (FieldComponentState) state; FieldComponentState comment = (FieldComponentState) viewDefinitionState.getComponentByReference("comment"); if (acceptedDefectsQuantity.getFieldValue() != null) { if (isNumber(acceptedDefectsQuantity.getFieldValue().toString()) && (new BigDecimal(acceptedDefectsQuantity.getFieldValue().toString())).compareTo(BigDecimal.ZERO) > 0) { comment.setRequired(true); } else { comment.setRequired(false); } } }
3.4 Row style resolver example
public Set<String> productsListRowStyleResolver(final Entity product) { final Set<String> entityStyles = Sets.newHashSet(); final String materialType = product.getStringField(ProductFields.GLOBAL_TYPE_OF_MATERIAL); if ("04waste".equals(materialType)) { entityStyles.add(GridComponent.CSS_RED_BG); } if (StringUtils.isBlank(product.getStringField(ProductFields.EAN))) { entityStyles.add(GridComponent.CSS_BOLD_FONT); } return entityStyles; }