Table of Contents
- Introduction
- Non-generic (type specific) forms
- Multiple forms
- Basic form operations
- Entering new data: newForm
- Editing existing data: editForm
- Adding data to sets: addForm
- Deleting data: delete and deleteLink
- Generic forms: form
- Changing the website skin
- E-Mail sending
- Displaying newly created data
- Combining forms: multiple forms
- Form submission: form actions, validation and business logics
- Form annotation
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 (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.
Non-generic (type specific) forms#
New, edit and add 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> 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 described earlier in this section. We are mainly using the company.Employee type:
company.Employee (company/Employee.mdd)
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). The fields in the form must be defined in the data definition specified, otherwise a org.makumba.NoSuchFieldException will be thrown.To make a new record of the type Employee, one could do a form as follows:
<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> allows to edit existing records in the database. To allow editing, the record has to be first fetched by a <mak:object> or <mak:list>.
<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> is constructed by comparing the org.makumba.Pointer to a parameter passed in the URL, e.g. in a page 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 object.
Adding data to sets: addForm#
The <mak:addForm> allows to add a new record to a so-called internal set, e.g. the projects set from the example data model:
If we want to add a new projects record to an existing employee record, we have to first, similar to the <mak:editForm>, fetch the employee record by a <mak:object> or <mak:list>.
<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 object, and specify which set to add to, using the 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 or <mak:list> 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 for the function definition)
<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.
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 button rather than a link, we need to specify this explicitely:
<mak:list from="company.employee e" where="e.shallRetire()"> <mak:value expr="e.nameSurname()"/> <mak:delete widget="button" object="e" action="employeeList.jsp" >delete from the database</mak:delete> <br/> </mak:list>
In the future, the default for widget will change from "link" to "button".
<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>.
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.
<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 "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.Displaying newly created data#
If you want to display the newly created data on a subsequent page, i.e. the form action page, you have to use the name="..." attribute of <mak:newForm>, e.g.:<mak:newForm type="company.Employee" action="employeeView.jsp" method="post" name="newEmployee"> <mak:input name="name"/> <mak:input name="surname"/> <input type="submit"> </mak:newForm>
Then, the newly created object is available in the action page as an attribute with the name "newEmployee". You can use this attribute in the <mak:object> to display the details:
<mak:object from="company.Employee e" where="e=$newEmployee"> Name: <mak:value expr="e.name"/> <br/> Surname: <mak:value expr="e.surname"/> <br/> </mak:object>
You can also use the attribute in JSP Expression Language as ${newEmployee}
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 documentationForm 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. Possible errors in this stage will collected.
- If the validation is successful, the business Logics handler method for the form submitted will be executed. If the form is a multiple form, a business logics handler method will be executed for each of them. In the handler method, the application programmer might throw a org.makumba.InvalidValueException if some data fails to validate, or a org.makumba.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 action attribute, will be loaded, and the success message defined in the form with the message attribute will be displayed by the <mak:response> tag. If not <mak:response> 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 or form-specific 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> tag.
- If no error was thrown:
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.