We have seen how to organize the content in a form, using structural components such as header, group, and notebook. Now we can take a closer look at the semantic components, fields and buttons, and what we can do with them.

View fields have a few attributes available for them. Most of them have values taken from their definition in the model, but these can be overridden in the view.

Attributes that are generic, and do not depend on the field type, are:

Attributes specific to some field types are:

Each field type is displayed in the form with the appropriate default widget. But additional alternative widgets are available to be used.

For text fields, we have the following widgets:

For numeric fields, we have the following widgets:

For relational and selection fields, we have these additional widgets:

When designing the form structure, we included a top-right area to contain smart buttons.  Let's now add a button inside it.

For our app, we will have a button displaying the total number of to-dos for the owner of the current to-do, and clicking on it would navigate to the list of those items.

First we need to add the corresponding computed field to models/todo_model.py. Add to the TodoTask class with the following:

def compute_user_todo_count(self):
    for task in self:
        task.user_todo_count = task.search_count(
            [('user_id', '=', task.user_id.id)]) 

user_todo_count = fields.Integer(
    'User To-Do Count',
    compute='compute_user_todo_count')

Next we add the button box and the button inside it. Right after the end of the oe_title DIV, replace the buttons box placeholder we added before, with the following:

<div name="buttons" class="oe_right oe_button_box">
  <button class="oe_stat_button"
    type="action" icon="fa-tasks"
    name="%(action_todo_task_button)d"
    context="{'default_user_id': user_id}"
    help="All to-dos for this user" >
    <field string="To-Dos" name="user_todo_count"
      widget="statinfo"/>
  </button>
</div>

This button displays the total number of To-do Tasks for the person responsible for this to-do task, computed by the user_todo_count field.

These are the attributes that we can use when adding smart buttons:

The button element itself is a container, with fields displaying statistics. Those are regular fields using the widget statinfo. The field should be a computed field defined in the underlying model. Other than fields, inside a button we can also use static text, such as:

<div>User's To-dos</div>

When clicking on the button, we want to see a list with only the Tasks for the current responsible user. That will be done by the action_todo_task_button action, not yet implemented. But it needs to know the current responsible user, to be able to perform the filter. For that we use the button's context attribute to store that value.

The Action used must to be defined before the Form, so we should add it at the top of the XML file:

<act_window id="action_todo_task_button"
  name="To-Do Tasks"
  res_model="todo.task"
  view_mode="tree,form,calendar,graph,pivot"
  domain="[('user_id','=',default_user_id)]" />

Notice how we use the default_user_id context key for the domain filter. This particular key will also set the default value on the user_id field when creating new Tasks after following the button link.