Form Inheritance

Overview

Form inheritance is used to extend a form's functions and UI with those of another form (the super form). This will give the original form all the methods/variables/elements/properties/parts of the form that it extends.

The inheritance is not limited to 1 level, for example there is a form a, form b and form c, form b is extended with a and c with b. The result is that form c will then have all the methods/variables/elements/properties/parts of form a, b and c.

When using form inheritance, the properties and methods can still be overwritten in the sub forms. This is not the case for the datasource, the datasource can not be changed from one table to another, it can be changed from empty to a table.

Get Started

Let's consider the following main forms:

  • Form base_code: Here are all the functions like 'new record', 'delete record' and all buttons found in base form. On this form there are no parts, it is strictly code. This form will have no datasource.

  • Form base: Here are buttons for 'home', 'settings', 'employees', 'save', 'cancel' . There could be more than one, so there can be multiple designs. This form will inherit the base_code form and uses all it's functions. This form will have no datasource.

Sub forms, which extend base form and will inherit the base form (because the functions and buttons are already inherited only the datasource and fields have to be added) :

  • Form home

  • Form settings

  • Form employees

  • Form new_employee

The parent form (super form) can be set by selecting its form name in the subform's extendsForm property.

Override a form property

Inherited form properties can be overriden in the subform's properties.

Override a form event binding

Inherited form event bindings can be overriden in the subform's scripting editor. This can also be completely removed from the subform.

Override a component property

Inherited component's properties can be overriden in the subform's properties tab.

Override a component event binding

Inherited component's event binding can be overriden in the subform's scripting editor. This can also be completely removed from the subform.

Adding a component

When a component is added to a superform, it will also appear in all forms that extend the superform.

Deleting a component

When a component is deleted from a superform, it will also be removed from all forms that extend the superform.

Updating the base form UI

All changes made to the base form UI will be propagated to child forms unless overridden.

Inherited Business Logic

Overriding a method

A sub form will inherit all the methods of the super form. These methods can be overwritten. When this happens, Servoy will generate a method with a call to it's super in it. Inherited methods can be overriden in the subform's scripting editor. In order to override a method, you can right-click the method in the solex and select Override method from the pop-up menu.

Example:

  • on base form:

/**
 * Check if this form can be hidden, return false if this is not allowed.
 *
 * @param {JSEvent} event the event that triggered the action
 *
 * @return {Boolean}
 *
 * @properties={typeid:24,uuid:"FD8D9775-6F4D-42ED-8ED0-ECD4A6D5C365"}
 */
function onBeforeHide(event) {
	// TODO Auto-generated method stub
	databaseManager.revertEditedRecords();
	return true
}

In the generated method there will be _super.onBeforeHide(event) this will call the original method on the super form. This can be removed if the super code doesn't need to be called or code can be inserted before of after the call, if it is inserted after the super call don't forget to move the return.

  • on new_employee form:

Sample of code before:

/**
 * @param {JSEvent} event
 *
 * @return {Boolean}
 * @override
 *
 * @properties={typeid:24,uuid:"06BD3620-26F3-4F46-ABD4-84D200C86296"}
 */
function onBeforeHide(event) {
	elements.error.visible = false;
	return _super.onBeforeHide(event);
}

Sample of code after:

/**
 * @param {JSEvent} event
 *
 * @return {Boolean}
 * @override
 *
 * @properties={typeid:24,uuid:"06BD3620-26F3-4F46-ABD4-84D200C86296"}
 */
function onBeforeHide(event) {
	_super.onBeforeHide(event);
	elements.error.visible = false;
	return;
}

Sample of removed super code:

/**
 * @param {JSEvent} event
 *
 * @return {Boolean}
 * @override
 *
 * @properties={typeid:24,uuid:"06BD3620-26F3-4F46-ABD4-84D200C86296"}
 */
function onBeforeHide(event) {
	elements.error.visible = false;
	return true;
}

Invoking the "super" form

The inherited form can be invoked in child forms (subforms).

Exemple:

  • on new_employee form:

/**
 * @properties={typeid:24,uuid:"4A5E6308-A50F-400B-AC9A-EF4EBE4E1F7F"}
 * @override
 */
function newRecord()
{
	_super.newRecord();	// this will call the original method on the super form
	foundset.hiredate = new Date();	
}

Encapsulation Modifiers

Methods that are defined to be private, will not be available for the subforms. By creation of a method there is a choice to make it private, public or protected. If a method is already created it can be done by adding '@protected', '@private' to the docs.

  • Public : public methods will be available because they are available everywhere

  • Private : private methods will not be available for any other forms, not even the subforms

  • Protected : protected methods will be available for the subform but not for other forms

Abstract Forms

An Abstract Form is a Form that does not implement any Form Parts and as such can not be shown to the user, but can contain business logic and can act as a Super Form for Child Forms.

Example:

base_code form

/**
 * @properties={typeid:24,uuid:"3317FB54-008E-4B52-AF8C-03498081B173"}
 */
function newRecord()
{
	var newRec = foundset.getRecord(foundset.newRecord())
	foundset.selectRecord(newRec)
}

/**
 * TODO generated, please specify type and doc for the params
 * @param {JSRecord} record
 *
 * @properties={typeid:24,uuid:"023612B8-4711-4059-BA48-84F3C1BD562D"}
 */
function deleteRecord(record)
{
	foundset.deleteRecord(record)
}

/**
 * @properties={typeid:24,uuid:"4A5BF651-00B6-4EFE-AD67-90EBB70B6E49"}
 */
function SaveButton()
{
	databaseManager.saveData()
}

/**
 * @properties={typeid:24,uuid:"8026B0DF-6276-4BC9-A9AB-E5F62CDA459F"}
 */
function CancelButton()
{
	databaseManager.revertEditedRecords(foundset);
}

/**
 * Fired when the button is clicked.
 *
 * @param {JSEvent} event
 *
 * @properties={typeid:24,uuid:"1D4F5ACD-32C3-452D-864F-4651D5E0242C"}
 */
function onActionHome(event) {
	// TODO Auto-generated method stub
//var FormName = controller.getName();
//if (FormName != '')
application.showForm('home_simple');
}


/**
 * TODO generated, please specify type and doc for the params
 * @param event
 *
 * @properties={typeid:24,uuid:"177F881B-5922-481F-BCA2-5AB832DA8FE9"}
 */
function onActionSettings(event) {
	// TODO Auto-generated method stub
//var FormName = controller.getName();
//if (FormName != '')
application.showForm('settings_simple');
}

/**
 * TODO generated, please specify type and doc for the params
 * @param event
 *
 * @properties={typeid:24,uuid:"9AC1F0B5-E0FC-403A-A240-670BF8C49E91"}
 */
function onActionEmployees(event) {
	// TODO Auto-generated method stub
//var FormName = controller.getName();
//if (FormName != '')
application.showForm('employees_simple');
}

Last updated