diff --git a/web_domain_field/README.rst b/web_domain_field/README.rst
new file mode 100644
index 000000000..e70f68f28
--- /dev/null
+++ b/web_domain_field/README.rst
@@ -0,0 +1,104 @@
+.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+
+================
+Web Domain Field
+================
+
+When you define a view you can specify on the relational fields a domain
+attribute. This attribute is evaluated as filter to apply when displaying
+existing records for selection.
+
+.. code-block:: xml
+
+
+
+The value provided for the domain attribute must be a string representing a
+valid Odoo domain. This string is evaluated on the client side in a
+restricted context where we can reference as right operand the values of
+fields present into the form and a limited set of functions.
+
+In this context it's hard to build complex domain and we are facing to some
+limitations as:
+
+ * The syntax to include in your domain a criteria involving values from a
+ x2many field is complex.
+ * Domains computed by an onchange on an other field are not recomputed when
+ you modify the form and don't modify the field triggering the onchange.
+ * It's not possible to extend an existing domain. You must completely redefine
+ the domain in your specialized addon
+ * ...
+
+In order to mitigate these limitations this new addon allows you to use the
+value of a field as domain of an other field in the xml definition of your
+view.
+
+.. code-block:: xml
+
+
+
+
+The field used as domain must provide the domain as a JSON encoded string.
+
+.. code-block:: python
+
+ product_id_domain = fields.Char(
+ compute="_compute_product_id_domain",
+ readonly=True,
+ store=False,
+ )
+
+ @api.multi
+ @api.depends('name')
+ def _compute_product_id_domain(self):
+ for rec in self:
+ rec.product_id_domain = json.dumps(
+ [('type', '=', 'product'), ('name', 'like', rec.name)]
+ )
+
+
+Usage
+=====
+
+.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
+ :alt: Try me on Runbot
+ :target: https://runbot.odoo-community.org/runbot/162/9.0
+
+
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues
+`_. In case of trouble, please
+check there if your issue has already been reported. If you spotted it first,
+help us smashing it by providing a detailed and welcomed feedback.
+
+Credits
+=======
+
+Images
+------
+
+* Odoo Community Association: `Icon `_.
+
+Contributors
+------------
+
+* Laurent Mignon
+
+Maintainer
+----------
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+This module is maintained by the OCA.
+
+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.
+
+To contribute to this module, please visit https://odoo-community.org.
diff --git a/web_domain_field/__init__.py b/web_domain_field/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/web_domain_field/__openerp__.py b/web_domain_field/__openerp__.py
new file mode 100644
index 000000000..4ff66a1c7
--- /dev/null
+++ b/web_domain_field/__openerp__.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Copyright 2017 ACSONE SA/NV
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ 'name': 'Web Domain Field',
+ 'summary': """
+ Use computed field as domain""",
+ 'version': '9.0.1.0.0',
+ 'license': 'AGPL-3',
+ 'author': 'ACSONE SA/NV,Odoo Community Association (OCA)',
+ 'website': 'https://acsone.eu/',
+ 'depends': [
+ 'web'
+ ],
+ 'data': [
+ 'views/web_domain_field.xml',
+ ],
+ 'demo': [
+ ],
+}
diff --git a/web_domain_field/static/description/icon.png b/web_domain_field/static/description/icon.png
new file mode 100644
index 000000000..3a0328b51
Binary files /dev/null and b/web_domain_field/static/description/icon.png differ
diff --git a/web_domain_field/static/src/js/pyeval.js b/web_domain_field/static/src/js/pyeval.js
new file mode 100644
index 000000000..f4b75e579
--- /dev/null
+++ b/web_domain_field/static/src/js/pyeval.js
@@ -0,0 +1,233 @@
+odoo.define('web.domain_field', function (require) {
+"use strict";
+
+var pyeval = require('web.pyeval');
+var session = require('web.session');
+
+
+var original_pyeval = pyeval.eval;
+var original_ensure_evaluated = pyeval.ensure_evaluated;
+var py = window.py;
+
+/** copied from pyeval and not modified but required since not publicly
+exposed by web.pyeval**/
+
+// recursively wraps JS objects passed into the context to attributedicts
+// which jsonify back to JS objects
+function wrap(value) {
+ if (value === null) { return py.None; }
+
+ switch (typeof value) {
+ case 'undefined': throw new Error("No conversion for undefined");
+ case 'boolean': return py.bool.fromJSON(value);
+ case 'number': return py.float.fromJSON(value);
+ case 'string': return py.str.fromJSON(value);
+ }
+
+ switch(value.constructor) {
+ case Object: return wrapping_dict.fromJSON(value);
+ case Array: return wrapping_list.fromJSON(value);
+ }
+
+ throw new Error("ValueError: unable to wrap " + value);
+}
+
+var wrapping_dict = py.type('wrapping_dict', null, {
+ __init__: function () {
+ this._store = {};
+ },
+ __getitem__: function (key) {
+ var k = key.toJSON();
+ if (!(k in this._store)) {
+ throw new Error("KeyError: '" + k + "'");
+ }
+ return wrap(this._store[k]);
+ },
+ __getattr__: function (key) {
+ return this.__getitem__(py.str.fromJSON(key));
+ },
+ __len__: function () {
+ return Object.keys(this._store).length
+ },
+ __nonzero__: function () {
+ return py.PY_size(this) > 0 ? py.True : py.False;
+ },
+ get: function () {
+ var args = py.PY_parseArgs(arguments, ['k', ['d', py.None]]);
+
+ if (!(args.k.toJSON() in this._store)) { return args.d; }
+ return this.__getitem__(args.k);
+ },
+ fromJSON: function (d) {
+ var instance = py.PY_call(wrapping_dict);
+ instance._store = d;
+ return instance;
+ },
+ toJSON: function () {
+ return this._store;
+ },
+});
+
+var wrapping_list = py.type('wrapping_list', null, {
+ __init__: function () {
+ this._store = [];
+ },
+ __getitem__: function (index) {
+ return wrap(this._store[index.toJSON()]);
+ },
+ __len__: function () {
+ return this._store.length;
+ },
+ __nonzero__: function () {
+ return py.PY_size(this) > 0 ? py.True : py.False;
+ },
+ fromJSON: function (ar) {
+ var instance = py.PY_call(wrapping_list);
+ instance._store = ar;
+ return instance;
+ },
+ toJSON: function () {
+ return this._store;
+ },
+});
+
+function wrap_context (context) {
+ for (var k in context) {
+ if (!context.hasOwnProperty(k)) { continue; }
+ var val = context[k];
+
+ if (val === null) { continue; }
+ if (val.constructor === Array) {
+ context[k] = wrapping_list.fromJSON(val);
+ } else if (val.constructor === Object
+ && !py.PY_isInstance(val, py.object)) {
+ context[k] = wrapping_dict.fromJSON(val);
+ }
+ }
+ return context;
+}
+
+function ensure_evaluated (args, kwargs) {
+ for (var i=0; i
+
+
+
+
+
+
+
\ No newline at end of file