Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When a form step is submitted, the posthandling process is followed. In this case, the routing result is handled and the user is redirected accordingly. Form logic can be extended by installing a form logicProvider formlogicProvider plugin. Such form logicComponents can be written in either Java, JavaScript or a combination of both. What actually happens when a form is rendered or submitted is much more complex (see The Form Engine for more details).

...

This package provides interfaces that enable plugin developers to create their own form fragments. A form fragment uses the FormFragmentComponent to become a component, and is therefore able to be managed by the Component Manager. The FormFragmentComponent interface ensures a unified way of creating form fragment instances through the createInstance() method. The FormFragmentComponentType interface introduces the component type that identifies the class of form fragment components. The FormFragmentComponentDefinition defines the relationship between the component, component type, form fragment implementation class and more.

nl.gx.forms.wmpformapi.plugin.

...

formlogicProvidertype

This package provides interfaces that enable plugin developers to write their own form logic. The form logicProviderComponent formlogicProviderComponent is the XperienCentral component that provides form logic (routers, handlers and validators). Form logic typically implements this interface. The form logicProviderComponentType formlogicProviderComponentType interface introduces the component type that identifies the class of form logic components. The form logicProviderComponentDefinition formlogicProviderComponentDefinition defines the relation between the component, component type, form logic implementation class, and so forth. All form logic components typically implement the form logicProviderService formlogicProviderService, which allows them to be executed by the form engine.

...

The following table shows the Java interfaces used by the Interactive Forms form fragments.


Form Fragment NameJava Interface
Textnl.gx.forms.wmpformfragments.api.FormFragmentTextInput
Numbernl.gx.forms.wmpformfragments.api.FormFragmentNumberInput
Datenl.gx.forms.wmpformfragments.api.FormFragmentDateInput
Passwordnl.gx.forms.wmpformfragments.api.FormFragmentPasswordInput
Textareanl.gx.forms.wmpformfragments.api.FormFragmentTextArea
Radionl.gx.forms.wmpformfragments.api.FormFragmentRadioList
Checkboxnl.gx.forms.wmpformfragments.api.FormFragmentCheckboxList
Dropdownnl.gx.forms.wmpformfragments.api.FormFragmentDropDownList
Uploadnl.gx.forms.wmpformfragments.api.FormFragmentFileUpload
Emailnl.gx.forms.wmpformfragments.api.FormFragmentEmailInput
Columnsnl.gx.forms.wmpformfragments.api.FormFragmentColumns
Sectionnl.gx.forms.wmpformfragments.api.FormFragmentSection
Form Sectionnl.gx.forms.wmpformfragments.api.form.FormFragmentFormSection
Repeatnl.gx.forms.wmpformfragments.api.form.FormFragmentRepeat
Next Buttonnl.gx.forms.wmpformfragments.api.FormFragmentButton
Back Buttonnl.gx.forms.wmpformfragments.api.FormFragmentBackButton
Paragraphnl.gx.forms.wmpformfragments.api.FormFragmentParagraph
Overviewnl.gx.forms.wmpformfragments.api.FormFragmentOverview

...

  • Execute the following command to generate the helloworldfragment plugin:

    mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=nl.gx.forms.wmpformarchetypes -DarchetypeArtifactId=wmpformfragment-archetype -DarchetypeVersion=10.10.0 -DgroupId=com.gxwebmanager.helloworld -DartifactId=helloworld -Dclassprefix=HelloWorld -s <my_path_to_settings.xml>\settings.xml

  • Execute the following command to generate the helloworldlogicprovider plugin:

    mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=nl.gx.forms.wmpformarchetypes -DarchetypeArtifactId=wmpform logicproviderwmpformlogicprovider-archetype -DarchetypeVersion=10.10.0 -DgroupId=com.gx.webmanager.helloworld -DartifactId=helloworld -Dclassprefix=HelloWorld -s <my_path_to_settings.xml>\settings.xml


...

The implementation class (for example, CustomFragmentImpl) must contain the method getDefaultValidators(). This method returns the validator(s) that you want to use by default. If the fragment is added to the form step in the Interactive Forms interface, this set of validators will be assigned. The validators that are retrieved by this method have to be present in the framework. Create Your Own Form Logic Components explains how to create a fragment validator. Suppose a fragment validator is present in the bundle activator:


