Makumba Specification

[Data Definitions]  [Query Languages]  [JSP tag library: Intro | Listing | Forms] [Business Logics]  [Summary]

JSP taglib - Forms

Makumba can produce four types of forms: new, add, edit and generic forms.

All forms have a number of common features: They can include <mak:input > tags. They all can have "action", "method", "handler", "name" and "message" arguments.

Handler methods (if they exist) are executed by the makumba controller, when the form is submitted to another makumba page.

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).

If there is a business logic class, the engine will look (once after each page compilation) for the corresponding handler method. The handler methods are executed before the default action and may prevent the action from being executed by throwing an exception. Some forms also have an after-action handler method.

If the handler class exists but no handler method can be found, an error is thrown (the site is not allowed to do the operation, e.g. StudentHandler will never have a on_newLibraryBook() method). If the handler class wishes to allow the action, it can define an empty handler method.

Multiple forms
- addForms can add to the subsets of object produced by the enclosing newForm.
- any number of levels of form inclusion is possible but only the outermost form can have an action, onSubmit, and method and other attributes specific to HTML forms.
- all form actions take place in a single transaction, which is rolled back by the controller filter if there is an error.
- after_ methods are not executed in correct order (bug 689)

<mak:form action="blabla">
<%-- the topmost form, will result in a HTML form, may or may not have logic,
or it can be a specialized form (new, edit, add...)
--%>

<mak:input name="first" /> <%-- the topmost form can have fields of its own --%>

<mak:list .... >
  <mak:addForm object="bla" field="bla" >
<%-- note that there is no action indicated here, it's the action of the
topmost form a normal on_add BL method will be called
--%>
   <mak:input name="second" /><%-- the topmost form can have fields of its own,
even repeated in loops
--%>
...
</mak:addForm>
</mak:list>

<mak:list .... > <%-- there can be more than one loop in a root form -- %>
...
</mak:list>
<input type=submit> <%-- it's easy to add a submit button anywhere --%>
</mak:form>

(Later, new and edit forms that have no body, will build default forms. )

<mak:newForm  ...>.... </mak:newForm>

Makes a form for creating a new object of the indicated type.

Example (personNew.jsp):

<mak:newForm type="general.Person" action="personList.jsp" method="post">
<mak:input name="name"/>
<mak:input name="surname"/>
<input type="submit">
</mak:newForm>

tag parameter description comments
type Makumba type for record creation, or OQL label for subrecord creation Fixed, mandatory.
(handler) the Java class.method that handles the response defaults to on_new+NameOfMakumbaType. Arguments:
(Dictionary newData,  Attributes a, Database db)
action the response page of the form Mandatory if a <mak:action> is absent
method the HTTP method (get or post) Defaults to get
name the name of the created object in the response page Fixed. Defaults to __mak__edited__. If set, it is also used for the name of the html form (<form name="..." ...>)
message the message that is displayed in the response page upon success Fixed. Defaults to "changes done".
target Form-specific html tag attributes The content is copied to the resulting <form...> tag. Careful with (escaping) quotes.
onReset
onSubmit
styleId Generic HTML tag attributes. results in id="..."
styleClass results in class="..."
style The content is copied to the resulting html tags. Careful with (escaping) quotes.
title
onClick
onDblClick
onKeyDown
onKeyUp
onKeyPress
onMouseDown
onMouseUp
onMouseMove
onMouseOut
onMouseOver

At form response, makumba (controller) invokes the following methods:

  1. By defining on_new*, the handler class gets the opportunity to validate/change the data. If the data is not correct, the handler can throw an exception to prevent insertion in database.

    handler.on_newTypeName(data, attr, db);
  2. The standard Database call for insertion:

    Pointer created= db.insert(type, data);
  3. By defining after_new*, the handler class gets the opportunity to do supplementary operations with the inserted record.

    handler.after_newTypeName(created, data, attr, db);

argument Java type comments
data java.util.Dictionary The new record to create. It is read from the HTTP query string by interpreting the form.
attr org.makumba.Attributes Other attributes in the page (sent as HTTP arguments or present in the HTTP session).
db org.makumba.Database The database where the record will be inserted
created org.makumba.Pointer The pointer to the created record. Only for after_new

If the handler class is present but both handler methods are missing (on_new and after_new), the action is not allowed.

At response the following calls are executed (in this order):

PersonLogic handler_obj; // see handler discovery
handler_obj.checkAttributes(attr, db);
handler_obj.on_newGeneralPerson(data, attr, db);
Pointer created= db.insert("general.Person", data);
handler_obj.after_newGeneralPerson(created, data, attr, db);

<mak:addForm  ...>.... </mak:addForm>

Makes a form for creating a sub-object of the mandatory enclosing <mak:object> (e.g. a language of a student, an address for a person).

Example:

<mak:object from="best.Student s" where="s=$student">
<mak:addForm object="s" field="languages"
action="studentView.jsp" method="post">
<mak:value expr="s.name"/>
<mak:input name="level"/>
<mak:input name="comments"/>
</mak:addForm>
</mak:object>

