Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions web_widget_autocomplete/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
=======================
Web Widget Autocomplete
=======================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:962bbb051b41b6c023a4326613614a30d9c9aab2590bdb65e5ca0cb40cbbcda8
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/18.0/web_widget_autocomplete
:alt: OCA/web
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_widget_autocomplete
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module adds a backend Char field widget that typeahead-fills the
field from a public ``@api.model`` method on the same model.

Type in the field; after a configurable number of characters the widget
calls the method with the trimmed input, shows matching rows, and on
select writes the Char plus any extra Char or Integer keys that exist on
the model and in the current view.

**Table of contents**

.. contents::
:local:

Configuration
=============

No configuration is required. Enable the module; consuming addons
declare Char fields and the method.

To try the widget on a partner City field (Umbria cities), install
``web_widget_autocomplete_demo``.

Usage
=====

Use ``widget="autocomplete"`` on a ``fields.Char`` and name a public
``@api.model`` method in ``options``.

The method receives the trimmed input string and must return a list of
dicts. Each dict’s keys are field names. The widget field’s key is the
label shown in the dropdown and the value written to the Char. Any
number of extra keys may be present; on **select** they are written to
sibling Char or Integer fields that exist on the **model and in the same
view** (visible or ``invisible``). Keys missing from the model, missing
from the view, or whose type is not Char/Integer are skipped.

Free typing (without selecting a row) updates only the Char. Extra
fields keep their previous values until the next select.

A **readonly** extra is still filled in the UI on select. It is
persisted on save only if that field’s view node has ``force_save="1"``.
Without it, the fill is dropped on save with no error.

The method must be publicly RPC-callable: not prefixed with ``_``, not
``@api.private``, and decorated with ``@api.model`` so the first
argument is the search string rather than record ids.

.. code:: xml

<field
name="address_string"
widget="autocomplete"
options="{'function': 'address_auto_complete', 'min_symbols': 3, 'debounce': 5}"
/>
<field name="address_ref" readonly="1" force_save="1"/>
<field name="city" invisible="1"/>

.. code:: python

@api.model
def address_auto_complete(self, value):
"""Return autocomplete rows for ``value``.

:param str value: current Char input (trimmed by the widget)
:return: list of dicts whose keys are field names on this model
:rtype: list[dict]
"""
return [
{
"address_string": "string1",
"address_ref": 1,
"city": "Perugia",
},
]

=============== ================= ==================================
Option Type Default if omitted
=============== ================= ==================================
``function`` str (method name) none — no RPC, Char still editable
``min_symbols`` int ``3``
``debounce`` int (ms) ``250``
=============== ================= ==================================

This is typeahead, not a closed ``<select>``. For a dropdown whose
options are fetched once (or when a ``depending_on`` context key
changes), use ``web_widget_dropdown_dynamic`` instead.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_widget_autocomplete%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Cetmix

Contributors
------------

- `Cetmix OÜ <https://cetmix.com>`__:

- Ivan Sokolov

Other credits
-------------

The dropdown UI is Odoo Community ``web.AutoComplete``
(``addons/web/static/src/core/autocomplete/``).

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/web <https://github.com/OCA/web/tree/18.0/web_widget_autocomplete>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions web_widget_autocomplete/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
22 changes: 22 additions & 0 deletions web_widget_autocomplete/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2026 Cetmix OÜ
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).

{
"name": "Web Widget Autocomplete",
"summary": "Autocomplete widget",
"version": "18.0.1.0.0",
"development_status": "Beta",
"category": "Hidden",
"website": "https://github.com/OCA/web",
"author": "Cetmix, Odoo Community Association (OCA)",
"license": "LGPL-3",
"depends": ["web"],
"assets": {
"web.assets_backend": [
"web_widget_autocomplete/static/src/**/*",
],
"web.assets_unit_tests": [
"web_widget_autocomplete/static/tests/**/*",
],
},
}
3 changes: 3 additions & 0 deletions web_widget_autocomplete/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
5 changes: 5 additions & 0 deletions web_widget_autocomplete/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
No configuration is required. Enable the module; consuming addons declare Char
fields and the method.

To try the widget on a partner City field (Umbria cities), install
`web_widget_autocomplete_demo`.
2 changes: 2 additions & 0 deletions web_widget_autocomplete/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [Cetmix OÜ](https://cetmix.com):
- Ivan Sokolov
2 changes: 2 additions & 0 deletions web_widget_autocomplete/readme/CREDITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The dropdown UI is Odoo Community `web.AutoComplete`
(`addons/web/static/src/core/autocomplete/`).
7 changes: 7 additions & 0 deletions web_widget_autocomplete/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This module adds a backend Char field widget that typeahead-fills the field
from a public `@api.model` method on the same model.

Type in the field; after a configurable number of characters the widget calls
the method with the trimmed input, shows matching rows, and on select writes
the Char plus any extra Char or Integer keys that exist on the model and in
the current view.
59 changes: 59 additions & 0 deletions web_widget_autocomplete/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Use `widget="autocomplete"` on a `fields.Char` and name a public
`@api.model` method in `options`.

The method receives the trimmed input string and must return a list of
dicts. Each dict’s keys are field names. The widget field’s key is the
label shown in the dropdown and the value written to the Char. Any number
of extra keys may be present; on **select** they are written to sibling
Char or Integer fields that exist on the **model and in the same view**
(visible or `invisible`). Keys missing from the model, missing from the
view, or whose type is not Char/Integer are skipped.

Free typing (without selecting a row) updates only the Char. Extra fields
keep their previous values until the next select.

A **readonly** extra is still filled in the UI on select. It is persisted
on save only if that field’s view node has `force_save="1"`. Without it,
the fill is dropped on save with no error.

The method must be publicly RPC-callable: not prefixed with `_`, not
`@api.private`, and decorated with `@api.model` so the first argument is
the search string rather than record ids.

```xml
<field
name="address_string"
widget="autocomplete"
options="{'function': 'address_auto_complete', 'min_symbols': 3, 'debounce': 5}"
/>
<field name="address_ref" readonly="1" force_save="1"/>
<field name="city" invisible="1"/>
```

```python
@api.model
def address_auto_complete(self, value):
"""Return autocomplete rows for ``value``.

:param str value: current Char input (trimmed by the widget)
:return: list of dicts whose keys are field names on this model
:rtype: list[dict]
"""
return [
{
"address_string": "string1",
"address_ref": 1,
"city": "Perugia",
},
]
```

| Option | Type | Default if omitted |
|--------|------|-------------------|
| `function` | str (method name) | none — no RPC, Char still editable |
| `min_symbols` | int | `3` |
| `debounce` | int (ms) | `250` |

This is typeahead, not a closed `<select>`. For a dropdown whose options
are fetched once (or when a `depending_on` context key changes), use
`web_widget_dropdown_dynamic` instead.
Loading
Loading