[{TableOfContents}]

!!!Introduction

Makumba can produce four types of forms: new, add, edit and generic forms. In addition to the forms, it is also possible to delete records. 

All forms have a number of common features:
* they can include a number of <mak:input> tags, which will render controls to manipulate data.
* they accept an attribute to specify the action page, i.e. the page that will be loaded after the form is submitted, just as in normal HTML forms
* they accept an attribute to specify the message to be displayed upon successful completion of the action
* the form method (%%code get%% or &&code post%%) can be set via an attribute, just as in normal HTML forms
* the form name can be set via an attribute
* forms can have handler methods to do post-processing, validation, e-mail sending, ... The handler methods are part of the [Makumba Business Logics|JavaBusinessLogic].

!!Non-generic (type specific) forms
[New|NewFormTag], [edit|EditFormTag] and [add|AddFormTag] forms are type specific. Their fields must be named after the fields in the respective type (and related fields).

For other purposes, a generic [<mak:form>|FormTag] tag is available.

!!Multiple forms
Multiple forms are a powerful feature of Makumba which makes it possible to:
* embed several forms in one, so as to have only one submit button
* create or edit multiple data sets at once, in combination with Makumba lists

!!!Basic form operations

The following code examples are all based on the [company data model|DataModelHowto] described earlier in this section. We are mainly using the %%code company.Employee%% type:

__company.Employee (company/Employee.mdd)__
[{Code

name = char[200]
surname = char[200]
...
projects = set
projects->project = ptr company.Project
projects->timePercentage = int ;percentage assigned
}]



!!Entering new data: newForm
In order to create new data of a specific type ([Makumba Data Definition|DataDefinitions]). The fields in the form must be defined in the data definition specified, otherwise a [NoSuchFieldException] will be thrown.

To make a new record of the type %%code Employee%%, one could do a form as follows:

[{Code

<mak:newForm type="company.Employee" action="employeeList.jsp" method="post">
    <mak:input name="name"/>
    <mak:input name="surname"/>
    <input type="submit">
</mak:newForm>
}]

!!Editing existing data: editForm

The [<mak:editForm>|EditFormTag] allows to edit existing records in the database. To allow editing, the record has to be first fetched by a [<mak:object>|ObjectTag] or [<mak:list>|ListTag].

[{Code

<mak:object from="company.Employee e" where="e=$employee">
    <mak:editForm object="e" action="employeeList.jsp" method="post">
        <mak:input name="name"/>
        <mak:input name="surname"/>
    </mak:editForm>
</mak:object>
}]

Note that in this example, we assume that the where-condition in the [<mak:object>|ObjectTag] is constructed by comparing the [Pointer] to a parameter passed in the URL, e.g. in a page %%code employeeEdit.jsp?employee=hhiwx47%%.

When we have fetched the record to edit, we have to specify that we want to edit that very same object in the <mak:editForm> by using the attribute %%code object%%.

!!Adding data to sets: addForm

