Skip to content

Commit 89e3508

Browse files
authored
feat: add form support for ui5-select (#565)
ui5-select gets "name" attribute, ui5-option gets "value" attribute BREAKING CHANGE: the parameter of the change event is now called "selectedOption"; ui5-select enforces ui5-option as children in the metadata
1 parent 2d94b60 commit 89e3508

File tree

13 files changed

+76
-27
lines changed

13 files changed

+76
-27
lines changed

docs/PublicModuleImports.md

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ For API documentation and samples, please check the [UI5 Web Components Playgrou
2929
| Popover | `ui5-popover` | `import "@ui5/webcomponents/dist/Popover.js";` |
3030
| Radio Button | `ui5-radiobutton` | `import "@ui5/webcomponents/dist/RadioButton.js";` |
3131
| Select | `ui5-select` | `import "@ui5/webcomponents/dist/Select.js";` |
32+
| Select Option | `ui5-option` | comes with ui5-select |
3233
| Shell Bar (Fiori 3) | `ui5-shellbar` | `import "@ui5/webcomponents/dist/ShellBar.js";` |
3334
| Shell Bar Item | `ui5-shellbar-item` | `import "@ui5/webcomponents/dist/ShellBarItem.js";` |
3435
| Switch | `ui5-switch` | `import "@ui5/webcomponents/dist/Switch.js";` |
@@ -224,6 +225,7 @@ If you however need to submit forms, you can import the module above and it will
224225
- ui5-checkbox
225226
- ui5-radiobutton
226227
- ui5-datepicker
228+
- ui5-select
227229

228230
with functionality, allowing them to be submitted in forms (provided you set their <code>name</code> attribute) just as
229231
any standard HTML input element would be.

packages/main/bundle.esm.js

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import Popover from "./dist/Popover.js";
2626
import Panel from "./dist/Panel.js";
2727
import RadioButton from "./dist/RadioButton.js";
2828
import Select from "./dist/Select.js";
29-
import Option from "./dist/Option.js";
3029
import ShellBar from "./dist/ShellBar.js";
3130
import ShellBarItem from "./dist/ShellBarItem.js";
3231
import Switch from "./dist/Switch.js";

packages/main/src/Button.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const metadata = {
8282
* automatically submit the nearest form element upon <code>press</code>.
8383
*
8484
* <b>Important:</b> For the <code>submits</code> property to have effect, you must add the following import to your project:
85-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
85+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
8686
*
8787
* @type {boolean}
8888
* @defaultvalue false
@@ -198,7 +198,7 @@ class Button extends UI5Element {
198198
onBeforeRendering() {
199199
const FormSupport = getFeature("FormSupport");
200200
if (this.submits && !FormSupport) {
201-
console.warn(`In order for the "submits" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
201+
console.warn(`In order for the "submits" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
202202
}
203203
}
204204

packages/main/src/CheckBox.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ const metadata = {
104104
* Determines the name with which the <code>ui5-checkbox</code> will be submitted in an HTML form.
105105
*
106106
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
107-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
107+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
108108
*
109109
* <b>Note:</b> When set, a native <code>input</code> HTML element
110110
* will be created inside the <code>ui5-checkbox</code> so that it can be submitted as
@@ -214,7 +214,7 @@ class CheckBox extends UI5Element {
214214
nativeInput.value = element.checked ? "on" : "";
215215
});
216216
} else if (this.name) {
217-
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
217+
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
218218
}
219219
}
220220

packages/main/src/DatePicker.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ const metadata = {
122122
* Determines the name with which the <code>ui5-datepicker</code> will be submitted in an HTML form.
123123
*
124124
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
125-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
125+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
126126
*
127127
* <b>Note:</b> When set, a native <code>input</code> HTML element
128128
* will be created inside the <code>ui5-datepicker</code> so that it can be submitted as
@@ -313,7 +313,7 @@ class DatePicker extends UI5Element {
313313
if (FormSupport) {
314314
FormSupport.syncNativeHiddenInput(this);
315315
} else if (this.name) {
316-
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
316+
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
317317
}
318318
}
319319

packages/main/src/Input.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ const metadata = {
159159
* Determines the name with which the <code>ui5-input</code> will be submitted in an HTML form.
160160
*
161161
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
162-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
162+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
163163
*
164164
* <b>Note:</b> When set, a native <code>input</code> HTML element
165165
* will be created inside the <code>ui5-input</code> so that it can be submitted as
@@ -329,7 +329,7 @@ class Input extends UI5Element {
329329
if (FormSupport) {
330330
FormSupport.syncNativeHiddenInput(this);
331331
} else if (this.name) {
332-
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
332+
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
333333
}
334334
}
335335

packages/main/src/Option.js

+11
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ const metadata = {
3333
type: String,
3434
defaultValue: null,
3535
},
36+
37+
/**
38+
* Defines the value of the <code>ui5-select</code> inside an HTML Form element when this <code>ui5-option</code> is selected.
39+
* For more information on HTML Form support, see the <code>name</code> property of <code>ui5-select</code>.
40+
*
41+
* @type {string}
42+
* @public
43+
*/
44+
value: {
45+
type: String,
46+
},
3647
},
3748

3849
events: /** @lends sap.ui.webcomponents.main.Option.prototype */ {},

packages/main/src/RadioButton.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const metadata = {
106106
* Only one radio button can be selected per group.
107107
* <br/>
108108
* <b>Important:</b> For the <code>name</code> property to have effect when submitting forms, you must add the following import to your project:
109-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
109+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
110110
*
111111
* <b>Note:</b> When set, a native <code>input</code> HTML element
112112
* will be created inside the <code>ui5-radiobutton</code> so that it can be submitted as
@@ -126,7 +126,7 @@ const metadata = {
126126
* will be the value of the currently selected radio button.
127127
* <br/>
128128
* <b>Important:</b> For the <code>value</code> property to have effect, you must add the following import to your project:
129-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
129+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
130130
*
131131
* @type {string}
132132
* @defaultvalue: ""
@@ -263,7 +263,7 @@ class RadioButton extends UI5Element {
263263
nativeInput.value = element.selected ? element.value : "";
264264
});
265265
} else if (this.value) {
266-
console.warn(`In order for the "value" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
266+
console.warn(`In order for the "value" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
267267
}
268268
}
269269

packages/main/src/Select.hbs

+2
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@
3737
class="sapWCSelectDropDownIcon"
3838
@ui5-press="{{_togglePopover}}"
3939
></ui5-icon>
40+
41+
<slot name="formSupport"></slot>
4042
</div>

packages/main/src/Select.js

+43-8
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import {
1010
isShow,
1111
} from "@ui5/webcomponents-base/src/events/PseudoEvents.js";
1212
import { getCompactSize } from "@ui5/webcomponents-base/src/Configuration.js";
13+
import { getFeature } from "@ui5/webcomponents-base/src/FeaturesRegistry.js";
1314
import getEffectiveRTL from "@ui5/webcomponents-base/src/util/getEffectiveRTL.js";
1415
import ValueState from "@ui5/webcomponents-base/src/types/ValueState.js";
16+
import Option from "./Option.js";
1517
import Label from "./Label.js";
1618
import Popover from "./Popover.js";
1719
import List from "./List.js";
@@ -33,18 +35,18 @@ const metadata = {
3335
slots: /** @lends sap.ui.webcomponents.main.Select.prototype */ {
3436

3537
/**
36-
* Defines the <code>ui5-select</code> items.
38+
* Defines the <code>ui5-select</code> options.
3739
* <br/><br/>
38-
* <b>Note:</b> Only one selected item is allowed.
39-
* If more than one item is defined as selected, the last one would be considered as the selected one.
40+
* <b>Note:</b> Only one selected option is allowed.
41+
* If more than one option is defined as selected, the last one would be considered as the selected one.
4042
* <br/><br/>
4143
* <b>Note:</b> Use the <code>ui5-option</code> component to define the desired options.
42-
* @type {HTMLElement[]}
44+
* @type {Option[]}
4345
* @slot
4446
* @public
4547
*/
4648
options: {
47-
type: HTMLElement,
49+
type: Option,
4850
multiple: true,
4951
listenFor: { include: ["*"] },
5052
},
@@ -64,6 +66,25 @@ const metadata = {
6466
type: Boolean,
6567
},
6668

69+
/**
70+
* Determines the name with which the <code>ui5-select</code> will be submitted in an HTML form.
71+
* The value of the <code>ui5-select</code> will be the value of the currently selected <code>ui5-option</code>.
72+
*
73+
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
74+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
75+
*
76+
* <b>Note:</b> When set, a native <code>input</code> HTML element
77+
* will be created inside the <code>ui5-select</code> so that it can be submitted as
78+
* part of an HTML form. Do not use this property unless you need to submit a form.
79+
*
80+
* @type {string}
81+
* @defaultvalue ""
82+
* @public
83+
*/
84+
name: {
85+
type: String,
86+
},
87+
6788
/**
6889
* Defines the value state of <code>ui5-select</code>.
6990
* Available options are: <code>None</code>, <code>Success</code>, <code>Warning</code> and <code>Error</code>.
@@ -99,7 +120,7 @@ const metadata = {
99120
*/
100121
change: {
101122
detail: {
102-
selectedItem: {},
123+
selectedOption: {},
103124
},
104125
},
105126
},
@@ -160,6 +181,7 @@ class Select extends UI5Element {
160181

161182
onBeforeRendering() {
162183
this._syncSelection();
184+
this._enableFormSupport();
163185
}
164186

165187
get _isPickerOpen() {
@@ -220,6 +242,18 @@ class Select extends UI5Element {
220242
this._syncedOptions = opts;
221243
}
222244

245+
_enableFormSupport() {
246+
const FormSupport = getFeature("FormSupport");
247+
if (FormSupport) {
248+
FormSupport.syncNativeHiddenInput(this, (element, nativeInput) => {
249+
nativeInput.disabled = element.disabled;
250+
nativeInput.value = element.selectedOption.value;
251+
});
252+
} else if (this.name) {
253+
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
254+
}
255+
}
256+
223257
_keydown(event) {
224258
if (isShow(event)) {
225259
this._togglePopover();
@@ -285,7 +319,7 @@ class Select extends UI5Element {
285319
this._selectedIndex = nextIndex === -1 ? this._selectedIndex : nextIndex;
286320

287321
if (shouldFireEvent) {
288-
this.fireEvent("change", { selectedItem: this.options[nextIndex] });
322+
this.fireEvent("change", { selectedOption: this.options[nextIndex] });
289323
}
290324
}
291325

@@ -316,7 +350,7 @@ class Select extends UI5Element {
316350
this._select(this._selectedIndexBeforeOpen);
317351
this._escapePressed = false;
318352
} else if (this._lastSelectedOption !== this.options[this._selectedIndex]) {
319-
this.fireEvent("change", { selectedItem: this.options[this._selectedIndex] });
353+
this.fireEvent("change", { selectedOption: this.options[this._selectedIndex] });
320354
this._lastSelectedOption = this.options[this._selectedIndex];
321355
}
322356
}
@@ -353,6 +387,7 @@ class Select extends UI5Element {
353387

354388
static async define(...params) {
355389
await Promise.all([
390+
Option.define(),
356391
Label.define(),
357392
Popover.define(),
358393
List.define(),

packages/main/src/TextArea.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ const metadata = {
142142
* Determines the name with which the <code>ui5-textarea</code> will be submitted in an HTML form.
143143
*
144144
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
145-
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
145+
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
146146
*
147147
* <b>Note:</b> When set, a native <code>input</code> HTML element
148148
* will be created inside the <code>ui5-textarea</code> so that it can be submitted as
@@ -256,7 +256,7 @@ class TextArea extends UI5Element {
256256
if (FormSupport) {
257257
FormSupport.syncNativeHiddenInput(this);
258258
} else if (this.name) {
259-
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
259+
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
260260
}
261261
}
262262

packages/main/test/sap/ui/webcomponents/main/pages/Select.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ <h2> Change event counter holder</h2>
6565

6666
// Select
6767
select.addEventListener("ui5-change", function(e) {
68-
lbl.innerHTML = "selected item :: " + e.detail.selectedItem.textContent + " :: " + (++counter);
68+
lbl.innerHTML = "selected item :: " + e.detail.selectedOption.textContent + " :: " + (++counter);
6969
inputResult.value = counter;
7070
});
7171

packages/main/test/sap/ui/webcomponents/main/pages/form.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ <h3> Input type 'URL'</h3>
5454

5555
<br>
5656
<ui5-select name="sel2">
57-
<ui5-option selected>Cozy</ui5-option>
58-
<ui5-option selected>Compact</ui5-option>
59-
<ui5-option selected>Condensed</ui5-option>
57+
<ui5-option value="czy">Cozy</ui5-option>
58+
<ui5-option value="cmp" selected>Compact</ui5-option>
59+
<ui5-option value="cnd">Condensed</ui5-option>
6060
</ui5-select>
6161

6262
<br />
@@ -106,4 +106,4 @@ <h3> Input type 'URL'</h3>
106106

107107
</body>
108108

109-
</html>
109+
</html>

0 commit comments

Comments
 (0)