tag parameter description comments
object The label of the object whose sub-object will be created Fixed, mandatory
field The field name that denotes the sub-object. Fixed, mandatory.
(handler) the Java class.method that handles the response defaults to on_add+MakumbaType+fieldname. Arguments: (Pointer baseObject, Dictionary newData,  Attributes a, Database db)
action see newForm
method
name
message
target Form-specific html tag attributes, see newForm
onReset
onSubmit
styleId Generic html tag attributes, see newForm
styleClass
style
title
onClick
onDblClick
onKeyDown
onKeyUp
onKeyPress
onMouseDown
onMouseUp
onMouseMove
onMouseOut
onMouseOver

This will call the handler methods: (the argument names are adapted to the example. Note the changed pointer argument in the methods.)

on_addBestStudentLang(Pointer student, Dictionary languageData, Attributes pageParams, Database db)
after_addBestStudentLang(Pointer address, Dictionary languageData, Attributes pageParams, Database db)

<mak:editForm  ...>.... </mak:editForm>

Makes a form for editing the object indicated by any of the labels of the mandatory enclosing <mak:object> or <mak:list>. Also linked objects can be edited through the same form.

Example:

<mak:object from="best.Student s, s.person p" where="s=$student">
<mak:editForm object="s" action="studentView.jsp" method="post">
<mak:input name="person.name"/>
<mak:input name="person.surname"/>
<mak:input name="graduated"/>
</mak:editForm>
</mak:object>

tag parameter description comments
object The label of the OQL object to edit Fixed, mandatory.
(handler) the Java class.method that handles the response defaults to on_edit+MakumbaTypeOfEditedObject. Arguments: (Pointer object, Dictionary changedFields, Attributes a, Database db)
action see newForm
method
name
message
target Form-specific html tag attributes, see newForm
onReset
onSubmit
styleId Generic html tag attributes, see newForm
styleClass
style
title
onClick
onDblClick
onKeyDown
onKeyUp
onKeyPress
onMouseDown
onMouseUp
onMouseMove
onMouseOut
onMouseOver

The response will call the handler method: (the argument names are adapted to the example)

on_editBestStudent(Pointer student, Dictionary fieldsToChange, Attributes pageParams, Database db)

<mak:form  ...>....</mak:form>

Creates a generic form, that may call a handler method in response. It allows the JSP author to make any kind of form. They are suitable for more complex operations than new, add, edit.

Example:

<mak:object from="best.Student s" where="s=$student">
<mak:form handler="doSomething" action="studentView.jsp" method="post">
<mak:input name="xxx" value="s.person.name"/>
<input type=submit>
</mak:form>
</mak:object>

tag parameter description comments
handler the Java method that handles the response Arguments: (Dictionary formFields, Attributes restOfArguments, Database db)
Not mandatory. A form without handler will simply set attributes (as makumba objects) for the next page
action see newForm
method
name
message
target Form-specific html tag attributes, see newForm
onReset
onSubmit
styleId Generic html tag attributes, see newForm
styleClass
style
title
onClick
onDblClick
onKeyDown
onKeyUp
onKeyPress
onMouseDown
onMouseUp
onMouseMove
onMouseOut
onMouseOver

<mak:input... />

An input field to be created, depending on the makumba type of the field. See the example for set/ptr choosers with Makumba.

scripts/makumba-javascript.html

The difference between <mak:input > and normal HTML <input> in a makumba form are:

  • <mak:input> produces objects prepared for setting/comparing makumba fields (e.g. Pointer, Date, Text).
  • the fields produced by <input> will be available as page $attributes but will all be of type String
  • the fields produced by <mak:input> are available separately as a Dictionary to the handler method
<mak:object from="best.Student s, s.person p" where="s=$student">
<mak:editForm object="p" action="studentView.jsp" method="post">
name <mak:input name="name"/>
surname <mak:input name="surname"/>
gender <mak:input name="gender" type="tickbox" />
dob <mak:input name="birthdate" format="yyyy-MM-dd" />
</mak:editForm>
</mak:object>

tag parameter description comments
name
(or field)
Makumba field (from the edited record or via base pointers or sub-record pointers) Fixed, mandatory
nameVar The name of the java variable in which to store the name of the HTML input. In multiple forms,  there may be more HTML inputs generated by one mak:input, so a suffix is added by makumba to the name to generate unique names for each.
Fixed
value OQL expression relative to enclosing query tags or a $attribute computed previously in the page (with <mak:value var=.../> or pageContext.setAttribute(...)), or read by in the previous page by an <mak:input /> Fixed
type HTML INPUT type to be used
  • "hidden" works for all fields
  • for char[] , type can be "text" or "password", default is "text"
  • default type for [set]intEnum, [set]charEnum, ptr and set is "select" (dropdown or scroll list depending on size). Alternative is "tickbox" (checkboxes or radio buttons)
  • date is splitted in 3 inputs, <fieldname>_0 (day), _1 (month), _2 (year), and likewise for time elements
  • for text, default is "textarea"; "file" will create file upload box, and will create supplementary attributes <fieldname>_filename, <fieldname>_contentType and <fieldname>_contentLength that have to be handled separately by the handler method