Code Block
themeEclipse
form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl def = new form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl(false, form logicProviderComponentDefinitionformlogicProviderComponentDefinition.FORM_LOGIC_PROVIDER_TYPE_FRAGMENTVALIDATOR, pluginConstants.MY_VALIDATOR_IDENTIFIER);

...

Form Logic is a generic term for handlers, routers, form validators and fragment validators. A form logic component implements both the form logicProvidercomponent formlogicProvidercomponent interface and the form logicProviderService formlogicProviderService interface. Usage of these interfaces requires the implementation of the run() method.

...

Code Block
themeEclipse
class implements form logicProvidercomponentformlogicProvidercomponent,formformlogicProviderService logicProviderService {
	public RoutingResult run(FormScope scope, Map<String, Object> parameters,Map<String, Object> languageLabels) {...}
}

...

If null is returned, there is no routing result, therefore the next logic component in the queue will be handled. If a RoutingResult is returned, execution within the handler queue is stopped and the routing result is handled. Because the form logicProvidercomponent formlogicProvidercomponent class is the action class of the logic component, the form logicProviderComponentDefinition formlogicProviderComponentDefinition object will register the form logic component. This definition is added to the bundle Activator of a plugin.

...

When a form logic (provider) component (definition) is added to the XperienCentral framework (by deploying a plugin), a form logicComponentDefinition object will be registered. In other words, the form logicComponentDefinition object is the entity reference of the form logic component. The method getform logicProviderComponentgetformlogicProviderComponent() returns the form logic provider component of this entity.

...

The Interactive Forms component uses these subinterfaces according to the form logicProviderType formlogicProviderType that is assigned to the form logicProviderComponentDefinition formlogicProviderComponentDefinition in the activator class. Registering a logic component in the bundle Activator is similar for all form logic component types. The following code sample shows how to define a fragment validator:

...

Code Block
themeEclipse
private form logicProviderComponentDefinitionformlogicProviderComponentDefinition getBankAccountValidatorDefinition() {  form formlogicProviderComponentDefinitionImpl logicProviderComponentDefinitionImpl def = new form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl(false, form logicProviderComponentDefinitionformlogicProviderComponentDefinition.		FORM_LOGIC_PROVIDER_TYPE_FRAGMENTVALIDAT OR, pluginConstants.BANKACCOUNT_VALIDATOR_IDENTIFIER);

	def.setId(pluginConstants.BANKACCOUNT_VALIDATOR_COMPONENT_ID);
	def.setName(pluginConstants.BANKACCOUNT_VALIDATOR_COMPONENT_NAME);
	def.setDescription(pluginConstants.BANKACCOUNT_VALIDATOR_COMPONENT_DESCR);
	def.setJsFilename("bankaccount_validator.js");
	def.setTypeId(form logicProviderComponentTypeformlogicProviderComponentType.class.getName());
	def.setImplementationClassName(Simpleform logicComponent.class.getName());
	def.setProperties(new Hashtable<String, String>());
	def.addRequiredParameter(ParameterDefinition.PARAMETER_TYPE_FORMFRAGMENT_IDENTIFIER, nl.gx.forms.wmpformapi.pluginConstants.VALIDATOR_FRAGMENT_PARAMETER, nl.gx.forms.wmpformapi.pluginConstants.VALIDATOR_FRAGMENT_PARAMETER);
	def.setAllowedToRunClientside(true);
	def.addLanguageLabelMapping("INVALID_BANKACCOUNT", "invalid_bankaccount");
	def.setTitleLanguageLabel("wmpform logicprovidersnlwmpformlogicProvidersnl.validator.bankaccountvalidator.title");

return def;
}

...

The constructor of the component definition requires a form logicProviderComponentDefinition formlogicProviderComponentDefinition type as a (second) parameter. The form logicProviderComponentDefinition formlogicProviderComponentDefinition defines four types:

  • FORM_LOGIC_PROVIDER_TYPE_FRAGMENTVALIDATOR
  • FORM_LOGIC_PROVIDER_TYPE_FORMVALIDATOR
  • FORM_LOGIC_PROVIDER_TYPE_ROUTER
  • FORM_LOGIC_PROVIDER_TYPE_HANDLER

