Skip to content

Commit

Permalink
feat: add form support for ui5-select (#565)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
vladitasev authored Jun 20, 2019
1 parent 2d94b60 commit 89e3508
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 27 deletions.
2 changes: 2 additions & 0 deletions docs/PublicModuleImports.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ For API documentation and samples, please check the [UI5 Web Components Playgrou
| Popover | `ui5-popover` | `import "@ui5/webcomponents/dist/Popover.js";` |
| Radio Button | `ui5-radiobutton` | `import "@ui5/webcomponents/dist/RadioButton.js";` |
| Select | `ui5-select` | `import "@ui5/webcomponents/dist/Select.js";` |
| Select Option | `ui5-option` | comes with ui5-select |
| Shell Bar (Fiori 3) | `ui5-shellbar` | `import "@ui5/webcomponents/dist/ShellBar.js";` |
| Shell Bar Item | `ui5-shellbar-item` | `import "@ui5/webcomponents/dist/ShellBarItem.js";` |
| Switch | `ui5-switch` | `import "@ui5/webcomponents/dist/Switch.js";` |
Expand Down Expand Up @@ -224,6 +225,7 @@ If you however need to submit forms, you can import the module above and it will
- ui5-checkbox
- ui5-radiobutton
- ui5-datepicker
- ui5-select

with functionality, allowing them to be submitted in forms (provided you set their <code>name</code> attribute) just as
any standard HTML input element would be.
Expand Down
1 change: 0 additions & 1 deletion packages/main/bundle.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import Popover from "./dist/Popover.js";
import Panel from "./dist/Panel.js";
import RadioButton from "./dist/RadioButton.js";
import Select from "./dist/Select.js";
import Option from "./dist/Option.js";
import ShellBar from "./dist/ShellBar.js";
import ShellBarItem from "./dist/ShellBarItem.js";
import Switch from "./dist/Switch.js";
Expand Down
4 changes: 2 additions & 2 deletions packages/main/src/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const metadata = {
* automatically submit the nearest form element upon <code>press</code>.
*
* <b>Important:</b> For the <code>submits</code> property to have effect, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* @type {boolean}
* @defaultvalue false
Expand Down Expand Up @@ -198,7 +198,7 @@ class Button extends UI5Element {
onBeforeRendering() {
const FormSupport = getFeature("FormSupport");
if (this.submits && !FormSupport) {
console.warn(`In order for the "submits" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
console.warn(`In order for the "submits" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/main/src/CheckBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const metadata = {
* Determines the name with which the <code>ui5-checkbox</code> will be submitted in an HTML form.
*
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* <b>Note:</b> When set, a native <code>input</code> HTML element
* will be created inside the <code>ui5-checkbox</code> so that it can be submitted as
Expand Down Expand Up @@ -214,7 +214,7 @@ class CheckBox extends UI5Element {
nativeInput.value = element.checked ? "on" : "";
});
} else if (this.name) {
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/main/src/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const metadata = {
* Determines the name with which the <code>ui5-datepicker</code> will be submitted in an HTML form.
*
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* <b>Note:</b> When set, a native <code>input</code> HTML element
* will be created inside the <code>ui5-datepicker</code> so that it can be submitted as
Expand Down Expand Up @@ -313,7 +313,7 @@ class DatePicker extends UI5Element {
if (FormSupport) {
FormSupport.syncNativeHiddenInput(this);
} else if (this.name) {
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/main/src/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const metadata = {
* Determines the name with which the <code>ui5-input</code> will be submitted in an HTML form.
*
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* <b>Note:</b> When set, a native <code>input</code> HTML element
* will be created inside the <code>ui5-input</code> so that it can be submitted as
Expand Down Expand Up @@ -329,7 +329,7 @@ class Input extends UI5Element {
if (FormSupport) {
FormSupport.syncNativeHiddenInput(this);
} else if (this.name) {
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

Expand Down
11 changes: 11 additions & 0 deletions packages/main/src/Option.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ const metadata = {
type: String,
defaultValue: null,
},

/**
* Defines the value of the <code>ui5-select</code> inside an HTML Form element when this <code>ui5-option</code> is selected.
* For more information on HTML Form support, see the <code>name</code> property of <code>ui5-select</code>.
*
* @type {string}
* @public
*/
value: {
type: String,
},
},

events: /** @lends sap.ui.webcomponents.main.Option.prototype */ {},
Expand Down
6 changes: 3 additions & 3 deletions packages/main/src/RadioButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const metadata = {
* Only one radio button can be selected per group.
* <br/>
* <b>Important:</b> For the <code>name</code> property to have effect when submitting forms, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* <b>Note:</b> When set, a native <code>input</code> HTML element
* will be created inside the <code>ui5-radiobutton</code> so that it can be submitted as
Expand All @@ -126,7 +126,7 @@ const metadata = {
* will be the value of the currently selected radio button.
* <br/>
* <b>Important:</b> For the <code>value</code> property to have effect, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* @type {string}
* @defaultvalue: ""
Expand Down Expand Up @@ -263,7 +263,7 @@ class RadioButton extends UI5Element {
nativeInput.value = element.selected ? element.value : "";
});
} else if (this.value) {
console.warn(`In order for the "value" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
console.warn(`In order for the "value" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/main/src/Select.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@
class="sapWCSelectDropDownIcon"
@ui5-press="{{_togglePopover}}"
></ui5-icon>

<slot name="formSupport"></slot>
</div>
51 changes: 43 additions & 8 deletions packages/main/src/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import {
isShow,
} from "@ui5/webcomponents-base/src/events/PseudoEvents.js";
import { getCompactSize } from "@ui5/webcomponents-base/src/Configuration.js";
import { getFeature } from "@ui5/webcomponents-base/src/FeaturesRegistry.js";
import getEffectiveRTL from "@ui5/webcomponents-base/src/util/getEffectiveRTL.js";
import ValueState from "@ui5/webcomponents-base/src/types/ValueState.js";
import Option from "./Option.js";
import Label from "./Label.js";
import Popover from "./Popover.js";
import List from "./List.js";
Expand All @@ -33,18 +35,18 @@ const metadata = {
slots: /** @lends sap.ui.webcomponents.main.Select.prototype */ {

/**
* Defines the <code>ui5-select</code> items.
* Defines the <code>ui5-select</code> options.
* <br/><br/>
* <b>Note:</b> Only one selected item is allowed.
* If more than one item is defined as selected, the last one would be considered as the selected one.
* <b>Note:</b> Only one selected option is allowed.
* If more than one option is defined as selected, the last one would be considered as the selected one.
* <br/><br/>
* <b>Note:</b> Use the <code>ui5-option</code> component to define the desired options.
* @type {HTMLElement[]}
* @type {Option[]}
* @slot
* @public
*/
options: {
type: HTMLElement,
type: Option,
multiple: true,
listenFor: { include: ["*"] },
},
Expand All @@ -64,6 +66,25 @@ const metadata = {
type: Boolean,
},

/**
* Determines the name with which the <code>ui5-select</code> will be submitted in an HTML form.
* The value of the <code>ui5-select</code> will be the value of the currently selected <code>ui5-option</code>.
*
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* <b>Note:</b> When set, a native <code>input</code> HTML element
* will be created inside the <code>ui5-select</code> so that it can be submitted as
* part of an HTML form. Do not use this property unless you need to submit a form.
*
* @type {string}
* @defaultvalue ""
* @public
*/
name: {
type: String,
},

/**
* Defines the value state of <code>ui5-select</code>.
* Available options are: <code>None</code>, <code>Success</code>, <code>Warning</code> and <code>Error</code>.
Expand Down Expand Up @@ -99,7 +120,7 @@ const metadata = {
*/
change: {
detail: {
selectedItem: {},
selectedOption: {},
},
},
},
Expand Down Expand Up @@ -160,6 +181,7 @@ class Select extends UI5Element {

onBeforeRendering() {
this._syncSelection();
this._enableFormSupport();
}

get _isPickerOpen() {
Expand Down Expand Up @@ -220,6 +242,18 @@ class Select extends UI5Element {
this._syncedOptions = opts;
}

_enableFormSupport() {
const FormSupport = getFeature("FormSupport");
if (FormSupport) {
FormSupport.syncNativeHiddenInput(this, (element, nativeInput) => {
nativeInput.disabled = element.disabled;
nativeInput.value = element.selectedOption.value;
});
} else if (this.name) {
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

_keydown(event) {
if (isShow(event)) {
this._togglePopover();
Expand Down Expand Up @@ -285,7 +319,7 @@ class Select extends UI5Element {
this._selectedIndex = nextIndex === -1 ? this._selectedIndex : nextIndex;

if (shouldFireEvent) {
this.fireEvent("change", { selectedItem: this.options[nextIndex] });
this.fireEvent("change", { selectedOption: this.options[nextIndex] });
}
}

Expand Down Expand Up @@ -316,7 +350,7 @@ class Select extends UI5Element {
this._select(this._selectedIndexBeforeOpen);
this._escapePressed = false;
} else if (this._lastSelectedOption !== this.options[this._selectedIndex]) {
this.fireEvent("change", { selectedItem: this.options[this._selectedIndex] });
this.fireEvent("change", { selectedOption: this.options[this._selectedIndex] });
this._lastSelectedOption = this.options[this._selectedIndex];
}
}
Expand Down Expand Up @@ -353,6 +387,7 @@ class Select extends UI5Element {

static async define(...params) {
await Promise.all([
Option.define(),
Label.define(),
Popover.define(),
List.define(),
Expand Down
4 changes: 2 additions & 2 deletions packages/main/src/TextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const metadata = {
* Determines the name with which the <code>ui5-textarea</code> will be submitted in an HTML form.
*
* <b>Important:</b> For the <code>name</code> property to have effect, you must add the following import to your project:
* <code>import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";</code>
* <code>import "@ui5/webcomponents/dist/InputElementsFormSupport.js";</code>
*
* <b>Note:</b> When set, a native <code>input</code> HTML element
* will be created inside the <code>ui5-textarea</code> so that it can be submitted as
Expand Down Expand Up @@ -256,7 +256,7 @@ class TextArea extends UI5Element {
if (FormSupport) {
FormSupport.syncNativeHiddenInput(this);
} else if (this.name) {
console.warn(`In order for the "name" property to have effect, you should also: import InputElementsFormSupport from "@ui5/webcomponents/dist/InputElementsFormSupport";`); // eslint-disable-line
console.warn(`In order for the "name" property to have effect, you should also: import "@ui5/webcomponents/dist/InputElementsFormSupport.js";`); // eslint-disable-line
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ <h2> Change event counter holder</h2>

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

Expand Down
8 changes: 4 additions & 4 deletions packages/main/test/sap/ui/webcomponents/main/pages/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ <h3> Input type 'URL'</h3>

<br>
<ui5-select name="sel2">
<ui5-option selected>Cozy</ui5-option>
<ui5-option selected>Compact</ui5-option>
<ui5-option selected>Condensed</ui5-option>
<ui5-option value="czy">Cozy</ui5-option>
<ui5-option value="cmp" selected>Compact</ui5-option>
<ui5-option value="cnd">Condensed</ui5-option>
</ui5-select>

<br />
Expand Down Expand Up @@ -106,4 +106,4 @@ <h3> Input type 'URL'</h3>

</body>

</html>
</html>

0 comments on commit 89e3508

Please sign in to comment.