.. _frontend/components: ============== Owl components ============== The Odoo Javascript framework uses a custom component framework called Owl. It is a declarative component system, loosely inspired by Vue and React. Components are defined using :doc:`QWeb templates `, enriched with some Owl specific directives. The official `Owl documentation `_ contains a complete reference and a tutorial. .. important:: Although the code can be found in the `web` module, it is maintained from a separate GitHub repository. Any modification to Owl should therefore be made through a pull request on https://github.com/odoo/owl. .. note:: Currently, all Odoo versions (starting in version 14) share the same Owl version. Using Owl components ==================== The `Owl documentation`_ already documents in detail the Owl framework, so this page will only provide Odoo specific information. But first, let us see how we can make a simple component in Odoo. .. code-block:: javascript const { useState } = owl.hooks; const { xml } = owl.tags; class MyComponent extends Component { setup() { this.state = useState({ value: 1 }); } increment() { this.state.value++; } } MyComponent.template = xml `
`; This example shows that Owl is available as a library in the global namespace as `owl`: it can simply be used like most libraries in Odoo. Note that we defined here the template as a static property, but without using the `static` keyword, which is not available in some browsers (Odoo javascript code should be Ecmascript 2019 compliant). We define here the template in the javascript code, with the help of the `xml` helper. However, it is only useful to get started. In practice, templates in Odoo should be defined in an xml file, so they can be translated. In that case, the component should only define the template name. In practice, most components should define 2 or 3 files, located at the same place: a javascript file (`my_component.js`), a template file (`my_component.xml`) and optionally a scss (or css) file (`my_component.scss`). These files should then be added to some assets bundle. The web framework will take care of loading the javascript/css files, and loading the templates into Owl. Here is how the component above should be defined: .. code-block:: javascript const { useState } = owl.hooks; class MyComponent extends Component { ... } MyComponent.template = 'myaddon.MyComponent'; And the template is now located in the corresponding xml file: .. code-block:: xml
.. note:: Template names should follow the convention `addon_name.ComponentName`. .. seealso:: - `Owl Repository `_ .. _frontend/owl/best_practices: Best practices ============== First of all, components are classes, so they have a constructor. But constructors are special methods in javascript that are not overridable in any way. Since this is an occasionally useful pattern in Odoo, we need to make sure that no component in Odoo directly uses the constructor method. Instead, components should use the `setup` method: .. code-block:: javascript // correct: class MyComponent extends Component { setup() { // initialize component here } } // incorrect. Do not do that! class IncorrectComponent extends Component { constructor(parent, props) { // initialize component here } } Another good practice is to use a consistent convention for template names: `addon_name.ComponentName`. This prevents name collision between odoo addons. Reference List ============== The Odoo web client is built with `Owl `_ components. To make it easier, the Odoo javascript framework provides a suite of generic components that can be reused in some common situations, such as dropdowns, checkboxes or datepickers. This page explains how to use these generic components. .. list-table:: :widths: 30 70 :header-rows: 1 * - Technical Name - Short Description * - :ref:`ActionSwiper ` - a swiper component to perform actions on touch swipe * - :ref:`CheckBox ` - a simple checkbox component with a label next to it * - :ref:`ColorList ` - a list of colors to choose from * - :ref:`Dropdown ` - full-featured dropdown * - :ref:`Notebook ` - a component to navigate between pages using tabs * - :ref:`Pager ` - a small component to handle pagination * - :ref:`SelectMenu ` - a dropdown component to choose between different options * - :ref:`TagsList ` - a list of tags displayed in rounded pills .. _frontend/owl/actionswiper: ActionSwiper ------------ Location ~~~~~~~~ `@web/core/action_swiper/action_swiper` Description ~~~~~~~~~~~ This is a component that can perform actions when an element is swiped horizontally. The swiper is wrapping a target element to add actions to it. The action is executed once the user has released the swiper passed a portion of its width. .. code-block:: xml The simplest way to use the component is to use it around your target element directly in an xml template as shown above. But sometimes, you may want to extend an existing element and would not want to duplicate the template. It is possible to do just that. If you want to extend the behavior of an existing element, you must place the element inside, by wrapping it directly. Also, you can conditionnally add props to manage when the element might be swipable, its animation and the minimum portion to swipe to perform the action. You can use the component to interact easily with records, messages, items in lists and much more. .. image:: owl_components/actionswiper.png :width: 400 px :alt: Example of ActionSwiper usage :align: center The following example creates a basic ActionSwiper component. Here, the swipe is enabled in both directions. .. code-block:: xml
Swipable item
.. note:: Actions are permuted when using right-to-left (RTL) languages. Props ~~~~~ .. list-table:: :widths: 20 20 60 :header-rows: 1 * - Name - Type - Description * - `animationOnMove` - `Boolean` - optional boolean to determine if a translate effect is present during the swipe * - `animationType` - `String` - optional animation that is used after the swipe ends (`bounce` or `forwards`) * - `onLeftSwipe` - `Object` - if present, the actionswiper can be swiped to the left * - `onRightSwipe` - `Object` - if present, the actionswiper can be swiped to the right * - `swipeDistanceRatio` - `Number` - optional minimum width ratio that must be swiped to perform the action You can use both `onLeftSwipe` and `onRightSwipe` props at the same time. The `Object`'s used for the left/right swipe must contain: - `action`, which is the callable `Function` serving as a callback. Once the swipe has been completed in the given direction, that action is performed. - `icon` is the icon class to use, usually to represent the action. It must be a `string`. - `bgColor` is the background color, given to decorate the action. can be one of the following `bootstrap contextual color `_ (`danger`, `info`, `secondary`, `success` or `warning`). Those values must be given to define the behavior and the visual aspect of the swiper. Example: Extending existing components ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the following example, you can use `xpath`'s to wrap an existing element in the ActionSwiper component. Here, a swiper has been added to mark a message as read in mail. .. code-block:: xml .. _frontend/owl/checkbox: CheckBox -------- Location ~~~~~~~~ `@web/core/checkbox/checkbox` Description ~~~~~~~~~~~ This is a simple checkbox component with a label next to it. The checkbox is linked to the label: the checkbox is toggled whenever the label is clicked. .. code-block:: xml Some Text Props ~~~~~ .. list-table:: :widths: 20 20 60 :header-rows: 1 * - Name - Type - Description * - `value` - `boolean` - if true, the checkbox is checked, otherwise it is unchecked * - `disabled` - `boolean` - if true, the checkbox is disabled, otherwise it is enabled .. _frontend/owl/colorlist: ColorList --------- Location ~~~~~~~~ `@web/core/colorlist/colorlist` Description ~~~~~~~~~~~ The ColorList let you choose a color from a predefined list. By default, the component displays the current selected color, and is not expandable until the `canToggle` props is present. Different props can change its behavior, to always expand the list, or make it act as a toggler once it is clicked, to display the list of available colors until a choice is selected. Props ~~~~~ .. list-table:: :widths: 20 20 60 :header-rows: 1 * - Name - Type - Description * - `canToggle` - `boolean` - optional. Whether the colorlist can expand the list on click * - `colors` - `array` - list of colors to display in the component. Each color has a unique `id` * - `forceExpanded` - `boolean` - optional. If true, the list is always expanded * - `isExpanded` - `boolean` - optional. If true, the list is expanded by default * - `onColorSelected` - `function` - callback executed once a color is selected * - `selectedColor` - `number` - optional. The color `id` that is selected Color `id`'s are the following: .. list-table:: :header-rows: 1 * - Id - Color * - `0` - `No color` * - `1` - `Red` * - `2` - `Orange` * - `3` - `Yellow` * - `4` - `Light blue` * - `5` - `Dark purple` * - `6` - `Salmon pink` * - `7` - `Medium blue` * - `8` - `Dark blue` * - `9` - `Fuchsia` * - `12` - `Green` * - `11` - `Purple` .. _frontend/owl/dropdown: Dropdown -------- Location ~~~~~~~~ `@web/core/dropdown/dropdown` and `@web/core/dropdown/dropdown_item` Description ~~~~~~~~~~~ Dropdowns are surprisingly complicated components. They need to provide many features such as: - Toggle the item list on click - Direct siblings dropdowns: when one is open, toggle others on hover - Close on outside click - Optionally close the item list when an item is selected - Call a function when the item is selected - Support sub dropdowns, up to any level - SIY: style it yourself - Configurable hotkey to open/close a dropdown or select a dropdown item - Keyboard navigation (arrows, tab, shift+tab, home, end, enter and escape) - Reposition itself whenever the page scrolls or is resized - Smartly chose the direction it should open (right-to-left direction is automatically handled). To solve these issues once and for all, the Odoo framework provides a set of two components: a `Dropdown` component (the actual dropdown), and `DropdownItem`, for each element in the item list. .. code-block:: xml Click me to toggle the dropdown menu ! Menu Item 1 Menu Item 2 Props ~~~~~ A `` component is simply a ` To properly use a `` component, you need to populate two `OWL slots `_ : - `toggler` slot: it contains the *toggler* elements of your dropdown and is rendered inside the dropdown `button` (unless the `toggler` prop is set to `parent`), - `default` slot: it contains the *elements* of the dropdown menu itself and is rendered inside the `