...

The implementation class of this component is the Simpleform logicComponent class. This class implements the form logicProviderComponent formlogicProviderComponent class and has been used as a base or dummy form logic provider component. It is possible to use such a (empty) class in your plugin as the implementation class for a form logic provider that has only a JavaScript implementation. A dummy class should resemble the following:

...

Code Block
themeEclipse
package nl.gx.forms.yourform logicprovidertypeyourformlogicProvidertype.impl;

import nl.gx.forms.wmpformapi.plugin.form logicprovidertype.form logicProviderComponentformlogicProvidertype.formlogicProviderComponent;
import nl.gx.XperienCentral.plugin.foundation.ComponentBase;

public class Simpleform logicComponent extends ComponentBase implements form logicProviderComponentformlogicProviderComponent {
}



Note

This class doesn't implement the form logicProviderService formlogicProviderService interface. If no Java logic action (for example, validation action) is required, the form logicProviderService formlogicProviderService doesn't have to be implemented.

...

The second parameter refers to the name/identifier of this parameter. This identifier can be used as a reference in the run() method of your form logicProviderComponent formlogicProviderComponent class. In Form Validator the retrieval parameters values are described. The third parameter refers to the language label that will be used in the user interface. (It should be present in the language_labels_xx.properties file.) For a fragment validator, one specific parameter has to be defined. It should be a required parameter of the PARAMETER_TYPE_FORMFRAGMENT_IDENTIFIER type. For example:

...

Creating a simple (that is, JavaScript only) fragment validator definition is fairly straightforward. First, add a componentDefinition to your bundle Activator. Next, implement a JavaScript validator function. Finally, implement a dummy form logicProviderComponent formlogicProviderComponent class and, after deploying the plugin, the validator is ready to use.

...

In the code example above, the validateFormFragment() method checks to see whether the precondition for the fragment is met. If so, it retrieves the validators that are assigned to the form fragment. The executeform logicComponent() method that is called for a set of validators will retrieve and execute the validation action. This action could be either based on JavaScript or Java code. First, the JavaScript logic will be retrieved from the form logicComponentDefinition. If no JavaScript is defined, the form logicProviderComponent formlogicProviderComponent object is retrieved and the run() method will be called. However, this is only done when the form logicProviderComponent formlogicProviderComponent is an instance of the form logicProviderService formlogicProviderService, therefore be sure that custom-defined form logicProviderComponent formlogicProviderComponent implements the form logicProviderService formlogicProviderService interface.

If neither a JavaScript source nor a Java implementation is available, the FormengineService will log the (severe) message: No implementation found for form logic component. Additionally, a (custom) FormFagment class should (indirectly) implement the BasicFormInputFragment interface if you want to perform server side validation. This interface requires the implementation of the method getDefaultValidators(). This particular method (again) could bring up the question, how can default Fragment validators be assigned to fragments?

...

This identifier is already introduced in the component definition of the validator in the bundle Activator:


Code Block
themeEclipse
form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl def =new form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl(false, form logicProviderComponentDefinitionformlogicProviderComponentDefinition.FORM_LOGIC_PROVIDER_TYPE_FRAGMENTVALIDATOR,pluginConstants.HELLOWORLD_VALIDATOR_IDENTIFIER);

...

To include a Form Validator in your plugin start with adding the definition type FORM_LOGIC_PROVIDER_TYPE_FORMVALIDATOR in your bundle Activator. For example:


Code Block
themeEclipse
form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl def =new form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl(false, form logicProviderComponentDefinitionformlogicProviderComponentDefinition.FORM_LOGIC_PROVIDER_TYPE_FORMVALIDATOR,pluginConstants.HELLOWORLD_MYFORMVALIDATOR_IDENTIFIER);
  
