From f1856cce2438b896e7623bc82d4fa219041eb715 Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Tue, 5 Jul 2022 12:47:56 +0000 Subject: [PATCH] [FIX] web: Adds missing placeholders to fields with an input This commit adds the ability to pass a placeholder to all fields containing an input. This commit tests the ability to use a placeholder in all fields containing an input. closes odoo/odoo#95309 Signed-off-by: Aaron Bohy (aab) --- .../src/views/fields/email/email_field.js | 6 +++++ .../src/views/fields/float/float_field.js | 2 ++ .../src/views/fields/float/float_field.xml | 2 +- .../fields/float_time/float_time_field.js | 4 ++- .../fields/float_time/float_time_field.xml | 2 +- .../fields/percentage/percentage_field.js | 2 ++ .../fields/percentage/percentage_field.xml | 1 + .../tests/views/fields/char_field_tests.js | 23 ++++++++++++++++ .../tests/views/fields/email_field_tests.js | 26 ++++++++++++++++++- .../tests/views/fields/float_field_tests.js | 21 +++++++++++++-- .../views/fields/float_time_field_tests.js | 22 +++++++++++++++- .../fields/font_selection_field_tests.js | 8 +++++- .../tests/views/fields/integer_field_tests.js | 25 +++++++++++++++++- .../fields/many2many_tags_field_tests.js | 15 +++++++++++ .../fields/many2one_avatar_field_tests.js | 15 +++++++++++ .../views/fields/many2one_field_tests.js | 14 ++++++++++ .../views/fields/monetary_field_tests.js | 22 ++++++++++++++++ .../views/fields/percentage_field_tests.js | 22 +++++++++++++++- .../tests/views/fields/phone_field_tests.js | 23 ++++++++++++++++ .../views/fields/selection_field_tests.js | 18 +++++++++++++ .../tests/views/fields/url_field_tests.js | 23 ++++++++++++++++ 21 files changed, 286 insertions(+), 10 deletions(-) diff --git a/addons/web/static/src/views/fields/email/email_field.js b/addons/web/static/src/views/fields/email/email_field.js index d97742001b1..550ac5b6814 100644 --- a/addons/web/static/src/views/fields/email/email_field.js +++ b/addons/web/static/src/views/fields/email/email_field.js @@ -16,6 +16,12 @@ export class EmailField extends Component { EmailField.template = "web.EmailField"; EmailField.props = { ...standardFieldProps, + placeholder: { type: String, optional: true }, +}; +EmailField.extractProps = (fieldName, record, attrs) => { + return { + placeholder: attrs.placeholder, + }; }; EmailField.displayName = _lt("Email"); diff --git a/addons/web/static/src/views/fields/float/float_field.js b/addons/web/static/src/views/fields/float/float_field.js index 81b73a7b767..e23967678a0 100644 --- a/addons/web/static/src/views/fields/float/float_field.js +++ b/addons/web/static/src/views/fields/float/float_field.js @@ -53,6 +53,7 @@ FloatField.props = { step: { type: Number, optional: true }, digits: { type: Array, optional: true }, invalidate: { type: Function, optional: true }, + placeholder: { type: String, optional: true }, }; FloatField.defaultProps = { inputType: "text", @@ -73,6 +74,7 @@ FloatField.extractProps = (fieldName, record, attrs) => { digits: (attrs.digits ? JSON.parse(attrs.digits) : attrs.options.digits) || record.fields[fieldName].digits, + placeholder: attrs.placeholder, }; }; diff --git a/addons/web/static/src/views/fields/float/float_field.xml b/addons/web/static/src/views/fields/float/float_field.xml index 4b5739405eb..6d424f2d55e 100644 --- a/addons/web/static/src/views/fields/float/float_field.xml +++ b/addons/web/static/src/views/fields/float/float_field.xml @@ -3,7 +3,7 @@ - + diff --git a/addons/web/static/src/views/fields/float_time/float_time_field.js b/addons/web/static/src/views/fields/float_time/float_time_field.js index 5f7377de69a..bdd517b0810 100644 --- a/addons/web/static/src/views/fields/float_time/float_time_field.js +++ b/addons/web/static/src/views/fields/float_time/float_time_field.js @@ -29,6 +29,7 @@ FloatTimeField.template = "web.FloatTimeField"; FloatTimeField.props = { ...standardFieldProps, invalidate: { type: Function, optional: true }, + placeholder: { type: String, optional: true }, }; FloatTimeField.defaultProps = { invalidate: () => {}, @@ -38,9 +39,10 @@ FloatTimeField.displayName = _lt("Time"); FloatTimeField.supportedTypes = ["float"]; FloatTimeField.isEmpty = () => false; -FloatTimeField.extractProps = (fieldName, record) => { +FloatTimeField.extractProps = (fieldName, record, attrs) => { return { invalidate: () => record.setInvalidField(fieldName), + placeholder: attrs.placeholder, }; }; diff --git a/addons/web/static/src/views/fields/float_time/float_time_field.xml b/addons/web/static/src/views/fields/float_time/float_time_field.xml index ee0425821b2..eee4e55bd5d 100644 --- a/addons/web/static/src/views/fields/float_time/float_time_field.xml +++ b/addons/web/static/src/views/fields/float_time/float_time_field.xml @@ -3,7 +3,7 @@ - + diff --git a/addons/web/static/src/views/fields/percentage/percentage_field.js b/addons/web/static/src/views/fields/percentage/percentage_field.js index 01998ad62f9..798ae0a025b 100644 --- a/addons/web/static/src/views/fields/percentage/percentage_field.js +++ b/addons/web/static/src/views/fields/percentage/percentage_field.js @@ -32,6 +32,7 @@ PercentageField.props = { ...standardFieldProps, invalidate: { type: Function, optional: true }, digits: { type: Array, optional: true }, + placeholder: { type: String, optional: true }, }; PercentageField.defaultProps = { invalidate: () => {}, @@ -46,6 +47,7 @@ PercentageField.extractProps = (fieldName, record, attrs) => { digits: (attrs.digits ? JSON.parse(attrs.digits) : attrs.options.digits) || record.fields[fieldName].digits, + placeholder: attrs.placeholder, }; }; diff --git a/addons/web/static/src/views/fields/percentage/percentage_field.xml b/addons/web/static/src/views/fields/percentage/percentage_field.xml index 412075a8b30..eb275d200d4 100644 --- a/addons/web/static/src/views/fields/percentage/percentage_field.xml +++ b/addons/web/static/src/views/fields/percentage/percentage_field.xml @@ -10,6 +10,7 @@ diff --git a/addons/web/static/tests/views/fields/char_field_tests.js b/addons/web/static/tests/views/fields/char_field_tests.js index 8ac4b4f9e42..5291e664384 100644 --- a/addons/web/static/tests/views/fields/char_field_tests.js +++ b/addons/web/static/tests/views/fields/char_field_tests.js @@ -1015,4 +1015,27 @@ QUnit.module("Fields", (hooks) => { ); } ); + + QUnit.test("char field with placeholder", async function (assert) { + serverData.models.partner.fields.foo.default = false; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + + +
`, + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='foo'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/email_field_tests.js b/addons/web/static/tests/views/fields/email_field_tests.js index ad8dcdb02d3..13d588a5633 100644 --- a/addons/web/static/tests/views/fields/email_field_tests.js +++ b/addons/web/static/tests/views/fields/email_field_tests.js @@ -163,11 +163,12 @@ QUnit.module("Fields", (hooks) => {
- +
`, }); + assert.strictEqual(target.querySelector(".o_field_email input").placeholder, "Placeholder"); await click(target.querySelector(".o_form_button_save")); const mailtoLink = target.querySelector(".o_field_email a"); @@ -239,4 +240,27 @@ QUnit.module("Fields", (hooks) => { ); } ); + + QUnit.test("email field with placeholder", async function (assert) { + serverData.models.partner.fields.foo.default = false; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + + +
`, + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='foo'] input").placeholder, + "New Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/float_field_tests.js b/addons/web/static/tests/views/fields/float_field_tests.js index f0eb5a3e06e..fdd46a67990 100644 --- a/addons/web/static/tests/views/fields/float_field_tests.js +++ b/addons/web/static/tests/views/fields/float_field_tests.js @@ -1,9 +1,9 @@ /** @odoo-module **/ -import { registry } from "@web/core/registry"; import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services"; -import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; +import { click, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; +import { registry } from "@web/core/registry"; let serverData; let target; @@ -447,4 +447,21 @@ QUnit.module("Fields", (hooks) => { "Float value must be formatted if input type isn't number." ); }); + + QUnit.test("float_field field with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: '
', + }); + + const input = target.querySelector(".o_field_widget[name='float_field'] input"); + input.value = ""; + await triggerEvent(input, null, "input"); + assert.strictEqual( + target.querySelector(".o_field_widget[name='float_field'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/float_time_field_tests.js b/addons/web/static/tests/views/fields/float_time_field_tests.js index dae0322b3da..e8aada0d09d 100644 --- a/addons/web/static/tests/views/fields/float_time_field_tests.js +++ b/addons/web/static/tests/views/fields/float_time_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; +import { click, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -164,4 +164,24 @@ QUnit.module("Fields", (hooks) => { "date field should not be displayed as invalid now" ); }); + + QUnit.test("float_time field with placeholder", async function (assert) { + await makeView({ + serverData, + type: "form", + resModel: "partner", + arch: ` +
+ + `, + }); + + const input = target.querySelector(".o_field_widget[name='qux'] input"); + input.value = ""; + await triggerEvent(input, null, "input"); + assert.strictEqual( + target.querySelector(".o_field_widget[name='qux'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/font_selection_field_tests.js b/addons/web/static/tests/views/fields/font_selection_field_tests.js index 00aa4b532de..79296eebcda 100644 --- a/addons/web/static/tests/views/fields/font_selection_field_tests.js +++ b/addons/web/static/tests/views/fields/font_selection_field_tests.js @@ -36,7 +36,7 @@ QUnit.module("Fields", (hooks) => { serverData, type: "form", resModel: "partner", - arch: '
', + arch: '
', }); const options = target.querySelectorAll('.o_field_widget[name="fonts"] option'); @@ -46,6 +46,12 @@ QUnit.module("Fields", (hooks) => { "Widget font should be default (Lato)" ); assert.strictEqual(options[0].value, "false", "Unselected option has no value"); + assert.strictEqual( + options[0].textContent, + "Placeholder", + "Unselected option is the placeholder" + ); + assert.strictEqual( options[1].style.fontFamily, "Lato", diff --git a/addons/web/static/tests/views/fields/integer_field_tests.js b/addons/web/static/tests/views/fields/integer_field_tests.js index 69e2abb2149..c6001131d7a 100644 --- a/addons/web/static/tests/views/fields/integer_field_tests.js +++ b/addons/web/static/tests/views/fields/integer_field_tests.js @@ -2,7 +2,13 @@ import { localization } from "@web/core/l10n/localization"; import { defaultLocalization } from "@web/../tests/helpers/mock_services"; -import { click, editInput, getFixture, patchWithCleanup } from "@web/../tests/helpers/utils"; +import { + click, + editInput, + getFixture, + patchWithCleanup, + triggerEvent, +} from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -299,4 +305,21 @@ QUnit.module("Fields", (hooks) => { "The new value should be saved and displayed properly." ); }); + + QUnit.test("IntegerField field with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: `
`, + }); + + const input = target.querySelector(".o_field_widget[name='int_field'] input"); + input.value = ""; + await triggerEvent(input, null, "input"); + assert.strictEqual( + target.querySelector(".o_field_widget[name='int_field'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/many2many_tags_field_tests.js b/addons/web/static/tests/views/fields/many2many_tags_field_tests.js index 28d922be56a..dc128a7bf6d 100644 --- a/addons/web/static/tests/views/fields/many2many_tags_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_tags_field_tests.js @@ -1525,4 +1525,19 @@ QUnit.module("Fields", (hooks) => { ); assert.containsOnce(row, ".o-autocomplete--input"); }); + + QUnit.test("Many2ManyTagsField with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: + '
', + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='timmy'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js b/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js index 57eab4a0de8..2b50d291e06 100644 --- a/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js +++ b/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js @@ -224,4 +224,19 @@ QUnit.module("Fields", (hooks) => { "/web/image/user/17/avatar_128" ); }); + + QUnit.test("Many2OneAvatar with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: + '
', + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='user_id'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/many2one_field_tests.js b/addons/web/static/tests/views/fields/many2one_field_tests.js index eda9e043815..ad2493a15e7 100644 --- a/addons/web/static/tests/views/fields/many2one_field_tests.js +++ b/addons/web/static/tests/views/fields/many2one_field_tests.js @@ -4034,4 +4034,18 @@ QUnit.module("Fields", (hooks) => { "Should contain 2 breadcrumbs after the clicking on the link" ); }); + + QUnit.test("Many2oneField with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: '
', + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='trululu'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/monetary_field_tests.js b/addons/web/static/tests/views/fields/monetary_field_tests.js index 626fa70e415..9e9aeb4c557 100644 --- a/addons/web/static/tests/views/fields/monetary_field_tests.js +++ b/addons/web/static/tests/views/fields/monetary_field_tests.js @@ -9,6 +9,7 @@ import { editInput, getFixture, patchWithCleanup, + triggerEvent, } from "@web/../tests/helpers/utils"; import { session } from "@web/session"; @@ -1112,4 +1113,25 @@ QUnit.module("Fields", (hooks) => { "The currency symbol is not displayed" ); }); + + QUnit.test("monetary field with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + `, + }); + + const input = target.querySelector(".o_field_widget[name='float_field'] input"); + input.value = ""; + await triggerEvent(input, null, "input"); + assert.strictEqual( + target.querySelector(".o_field_widget[name='float_field'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/percentage_field_tests.js b/addons/web/static/tests/views/fields/percentage_field_tests.js index 15d8d3f5ede..be247ae8ea0 100644 --- a/addons/web/static/tests/views/fields/percentage_field_tests.js +++ b/addons/web/static/tests/views/fields/percentage_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; +import { click, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -77,4 +77,24 @@ QUnit.module("Fields", (hooks) => { "The new value should be formatted properly." ); }); + + QUnit.test("percentage field with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + `, + }); + + const input = target.querySelector(".o_field_widget[name='float_field'] input"); + input.value = ""; + await triggerEvent(input, null, "input"); + assert.strictEqual( + target.querySelector(".o_field_widget[name='float_field'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/phone_field_tests.js b/addons/web/static/tests/views/fields/phone_field_tests.js index a62de608ddc..351107b3e84 100644 --- a/addons/web/static/tests/views/fields/phone_field_tests.js +++ b/addons/web/static/tests/views/fields/phone_field_tests.js @@ -162,4 +162,27 @@ QUnit.module("Fields", (hooks) => { "foo should be focused" ); }); + + QUnit.test("phone field with placeholder", async function (assert) { + serverData.models.partner.fields.foo.default = false; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + + +
`, + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='foo'] input").placeholder, + "Placeholder" + ); + }); }); diff --git a/addons/web/static/tests/views/fields/selection_field_tests.js b/addons/web/static/tests/views/fields/selection_field_tests.js index 7ee429a9330..9d5c586d1ab 100644 --- a/addons/web/static/tests/views/fields/selection_field_tests.js +++ b/addons/web/static/tests/views/fields/selection_field_tests.js @@ -395,4 +395,22 @@ QUnit.module("Fields", (hooks) => { "Two options in second selection as it is now required" ); }); + + QUnit.test("selection field with placeholder", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + `, + }); + + const placeholderOption = target.querySelector( + ".o_field_widget[name='trululu'] select option" + ); + assert.strictEqual(placeholderOption.textContent, "Placeholder"); + assert.strictEqual(placeholderOption.value, "false"); + }); }); diff --git a/addons/web/static/tests/views/fields/url_field_tests.js b/addons/web/static/tests/views/fields/url_field_tests.js index 94593192269..45f47e8bc3d 100644 --- a/addons/web/static/tests/views/fields/url_field_tests.js +++ b/addons/web/static/tests/views/fields/url_field_tests.js @@ -296,4 +296,27 @@ QUnit.module("Fields", (hooks) => { target.querySelector(".o_field_widget[name=foo]").textContent ); }); + + QUnit.test("url field with placeholder", async function (assert) { + serverData.models.partner.fields.foo.default = false; + + await makeView({ + type: "form", + resModel: "partner", + serverData, + arch: ` +
+ + + + + +
`, + }); + + assert.strictEqual( + target.querySelector(".o_field_widget[name='foo'] input").placeholder, + "Placeholder" + ); + }); });