The [<mak:addForm>|AddFormTag] allows to add a new record to a so-called [internal set|DataDefinitions#StructuralRelationalTypes], e.g. the %%code projects%% set from the example [data model|DataModelHowto]:

If we want to add a new %%code projects%% record to an existing employee record, we have to first, similar to the [<mak:editForm>|EditFormtTag], fetch the employee record by a <mak:object> or <mak:list>.

[{Code

<mak:object from="company.Employee e" where="e=$employee">
    <mak:addForm object="e" field="projects" action="employeeList.jsp" method="post">
        <mak:input name="project"/>
        <mak:input name="timePercentage"/>
        <input type="submit" value="Add project"/>
    </mak:addForm>
</mak:object>
}]

Note that in this example, we assume that the where-condition in the <mak:object> is constructed by comparing the Pointer to a parameter passed in the URL, e.g. in a page employeeEdit.jsp?employee=hhiwx47.

When we have fetched the record, we have to specify that we want to add a sub-record to that very same object in the <mak:addForm> by using the attribute %%code object%%, and specify which set to add to, using the %%code field%% attribute.
!!Deleting data: delete and deleteLink
Deleting requires a similar approach as editing
* first, the object that is supposed to be deleted has to be fetched via a [<mak:object|ObjectTag] or [<mak:list>|ListTag] tag.
* then, in the delete tag, you have to specify that object.

Let's say we want to delete employees from the data base that are ready for retirement (see the [MDD functions example|MDDFunctionsHowto] for the function definition)

[{Code

<mak:list from="company.employee e" where="e.shallRetire()">
  <mak:value expr="e.nameSurname()"/> 
  <mak:delete object="e" action="employeeList.jsp" >delete from the database</mak:delete> <br/>
</mak:list>  
}]

will render us a page with all the names of the employees fulfilling the retirement criterion, printing their name and a __link__ with the text "delete from the database".

Note that data can be deleted by two different input controls, a link or a form button. 

[{Box type='warning'

Deleting via a link is the legacy approach in Makumba, and has the major disadvantage that the in the resulting URL, the parameters such as the object deleted, are visible. Further, using a link is not a familiar concept in other user interfaces, where mostly buttons are used.
}]

If we want to use a form rather than a button, we need to specify this explicitely:

[{Code

<mak:list from="company.employee e" where="e.shallRetire()">
  <mak:value expr="e.nameSurname()"/> 
  <mak:delete widget="form" object="e" action="employeeList.jsp" >delete from the database</mak:delete> <br/>
</mak:list>  
}]

[{Box

In the future, the default for __widget__ will change from "link" to "form".
}]

[{Box

<mak:deleteLink ...> is a legacy notation that is equivalent to <mak:delete widget="link" ...>
}]
!!Generic forms: form

Sometimes, you want the user to input information into a form, but you don't necessarily want to store it in your database, but maybe do some other action, such as storing a user-dependent setting in your website.

!Changing the website skin

Consider we want to store the skin to be used for rendering the pages. You can achieve this by using a generic [<mak:form>|FormTag].

So, let's assume your website has a set of different skins to chose from, called "green", "geeky" and "funky", and you want a non-logged in the user to change that for his session only.

[{Code

<mak:form action="" handler="changeSkin">
  Skin: <mak:input tydataType="set int{1='green', 2='geeky', 3='funky'}" value="$currentSkin" />
  <input type="submit" value="change!"/>
</mak:form>
}]

when the form is submitted, a [handler method|JavaBusinessLogic#Custom handler methods] "changeSkin" will be called, in which you can alter the value of the session attribute of ''currentSkin'' to the newly chosen one.

!E-Mail sending
Another example when you might want to use generic forms is when we want to send an e-mail, e.g. when we want to allow users to send referral mails to their friends, which would contain a link to the page the user is currently looking at.

!!Combining forms: multiple forms
Makumba allows to combine several forms into each other, enabling the user to edit several objects at the same time. For example, one can edit the assignment of several employees to projects at the same time. More details can be found in the [multiple forms documentation|MultipleListsAndFormsHowto]

!!!Form submission: form actions, validation and business logics
After the form is submitted, a series of steps are executed:
* The data submitted in the form is validated, i.e. the values for each field are checked against the implicit and explicitly defined [validation rules|ValidationRules]. Possible errors in this stage will collected.
* If the validation is successful, the [business Logics handler method|JavaBusinessLogic] for the form submitted will be executed. If the form is a [multiple form|MultipleListsAndFormsHowto], a business logics handler method will be executed for each of them. In the handler method, the application programmer might throw a [validation error|InvalidValueException] if some data fails to validate, or a [logic error|LogicException], e.g. if the user is not allowed to do a certain operation.
* Depending on the two previous steps, the flow of execution will be different
** If no error was thrown:
*** Makumba will do the needed database operations, i.e. create, update or delete the records.
*** The result page, defined in the form with the %%code action%% attribute, will be loaded, and the success message defined in the form with the %%code message%% attribute will be displayed by the [<mak:response>|ResponseTag] tag. If not [<mak:response>|ResponseTag] tag is defined, no message will be shown to the user.
** If an error was thrown, no database operations will be carried out, and:
*** If the application programmer specified that the form page should be reloaded, either by having the [default |MakumbaConfiguration#ControllerBehaviorControllerConfig] or form-specific %%code reloadFormOnError%% attribute set to true, instead of the specified action page, the original page will be loaded, and the errors will be presented there. If the application programmer further specified that the form should be annotated, again via a default or form specific setting, the error messages will be displayed next to the input control holding the invalid values.
*** If the form shall not be reloaded, the result (action) page will be shown, and the errors will be displayed by the [<mak:response>|ResponseTag] tag.
!!!Form annotation
Form validation errors are either reported in the Makumba response which would be displayed on the form action page, or can for improved usability be annotated in the form itself. In the latter case, on a form validation error, the form page itself would be displayed again, and errors are displayed next to the inputs that failed validation.

An example can be seen below:
age 	  invalid integer: 1r
weight 	  invalid real: 24b

The annotation message will be put inside a <span class="formAnnotation">; this CSS-class can be used to add custom formatting to the message.

Reloading the form page on errors can be triggered by the attribute reloadFormOnError, the location of the annotation message by the attribute annotation.

Additionally, form validation can be done also on the client-side, i.e. in the browser. Client-side validation can be either live, i.e. on entering data in an input, or before form submission; this is controlled by the attribute clientSideValidation.


%%(display:none;)[Category Usage]%%