def.setId(pluginConstants.DATEDAYRANGE_VALIDATOR_COMPONENT_ID);
def.setName(pluginConstants.DATEDAYRANGE_VALIDATOR_COMPONENT_ID);
def.setDescription(pluginConstants.DATEDAYRANGE_VALIDATOR_COMPONENT_DESCRIPTION);
def.setTypeId(form logicProviderComponentTypeformlogicProviderComponentType.class.getName());
def.setImplementationClassName(Simpleform logicComponent.class.getName());
def.setJsFilename("helloworld_formvalidator.js");
def.setProperties(new Hashtable<String,String>());
def.addRequiredParameter(ParameterDefinition.PARAMETER_TYPE_FORMFRAGMENT_IDENTIFIER "anyfragment","helloworldformvalidator.anyfragment");
def.addOptionalParameter(ParameterDefinition.PARAMETER_TYPE_STRING,"anyinteger","helloworldformvalidator.anyinteger");
def.setAllowedToRunClientside(false);        
def.addLanguageLabelMapping("ILLEGAL_VALUE","helloworldformvalidator.illegal_value");
def.addLanguageLabelMapping("VALUE_TO_BIG","helloworldformvalidator.fragment_value_max_exceeded");        
def.setTitleLanguageLabel("helloworldformvalidator.title");

...

The Form Logic components discussed so far have been limited to JavaScript implementations of the action logic. In this part the focus is on a Java implementation, more specifically a Java implementation of a Form Handler. Defining the form handler starts with a registration via the Activator class of your plugin. This class should register  a form logicProviderComponentDefinition formlogicProviderComponentDefinition object of the Handler Type (FORM_LOGIC_PROVIDER_TYPE_HANDLER). For example:


Code Block
themeEclipse
form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl def = new form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl(false,form logicProviderComponentDefinitionformlogicProviderComponentDefinition.FORM_LOGIC_PROVIDER_TYPE_HANDLER,"YOURIDENTIFIERHERE");

	def.setTypeId(form logicProviderComponentTypeformlogicProviderComponentType.class.getName());
	def.setImplementationClassName(YOURHANDLERCLASS.class.getName());
	def.addLanguageLabelMapping(YOURHANDLERCLASS.ERROR_SENDEMAIL_FAILED,"error_sendemail_failed");
	def.addLanguageLabelMapping(YOURHANDLERCLASS.MESSAGE_SENDEMAIL_OK,"message_sendemail_ok");
	def.setTitleLanguageLabel("helloworld.handler.YOURHANDLERCLASS.title");

...

Code Block
themeEclipse
def.addRequiredParameter(
	ParameterDefinition.PARAMETER_TYPE_STRING,      //Type parameter
    YOURCONSTANTSCLASS.PARAM_URL,                   //Name
	"form logic.handler.addtosessionhandler.url");   // Titel of interface

def.setTypeId(form logicProviderComponentTypeformlogicProviderComponentType.class.getName());
def.setImplementationClassName(YOURHANDLERCLASS.class.getName());
def.addLanguageLabelMapping(YOURHANDLERCLASS.ERROR_SENDEMAIL_FAILED,"error_sendemail_failed");
def.addLanguageLabelMapping(YOURHANDLERCLASS.MESSAGE_SENDEMAIL_OK,"message_sendemail_ok");
def.setTitleLanguageLabel("helloworld.handler.YOURHANDLERCLASS.title");

...

Code Block
themeEclipse
private form logicProviderComponentDefinitionformlogicProviderComponentDefinition getGoToPageRouterDefinition() {
	Class myClass = GoToPageRouter.class;  form logicProviderComponentDefinitionImpl formlogicProviderComponentDefinitionImpl def = new form logicProviderComponentDefinitionImplformlogicProviderComponentDefinitionImpl(false, form logicProviderComponentDefinitionformlogicProviderComponentDefinition.FORM_LOGIC_PROVIDER_TYPE_ROUTER, "GoToPage");

	def.setId(myClass.getName());
	def.setName(myClass.getName());
	def.setDescription(myClass.getName());
	def.setTypeId(form logicProviderComponentTypeformlogicProviderComponentType.class.getName());
	def.setImplementationClassName(myClass.getName());
	def.setProperties(new Hashtable<String, String>());
	def.addRequiredParameter(ParameterDefinition.PARAMETER_TYPE_PAGE, GoToPageRouter.PARAM_PAGE, "page");
	def.setTitleLanguageLabel("wmpform logic.router.goto_page_router.title");
    return def;
    }

...