|
|
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. )
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:
-
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);
-
The standard Database call for insertion:
Pointer created= db.insert(type, data);
-
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);
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)
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)
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 |
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 |
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>
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)
|