Fixed
display If "false", it will not show the <input> but it will expect to read it in the next page. This allows the page designer to format the input control manually Rtexpr.
dataType The makumba type of the data (needed if there is no value, no default expression for the value, or no makumba type associated with an attribute) Fixed. Can be char, char[xx], int, date, text, ptr Type, set Type
format Format string, according to java.text.SimpleDateFormat
Can only countain d, M, y, H, m, s formatting chars, and any kind of separators. Ex:
'the day' dd 'of the month' MMMM 'in the year' yyyy.
Default is "dd MMMM yyyy"
Rtexpr. Only for date.
size Size of the input control Rtexpr. Only for char[], int (size of the textbox) and set, ptr (height of the select)
maxLength Max length of a text control Rtexpr. Only for char[] and int. Defaults to makumba width of the char[]
labelSeparator The string that separates the tickbox (radio/check) from the label. Default is " " (space).
The output will be < tick >< labelSeparator >< label >
Rtexpr. Only for type="tickbox".
elementSeparator The string that separates the different options. Default is " " (space).
The output will be < [x] label >< elementSeparator >< [x] label >
Rtexpr. Only for type="tickbox".
(elementSeparatorList) The list of strings that separates the different options. Not active by default. The format is "!sep[1]!sep[2]!...!sep[n]!" where any character (not appearing inside the separators) can be used as delimiter, e.g. '!'.
The output will be
< [x] label >< sep[1] >< [x] label >< sep[2] > ... < [x] label >< sep[n] >< [x] label >< sep[1] > ...
Rtexpr. Only for type="tickbox". Overrides elementSeparator if it exists.
rows, cols Number of textarea rows and columns only for text
default FIXME Rtexpr
empty FIXME Rtexpr
styleId Generic html tag attributes, see newForm
styleClass
style
title
onClick
onDblClick
onKeyDown
onKeyUp
onKeyPress
onMouseDown
onMouseUp
onMouseMove
onMouseOut
onMouseOver

Fields of related records can be reference and edited as well, via pointers. In this (somewhat strange) example, one can edit the name of the capital city of the country of which person is a citizen, through the person edit form :

<mak:input name="person.citizenship.capital.name" />

Restrictions for different field types:

  • fixed fields: cannot be edited
  • relational and index pointer: cannot be edited
  • timestamps (create and modify): cannot be edited
  • subset, subpointer: cannot be edited as a field, only as a separate object
<mak:option....>...</mak:option>
By default, for pointer and set fields, mak:input will show a choser (selector) that includes the title of all possible options, ordered by that title. To change that behavior, the mak:input can include one or more mak:option. Options can be repeated using mak:list, c:foreach, and in general can appear inside any other tag.

Text inside mak:option will become an option title. The value attribute will become the option. All text produced inside the mak:input that is not inside a mak:option must be blank!

If mak:option doesn't have a value indicated, it will produce a nil option. Such nil options will be ignored at form submission.

If an option value appears many times it will only be shown the first time it occurs.

<mak:input name="some" dataType="ptr T">
<mak:option>Please choose:</mak:option>
<mak:list from="T choice" where="someCondition" >
<mak:option value="choice"><mak:value expr="choice.someField" /></mak:option>
</mak:list>
<mak:option> -------- separator----------</mak:option>
<mak:list from="T choice" where="someOtherCondition" >
<mak:option value="choice"> <mak:value expr="choice.someField /></mak:option>
</mak:list>
</mak:input>

tag parameter description comments
value
Value of the option, can be an OQL expression or a $attribute Fixed, if not indicated, nil (null option) is default

<mak:action>....</mak:action>

If the action URI of a form or deleteLink is more complex, possibly including other makumba tags, the action parameter of the form tag can be omitted, and the action URI can be indicated in a mak:action, anywhere inside the form tag.

Example:

<mak:editForm object="ins" method="post">
<mak:action>memberView.jsp?person=<mak:value expr="p"/></mak:action>
...
</mak:editForm>

<mak:deleteLink>...</mak:deleteLink>

Produces a link to the page that will delete the object indicated by any of the labels of the mandatory enclosing <mak:object> or <mak:list>

Example:

<mak:object from="best.Student s, s.languages l"
where="s=$student AND l.lang.name=$langname">
<mak:deleteLink object="l" action="studentView.jsp">
Delete <mak:value expr="l.lang.name"/>
</mak:deleteLink>
</mak:object>

tag parameter description comments
object OQL label of the object to delete Fixed
(handler) the Java class.method that handles the response defaults to on_delete+MakumbaTypeOfEditedObject. Arguments: (Pointer object, Attributes a, Database db)
action see newForm
message
target
name
styleId Generic html tag attributes, see newForm
styleClass
style
title
onClick
onDblClick
onKeyDown
onKeyUp
onKeyPress
onMouseDown
onMouseUp
onMouseMove
onMouseOut
onMouseOver

The response will call the handler method: (the argument names are adapted to the example)

on_deleteBestStudentLang(Pointer lang, Attributes pageParams, Database db)