[IMP] developer: add Dropdown documentation
joint work with Bruno (boi) closes odoo/documentation#1247 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
parent
94b26c5fe0
commit
91f97aff54
@ -10,10 +10,9 @@ Frontend
|
||||
frontend/framework_overview
|
||||
frontend/assets
|
||||
frontend/javascript_modules
|
||||
frontend/owl_component_system
|
||||
frontend/owl_components
|
||||
frontend/registries
|
||||
frontend/services
|
||||
frontend/generic_components
|
||||
frontend/hooks
|
||||
frontend/javascript_cheatsheet
|
||||
frontend/javascript_reference
|
||||
|
@ -1,47 +0,0 @@
|
||||
==================
|
||||
Generic Components
|
||||
==================
|
||||
|
||||
The Odoo web client is built with `Owl <https://github.com/odoo/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.
|
||||
|
||||
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
|
||||
|
||||
<CheckBox value="boolean" disabled="boolean" t-on-change="onValueChange">
|
||||
Some Text
|
||||
</CheckBox>
|
||||
|
||||
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
|
||||
|
||||
|
@ -12,6 +12,19 @@ Using these hooks, it is possible to build many customized hooks that help solve
|
||||
a specific problem, or make some common tasks easier. The rest of this page
|
||||
documents the list of hooks provided by the Odoo web framework.
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 70
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Short Description
|
||||
* - :ref:`useBus <frontend/hooks/usebus>`
|
||||
- subscribe and unsubscribe to a bus
|
||||
* - :ref:`usePosition <frontend/hooks/useposition>`
|
||||
- position an element relative to a target
|
||||
|
||||
.. _frontend/hooks/usebus:
|
||||
|
||||
useBus
|
||||
======
|
||||
|
||||
@ -47,3 +60,69 @@ API
|
||||
:param string eventName: the name of the event that we want to listen to
|
||||
:param function callback: listener callback
|
||||
|
||||
.. _frontend/hooks/useposition:
|
||||
|
||||
usePosition
|
||||
===========
|
||||
|
||||
Location
|
||||
--------
|
||||
|
||||
`@web/core/position/position_hook`
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Helps positioning a component (or a specific HTMLElement) relatively to a target
|
||||
HTMLElement. This hook ensures the positioning is updated when the window is
|
||||
resized/scrolled.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
import { usePosition } from "@web/core/position/position_hook";
|
||||
|
||||
class MyPopover {
|
||||
setup() {
|
||||
// Here, the target is an HTMLElement
|
||||
usePosition(this.props.target);
|
||||
}
|
||||
}
|
||||
MyPopover.template = owl.tags.xml`<div>I am positioned through a wonderful hook!</div>`
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
.. js:function:: usePosition(reference[, options])
|
||||
|
||||
:param reference: the target HTMLElement to be positioned from
|
||||
:type reference: HTMLElement or ()=>HTMLElement
|
||||
:param Options options: the positioning options (see table below)
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 20 60
|
||||
:header-rows: 1
|
||||
|
||||
* - Option
|
||||
- Type
|
||||
- Description
|
||||
* - `popper`
|
||||
- string | undefined
|
||||
- this is the element that will get positioned. You can provide here a
|
||||
`useRef reference <https://github.com/odoo/owl/blob/master/doc/reference/hooks.md#useref>`_.
|
||||
If not provided, `this.el` is used (default: `undefined`).
|
||||
* - `container`
|
||||
- HTMLElement
|
||||
- the container from which the popper is expected not to overflow. If
|
||||
overflowing occurs, other popper positions are tried until a not
|
||||
overflowing one is found. (default: the `<html/>` node)
|
||||
* - `margin`
|
||||
- number
|
||||
- added margin between popper and reference elements (default: `0`)
|
||||
* - `position`
|
||||
- string
|
||||
- the desired position. It is a string composed of one direction and one
|
||||
variant separated by a dash character. Valid directions are: `top`,
|
||||
`bottom`, `right`, `left`. Valid variants are: `start`,
|
||||
`middle`, `end`. The variant can be omitted (default variant is
|
||||
`middle`). Examples of valid positions: `right-end`, `top-start`,
|
||||
`left-middle`, `left`. (default position: `bottom`)
|
||||
|
@ -1,106 +0,0 @@
|
||||
|
||||
====================
|
||||
Owl Component System
|
||||
====================
|
||||
|
||||
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 <qweb>`, enriched with some Owl
|
||||
specific directives. The official
|
||||
`Owl documentation <https://github.com/odoo/owl/blob/master/doc/readme.md>`_
|
||||
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 in Odoo
|
||||
============================
|
||||
|
||||
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
|
||||
`<div t-on-click="increment">
|
||||
<t t-esc="state.value">
|
||||
</div>`;
|
||||
|
||||
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
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="myaddon.MyComponent" owl="1">
|
||||
<div t-on-click="increment">
|
||||
<t t-esc="state.value"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
Odoo code is not yet completely made in Owl, so it needs a way to tell the
|
||||
difference between Owl templates (new code) and old templates (for components). To
|
||||
do that in a backward-compatible way, all new templates should be defined with
|
||||
the ``owl`` attribute set to 1.
|
||||
|
||||
.. note::
|
||||
|
||||
Do not forget to set ``owl="1"`` in your Owl templates!
|
||||
|
||||
.. note::
|
||||
|
||||
Template names should follow the convention `addon_name.ComponentName`.
|
||||
|
||||
|
||||
.. seealso::
|
||||
- `Owl Repository <https://github.com/odoo/owl>`_
|
438
content/developer/reference/frontend/owl_components.rst
Normal file
438
content/developer/reference/frontend/owl_components.rst
Normal file
@ -0,0 +1,438 @@
|
||||
|
||||
==============
|
||||
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 <qweb>`, enriched with some Owl
|
||||
specific directives. The official
|
||||
`Owl documentation <https://github.com/odoo/owl/blob/master/doc/readme.md>`_
|
||||
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
|
||||
`<div t-on-click="increment">
|
||||
<t t-esc="state.value">
|
||||
</div>`;
|
||||
|
||||
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
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="myaddon.MyComponent" owl="1">
|
||||
<div t-on-click="increment">
|
||||
<t t-esc="state.value"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
Odoo code is not yet completely made in Owl, so it needs a way to tell the
|
||||
difference between Owl templates (new code) and old templates (for components). To
|
||||
do that in a backward-compatible way, all new templates should be defined with
|
||||
the ``owl`` attribute set to 1.
|
||||
|
||||
.. note::
|
||||
|
||||
Do not forget to set ``owl="1"`` in your Owl templates!
|
||||
|
||||
.. note::
|
||||
|
||||
Template names should follow the convention `addon_name.ComponentName`.
|
||||
|
||||
|
||||
.. seealso::
|
||||
- `Owl Repository <https://github.com/odoo/owl>`_
|
||||
|
||||
Reference List
|
||||
==============
|
||||
|
||||
The Odoo web client is built with `Owl <https://github.com/odoo/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:`CheckBox <frontend/checkbox>`
|
||||
- a simple checkbox component with a label next to it
|
||||
* - :ref:`Dropdown <frontend/dropdown>`
|
||||
- full-featured dropdown
|
||||
|
||||
.. _frontend/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
|
||||
|
||||
<CheckBox value="boolean" disabled="boolean" t-on-change="onValueChange">
|
||||
Some Text
|
||||
</CheckBox>
|
||||
|
||||
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/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
|
||||
- Emit an event to inform which list item is clicked
|
||||
- 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
|
||||
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">
|
||||
<!-- "toggler" slot content is rendered inside a button -->
|
||||
Click me to toggle the dropdown menu !
|
||||
</t>
|
||||
<!-- "default" slot content is rendered inside a div -->
|
||||
<DropdownItem t-on-dropdown-item-selected="selectItem1">Menu Item 1</DropdownItem>
|
||||
<DropdownItem t-on-dropdown-item-selected="selectItem2">Menu Item 2</DropdownItem>
|
||||
</Dropdown>
|
||||
|
||||
Props
|
||||
~~~~~
|
||||
|
||||
A `<Dropdown/>` component is simply a `<div class="dropdown"/>` having a
|
||||
`<button class="dropdown-toggle"/>` next to menu div
|
||||
(`<div class="dropdown-menu"/>`). The button is responsible for the menu
|
||||
being present in the DOM or not.
|
||||
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 20 60
|
||||
:header-rows: 1
|
||||
|
||||
* - Dropdown
|
||||
- Type
|
||||
- Description
|
||||
* - ``startOpen``
|
||||
- boolean
|
||||
- initial dropdown open state (defaults to `false`)
|
||||
* - ``menuClass``
|
||||
- string
|
||||
- additional css class applied to the dropdown menu ``<div class="dropdown-menu"/>``
|
||||
* - ``togglerClass``
|
||||
- string
|
||||
- additional css class applied to the toggler ``<button class="dropdown-toggle"/>``
|
||||
* - ``hotkey``
|
||||
- string
|
||||
- hotkey to toggle the opening through keyboard
|
||||
* - ``beforeOpen``
|
||||
- function
|
||||
- hook to execute logic just before opening. May be asynchronous.
|
||||
* - ``manualOnly``
|
||||
- boolean
|
||||
- if true, only toggle the dropdown when the button is clicked on (defaults to `false`)
|
||||
* - ``title``
|
||||
- string
|
||||
- title attribute content for the ``<button class="dropdown-toggle"/>`` (default: none)
|
||||
* - ``position``
|
||||
- string
|
||||
- defines the desired menu opening position. RTL direction is automatically applied. Should be a valid :ref:`usePosition <frontend/hooks/useposition>` hook position. (default: ``bottom-start``)
|
||||
* - ``toggler``
|
||||
- ``"parent"`` or ``undefined``
|
||||
- when set to ``"parent"`` the ``<button class="dropdown-toggle"/>`` is not
|
||||
rendered (thus ``toggler`` slot is ignored) and the toggling feature is handled by the parent node (e.g. use
|
||||
case: pivot cells). (default: ``undefined``)
|
||||
|
||||
|
||||
A `<DropdownItem/>` is simply a span (`<span class="dropdown-item"/>`).
|
||||
When a `<DropdownItem/>` is selected, it emits a custom `dropdown-item-selected`
|
||||
event containing its payload. (see
|
||||
`OWL Business Events <https://github.com/odoo/owl/blob/master/doc/reference/event_handling.md#business-dom-events>`_).
|
||||
So, to react to such an event, one needs to define an event listener on the
|
||||
`dropdown-item-selected` event.
|
||||
|
||||
.. list-table::
|
||||
:widths: 20 20 60
|
||||
:header-rows: 1
|
||||
|
||||
* - DropdownItem
|
||||
- Type
|
||||
- Description
|
||||
* - ``payload``
|
||||
- Object
|
||||
- payload that will be added to the `dropdown-item-selected` event (default to null)
|
||||
* - `parentClosingMode`
|
||||
- `none` | `closest` | `all`
|
||||
- when the item is selected, control which parent dropdown will get closed:
|
||||
none, closest or all (default = `all`)
|
||||
* - ``hotkey``
|
||||
- string
|
||||
- optional hotkey to select the item
|
||||
* - ``href``
|
||||
- string
|
||||
- if provided the DropdownItem will become an ``<a href="value" class="dropdown-item"/>`` instead of a ``<span class="dropdown-item"/>``. (default: not provided)
|
||||
* - ``title``
|
||||
- string
|
||||
- optional title attribute which will be passed to the root node of the DropdownItem. (default: not provided)
|
||||
|
||||
Technical notes
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The rendered DOM is structured like this:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="dropdown-toggle">Click me !</button>
|
||||
<!-- following <div/> will or won't appear in the DOM depending on the state controlled by the preceding button -->
|
||||
<div class="dropdown-menu">
|
||||
<span class="dropdown-item">Menu Item 1</span>
|
||||
<span class="dropdown-item">Menu Item 2</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
To properly use a `<Dropdown/>` component, you need to populate two
|
||||
`OWL slots <https://github.com/odoo/owl/blob/master/doc/reference/slots.md>`_ :
|
||||
|
||||
|
||||
- `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 ``<div class="dropdown-menu"/>``. Although it is not mandatory, there is usually at least one
|
||||
`DropdownItem` inside the `menu` slot.
|
||||
|
||||
|
||||
When several dropdowns share the same parent element in the DOM, then they are
|
||||
considered part of a group, and will notify each other about their state changes.
|
||||
This means that when one of these dropdowns is open, the others will automatically
|
||||
open themselves on mouse hover, without the need for a click.
|
||||
|
||||
|
||||
Example: Direct Siblings Dropdown
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When one dropdown toggler is clicked (**File** , **Edit** or **About**), the
|
||||
others will open themselves on hover.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<div t-on-dropdown-item-selected="onItemSelected">
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">File</t>
|
||||
<DropdownItem payload="'file-open'">Open</DropdownItem>
|
||||
<DropdownItem payload="'file-new-document'">New Document</DropdownItem>
|
||||
<DropdownItem payload="'file-new-spreadsheet'">New Spreadsheet</DropdownItem>
|
||||
</Dropdown>
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">Edit</t>
|
||||
<DropdownItem payload="'edit-undo'">Undo</DropdownItem>
|
||||
<DropdownItem payload="'edit-redo'">Redo</DropdownItem>
|
||||
<DropdownItem payload="'edit-find'">Search</DropdownItem>
|
||||
</Dropdown>
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">About</t>
|
||||
<DropdownItem payload="'about-help'">Help</DropdownItem>
|
||||
<DropdownItem payload="'about-update'">Check update</DropdownItem>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
Example: Multi-level Dropdown (with `t-call`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This example shows how one could make a `File` dropdown menu, with submenus for
|
||||
the `New` and `Save as...` sub elements.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-name="addon.Dropdown.File" owl="1">
|
||||
<Dropdown t-on-dropdown-item-selected="onItemSelected">
|
||||
<t t-set-slot="toggler">File</t>
|
||||
<DropdownItem payload="'file-open'">Open</DropdownItem>
|
||||
<t t-call="addon.Dropdown.File.New"/>
|
||||
<DropdownItem payload="'file-save'">Save</DropdownItem>
|
||||
<t t-call="addon.Dropdown.File.Save.As"/>
|
||||
</Dropdown>
|
||||
</t>
|
||||
|
||||
<t t-name="addon.Dropdown.File.New" owl="1">
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">New</t>
|
||||
<DropdownItem payload="'file-new-document'">Document</DropdownItem>
|
||||
<DropdownItem payload="'file-new-spreadsheet'">Spreadsheet</DropdownItem>
|
||||
</Dropdown>
|
||||
</t>
|
||||
|
||||
<t t-name="addon.Dropdown.File.Save.As" owl="1">
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">Save as...</t>
|
||||
<DropdownItem payload="'file-save-as-csv'">CSV</DropdownItem>
|
||||
<DropdownItem payload="'file-save-as-pdf'">PDF</DropdownItem>
|
||||
</Dropdown>
|
||||
</t>
|
||||
|
||||
Example: Multi-level Dropdown (nested)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<Dropdown t-on-dropdown-item-selected="onItemSelected">
|
||||
<t t-set-slot="toggler">File</t>
|
||||
<DropdownItem payload="'file-open'">Open</DropdownItem>
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">New</t>
|
||||
<DropdownItem payload="'file-new-document'">Document</DropdownItem>
|
||||
<DropdownItem payload="'file-new-spreadsheet'">Spreadsheet</DropdownItem>
|
||||
</Dropdown>
|
||||
<DropdownItem payload="'file-save'">Save</DropdownItem>
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler">Save as...</t>
|
||||
<DropdownItem payload="'file-save-as-csv'">CSV</DropdownItem>
|
||||
<DropdownItem payload="'file-save-as-pdf'">PDF</DropdownItem>
|
||||
</Dropdown>
|
||||
</Dropdown>
|
||||
|
||||
Example: Recursive Multi-level Dropdown
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In this example, we recursively call a template to display a tree-like structure.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-name="addon.MainTemplate" owl="1">
|
||||
<div t-on-dropdown-item-selected="onItemSelected">
|
||||
<t t-call="addon.RecursiveDropdown">
|
||||
<t t-set="name" t-value="'Main Menu'" />
|
||||
<t t-set="items" t-value="state.menuItems" />
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="addon.RecursiveDropdown" owl="1">
|
||||
<Dropdown>
|
||||
<t t-set-slot="toggler"><t t-esc="name"/></t>
|
||||
<t t-foreach="items" t-as="item" t-key="item.id">
|
||||
|
||||
<!-- If this item has no child: make it a <DropdownItem/> -->
|
||||
<t t-if="!item.childrenTree.length">
|
||||
<DropdownItem payload="item" t-esc="item.name"/>
|
||||
</t>
|
||||
<!-- Else: recursively call the current dropdown template. -->
|
||||
<t t-else="" t-call="addon.RecursiveDropdown">
|
||||
<t t-set="name" t-value="item.name" />
|
||||
<t t-set="items" t-value="item.childrenTree" />
|
||||
</t>
|
||||
|
||||
</t>
|
||||
</t>
|
||||
</Dropdown>
|
||||
</t>
|
@ -312,4 +312,7 @@ developer/reference/javascript/javascript_reference.rst developer/refer
|
||||
developer/reference/javascript/mobile.rst developer/reference/frontend/mobile.rst
|
||||
developer/reference/javascript/qweb.rst developer/reference/frontend/qweb.rst
|
||||
|
||||
developer/reference/backend/assets.rst developer/reference/frontend/assets.rst
|
||||
developer/reference/backend/assets.rst developer/reference/frontend/assets.rst
|
||||
|
||||
developer/reference/frontend/owl_component_system.rst developer/reference/frontend/owl_components.rst
|
||||
developer/reference/frontend/generic_components.rst developer/reference/frontend/owl_components.rst
|
Loading…
Reference in New Issue
Block a user