# Makumba Specification

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

## JSP taglib - Forms

<mak:newForm> <mak:addForm> <mak:editForm> <mak:form> <mak:input> and <mak:option> <mak:action> <mak:deleteLink/> | 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`
1. 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);
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)