Form views

As we have seen in previous chapters, form views can follow a simple layout or a business document layout, similar to a paper document.

We will now see how to design business views and to use the elements and widgets available. Usually this would be done by inheriting the base view. But to make the code simpler, we will instead create a completely new view for to-do tasks that will override the previously defined one.

In fact, the same model can have several views of the same type. When an action asks to open a view type for a model, the one with the lowest priority is picked. Or as an alternative, the action can specify the exact identifier of the view to use. The action we defined at the beginning of this chapter does just that; the view_id tells the action to specifically use the form with ID view_form_todo_task_ui. This is the view we will create next.

Business views

In a business application we can differentiate auxiliary data from main business data. For example, in our app the main data is the to-do tasks, and the tags and stages are auxiliary tables used by it.

These business models can use improved business view layouts for a better user experience. If you recall the to-do task form view added in Chapter 2, Building Your First Odoo Application, it was already following the business view structure.

The corresponding form view should be added after the actions and menu items we added before, and its generic structure is this:

<record id="view_form_todo_task_ui" model="ir.ui.view">
  <field name="name">view_form_todo_task_ui</field>
  <field name="model">todo.task</field>
  <field name="arch" type="xml">
    <form> <header> <!-- Buttons and status widget --> </header>
      <sheet>  <!-- Form content --> </sheet>
      <!-- History and communication: -->
      <div class="oe_chatter">
        <field name="message_follower_ids"
               widget="mail_followers" />
        <field name="message_ids"
               widget="mail_thread" />
      </div> </form>

  </field>
</record>

Business views are composed of three visual areas:

  • A top header
  • A sheet for the content
  • A bottom history and communication section

The history and communication section, with the social network widgets at the lower end is added by inheriting our model from mail.thread (from the mail module), and adding at the end of the form view the elements in the XML sample as previously mentioned. We've also seen this in Chapter 3, Inheritance - Extending Existing Applications.

The header status bar

The status bar on top usually features the business flow pipeline and action buttons.

The action buttons are regular form buttons, and the most common next steps should be highlighted, using class="oe_highlight". In todo_ui/todo_view.xml we can now expand the empty header to add a status bar to it:

<header>
  <field name="stage_state" invisible="True" />
  <button name="do_toggle_done" type="object"
          attrs="{'invisible':
                 [('stage_state','in',['done','cancel'])]}"
          string="Toggle Done" class="oe_highlight" />
  <!-- Add stage statusbar:  ... -->
</header>

Depending on where in the process the current document is, the action buttons available could differ. For example, a Set as Done button doesn't make sense if we are already in the "Done" state.

This can be done using the states attribute, listing the states where the button should be visible, like this: states="draft,open".

For more flexibility we can use the attrs attribute, forming conditions where the button should be made invisible: attrs="{'invisible': [('stage_state','in', ['done','cancel'])].

These visibility features are also available for other view elements, and not only for buttons. We will be exploring that in more detail later in this chapter.

The business flow pipeline

The business flow pipeline is a status-bar widget on a field that represents the point in the flow where the record is. This is usually a State selection field, or a Stage many to one field. Both cases can be found across several Odoo modules.

The Stage is a many to one field using a model where the process steps are defined. Because of this they can be easily configured by end users to fit their specific business process, and are perfect to support kanban boards.

The State is a selection list featuring rather stable major steps in a process, such as New, In Progress, or Done. They are not configurable by end users but on the other hand are easier to use in business logic. States also have special support for views: the state attribute allows for an element to be selectively available to the user depending on the state of the record.

Tip

It is possible to benefit from the best of both worlds, by using stages that are also mapped into states. This was what we did in the previous chapter, by making the State available in to-do task documents through a computed field.

To add a stage pipeline to our form header:

<!-- Add stage statusbar: ... -->
<field name="stage_id" widget="statusbar"
       clickable="True" options="{'fold_field': 'fold'}" />

The clickable attribute enables clicking on the widget, to change the document's stage or state. We may not want this if the progress through process steps should be done only through action buttons.

In the options attribute we can use some specific settings:

  • fold_field, when using stages, is the name of the field that the stage model uses to indicate which stages should be shown folded.
  • statusbar_visible, when using states, lists the states that should be always made visible, to keep hidden the other exception states used for less common cases. Example: statusbar_visible="draft,open,done".

The sheet canvas is the area of the form containing the main form elements. It is designed to look like an actual paper document, and its data records are sometimes referred to as documents.

