[FIX] web: placeholder in required SelectionField

This commit adds the possibility of having a placeholder in a
required SelectionField.

Solution:
We always add a false option with the placeholder but it is "display:none"
if the field is required.

How to reproduce:
- create a new record in a form view with a required selection field

Result before:
    The first option of the selection field will be selected

Result after:
    The placeholder of the selection field will be selected

When editing the selection field, the selection field does not propose
the placeholder.

closes odoo/odoo#98823

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
FrancoisGe
2022-08-25 09:06:30 +02:00
parent ff6f8b29e3
commit 15a032e84a
5 changed files with 42 additions and 43 deletions
@@ -9,13 +9,9 @@ const { Component } = owl;
export class FontSelectionField extends Component {
get options() {
const options = this.props.record.fields[this.props.name].selection.filter(
return this.props.record.fields[this.props.name].selection.filter(
(option) => option[0] !== false && option[1] !== ""
);
if (!this.isRequired) {
options.unshift([false, this.props.placeholder || ""]);
}
return options;
}
get isRequired() {
return this.props.record.isRequired(this.props.name);
@@ -7,6 +7,12 @@
</t>
<t t-else="">
<select class="o_input" t-on-change="onChange" t-attf-style="font-family:{{ props.value }};">
<option
t-att-selected="false === value"
t-att-value="stringify(false)"
t-esc="this.props.placeholder || ''"
t-attf-style="{{ isRequired ? 'display:none' : '' }}"
/>
<t t-foreach="options" t-as="option" t-key="option[0]">
<option
t-att-selected="option[0] === value"
@@ -8,21 +8,16 @@ const { Component } = owl;
export class SelectionField extends Component {
get options() {
let options;
switch (this.props.record.fields[this.props.name].type) {
case "many2one":
options = [...this.props.record.preloadedData[this.props.name]];
break;
return [...this.props.record.preloadedData[this.props.name]];
case "selection":
options = this.props.record.fields[this.props.name].selection.filter(
return this.props.record.fields[this.props.name].selection.filter(
(option) => option[0] !== false && option[1] !== ""
);
break;
default:
return [];
}
if (!this.isRequired) {
options.unshift([false, this.props.placeholder || ""]);
}
return options;
}
get string() {
switch (this.props.type) {
@@ -7,6 +7,12 @@
</t>
<t t-else="">
<select class="o_input" t-on-change="onChange">
<option
t-att-selected="false === value"
t-att-value="stringify(false)"
t-esc="this.props.placeholder || ''"
t-attf-style="{{ isRequired ? 'display:none' : '' }}"
/>
<t t-foreach="options" t-as="option" t-key="option[0]">
<option
t-att-selected="option[0] === value"
@@ -371,28 +371,26 @@ QUnit.module("Fields", (hooks) => {
});
await click(target, ".o_form_button_edit");
assert.containsN(
target.querySelector(".o_field_widget[name='color']"),
"option",
3,
"Three options in non required field"
assert.deepEqual(
[...target.querySelectorAll(".o_field_widget[name='color'] option")].map(
(option) => option.style.display
),
["", "", ""]
);
assert.containsN(
target.querySelector(".o_field_widget[name='feedback_value']"),
"option",
2,
"Two options in required field"
assert.deepEqual(
[...target.querySelectorAll(".o_field_widget[name='feedback_value'] option")].map(
(option) => option.style.display
),
["none", "", ""]
);
// change value to update widget modifier values
await editSelect(target, ".o_field_widget[name='feedback_value'] select", '"bad"');
assert.containsN(
target.querySelector(".o_field_widget[name='color']"),
"option",
2,
"Two options in second selection as it is now required"
assert.deepEqual(
[...target.querySelectorAll(".o_field_widget[name='color'] option")].map(
(option) => option.style.display
),
["none", "", ""]
);
});
@@ -427,22 +425,20 @@ QUnit.module("Fields", (hooks) => {
});
await click(target, ".o_form_button_edit");
assert.containsN(
target.querySelector(".o_field_widget[name='color']"),
"option",
3,
"Three options in non required field (one blank option)"
assert.deepEqual(
[...target.querySelectorAll(".o_field_widget[name='color'] option")].map(
(option) => option.style.display
),
["", "", ""]
);
// change value to update widget modifier values
await editSelect(target, ".o_field_widget[name='feedback_value'] select", '"bad"');
assert.containsN(
target.querySelector(".o_field_widget[name='color']"),
"option",
2,
"Still three options in required selection (one blank option)"
assert.deepEqual(
[...target.querySelectorAll(".o_field_widget[name='color'] option")].map(
(option) => option.style.display
),
["none", "", ""]
);
}
);