The document structure in general has these components:

  • Title and subtitle information
  • A smart button area, on the top right
  • Document header fields
  • A notebook with tab pages, with document lines or other details

Title and subtitle

When using the sheet layout, fields outside a <group> block won't have automatic labels displayed. It's up to the developer to control if and where to display the labels.

HTML tags can also be used to make the title shine. For best results, the document title should be in a div with the oe_title class:

<div class="oe_title">
  <label for="name" class="oe_edit_only"/>
  <h1><field name="name"/></h1>
  <h3>
    <span class="oe_read_only">By</span>
    <label for="user_id" class="oe_edit_only"/>
    <field name="user_id" class="oe_inline" />
  </h3>
</div>

Here we can see the use of regular HTML elements such as div, span, h1 and h3.

Labels for fields

Outside <group> sections the field labels are not automatically displayed, but we can display them using the <label> element:

  • The for attribute identify the field to get the label text from
  • The string attribute to override the field's original label text

With the class attribute to we can also use CSS classes to control their presentation. Some useful classes are:

  • oe_edit_only to display only when the form is in edit mode
  • oe_read_only to display only when the form is in read mode

An interesting example is to replace the text with an icon:

<label for="name" string=" " class="fa fa-wrench" />

Odoo bundles the Font Awesome icons, being used here. The available icons can be browsed at http://fontawesome.org.

Smart buttons

The top right area can have an invisible box to place smart buttons. These work like regular buttons but can include statistical information. As an example we will add a button displaying the total number of to-dos for the owner of the current to-do.

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

@api.one
def compute_user_todo_count(self):
    self.user_todo_count = self.search_count(
        [('user_id', '=', self.user_id.id)])

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

Now we will add the button box with one button inside it. Right after the end of the oe_title div block, add the following:

<div name="buttons" class="oe_right oe_button_box">
  <button class="oe_stat_button"
          type="action" icon="fa-tasks"
          name="%(todo_app.action_todo_task)d"
          string=""
          context="{'search_default_user_id': user_id,
                    'default_user_id': user_id}"
          help="Other to-dos for this user" >

      <field string="To-dos" name="user_todo_count"
             widget="statinfo"/>
  </button>
</div>

The container for the buttons is a div with the oe_button_box class and also oe_right, to have it aligned to the right hand side of the form.

In the example the button displays the total number of to-do tasks the document responsible has. Clicking on it will browse them, and if creating new tasks the original responsible will be used as default.

The button attributes used are:

  • class="oe_stat_button" is to use a rectangle style instead of a button.
  • icon is the icon to use, chosen from the Font Awesome icon set.
  • type will be usually action, for a window action, and name will be the ID of the action to execute. It can be inserted using the formula %(action-external-id)d, to translate the external ID into the actual ID number. This action is expected to open a view with related records.
  • string can be used to add text to the button. It is not used here because the contained field already provides the text for it.
  • context will set defaults on the target view, when clicking through the button, to filter data and set default values for new records created.
  • help is the tooltip to display.

The button itself is a container and can have inside it's fields to display statistics. These are regular fields using the widget statinfo. The field should be a computed field, defined in the underlying module. We can also use static text instead or alongside the statinfo fields, such as: <div>User's To-dos</div>

Organizing content in a form

The main content of the form should be organized using <group> tags. A group is a grid with two columns. A field and its label take two columns, so adding fields inside a group will have them stacked vertically.

If we nest two <group> elements inside a top group, we will be able to get two columns of fields with labels, side by side.

<group name="group_top">
  <group name="group_left">
    <field name="date_deadline" />
    <separator string="Reference" />
    <field name="refers_to" />
  </group>
  <group name="group_right">
    <field name="tag_ids" widget="many2many_tags"/>
  </group>
</group>

Groups can have a string attribute, used as a title for the section. Inside a group section, titles can also be added using a separator element.

Tip

Try the Toggle Form Layout Outline option of the Developer menu: it draws lines around each form section, allowing for a better understanding of how the current view is organized.

Tabbed notebooks

Another way to organize content is the notebook, containing multiple tabbed sections called pages. These can be used to keep less used data out of sight until needed or to organize a large number of fields by topic.

We won't need this on our to-do task form, but here is an example that could be added in the task stages form:

<notebook>
  <page string="Whiteboard" name="whiteboard">
    <field name="docs" />
  </page>
  <page name="second_page">
    <!-- Second page content -->
  </page>
</notebook>

It is good practice to have names on pages, to make it more reliable for other modules to extend them.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset