From be081cc34144e2843f9255daea6c314b9e59b588 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 13 Jun 2019 13:38:06 +0300 Subject: [PATCH 1/6] feat(ui5-textarea): implement input event --- packages/main/src/TextArea.hbs | 1 + packages/main/src/TextArea.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/main/src/TextArea.hbs b/packages/main/src/TextArea.hbs index d387fa98a8d4..de6f785900a2 100644 --- a/packages/main/src/TextArea.hbs +++ b/packages/main/src/TextArea.hbs @@ -25,6 +25,7 @@ ?readonly="{{readonly}}" maxlength="{{_exceededTextProps.calcedMaxLength}}" .value="{{value}}" + @input="{{_listeners.input}}" @change="{{_listeners.change}}" data-sap-focus-ref> diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index 6f7d1b2d0a54..a4f3681265cb 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -192,6 +192,15 @@ const metadata = { * @public */ change: {}, + + /** + * Fired when the value of the ui5-textarea changes at each keystroke or when + * something is pasted. + * + * @event + * @public + */ + input: {}, }, }; @@ -243,6 +252,7 @@ class TextArea extends UI5Element { this._listeners = { change: this._handleChange.bind(this), + input: this._handleInput.bind(this) }; } @@ -295,6 +305,17 @@ class TextArea extends UI5Element { this.fireEvent("change", {}); } + _handleInput(event) { + const nativeTextarea = this.getInputDomRef() + if (event.target === nativeTextarea) { + // stop the native event, as the semantic "input" would be fired. + event.stopImmediatePropagation(); + } + + this.value = nativeTextarea.value; + this.fireEvent("input", {}); + } + _tokenizeText(value) { const tokenizedText = value.replace(/&/gm, "&").replace(/"/gm, """).replace(/"/gm, "'").replace(//gm, ">") From 6a2d9ff8cd650945c70f7a38ea4de3255cedc324 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 13 Jun 2019 15:04:16 +0300 Subject: [PATCH 2/6] fix eslint --- packages/main/src/TextArea.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index a4f3681265cb..388eb1a56dd2 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -196,7 +196,7 @@ const metadata = { /** * Fired when the value of the ui5-textarea changes at each keystroke or when * something is pasted. - * + * * @event * @public */ @@ -252,7 +252,7 @@ class TextArea extends UI5Element { this._listeners = { change: this._handleChange.bind(this), - input: this._handleInput.bind(this) + input: this._handleInput.bind(this), }; } @@ -306,7 +306,7 @@ class TextArea extends UI5Element { } _handleInput(event) { - const nativeTextarea = this.getInputDomRef() + const nativeTextarea = this.getInputDomRef(); if (event.target === nativeTextarea) { // stop the native event, as the semantic "input" would be fired. event.stopImmediatePropagation(); From 6db7a972f4243a658ad7743270b96380cb459f23 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Wed, 19 Jun 2019 15:53:31 +0300 Subject: [PATCH 3/6] remove binding of event handler --- packages/main/src/TextArea.hbs | 4 ++-- packages/main/src/TextArea.js | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/main/src/TextArea.hbs b/packages/main/src/TextArea.hbs index de6f785900a2..79bc8cb351c4 100644 --- a/packages/main/src/TextArea.hbs +++ b/packages/main/src/TextArea.hbs @@ -25,8 +25,8 @@ ?readonly="{{readonly}}" maxlength="{{_exceededTextProps.calcedMaxLength}}" .value="{{value}}" - @input="{{_listeners.input}}" - @change="{{_listeners.change}}" + @input="{{_handleInput}}" + @change="{{_handleChange}}" data-sap-focus-ref> diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index 388eb1a56dd2..94a8cb2ea1be 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -180,9 +180,6 @@ const metadata = { _focussed: { type: Boolean, }, - _listeners: { - type: Object, - }, }, events: /** @lends sap.ui.webcomponents.main.TextArea.prototype */ { /** @@ -249,11 +246,6 @@ class TextArea extends UI5Element { super(); this.resourceBundle = getResourceBundle("@ui5/webcomponents"); - - this._listeners = { - change: this._handleChange.bind(this), - input: this._handleInput.bind(this), - }; } onBeforeRendering() { From 15676cf8e69590052af509d4042773c52f6db8b8 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Wed, 16 Oct 2019 15:33:12 +0300 Subject: [PATCH 4/6] skip input event for placeholder in IE --- packages/main/src/TextArea.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index 24882aa423d9..a2de34d11b07 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -3,6 +3,7 @@ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; import Integer from "@ui5/webcomponents-base/dist/types/Integer.js"; import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js"; +import { isIE } from "@ui5/webcomponents-core/dist/sap/ui/Device.js"; import TextAreaTemplate from "./generated/templates/TextAreaTemplate.lit.js"; import { TEXTAREA_CHARACTERS_LEFT, TEXTAREA_CHARACTERS_EXCEEDED } from "./generated/i18n/i18n-defaults.js"; @@ -296,6 +297,14 @@ class TextArea extends UI5Element { this.value = inputValue; } + onkeydown() { + this._keyDown = true; + } + + onkeyup() { + this._keyDown = false; + } + onfocusin() { this.focused = true; } @@ -310,11 +319,21 @@ class TextArea extends UI5Element { _handleInput(event) { const nativeTextarea = this.getInputDomRef(); + + /* skip calling change event when an textarea with a placeholder is focused on IE + - value of the host and the internal textarea should be differnt in case of actual textarea + - textarea is called when a key is pressed => keyup should not be called yet + */ + const skipFiring = (this.getInputDomRef().value === this.value) && isIE() && !this._keyDown && !!this.placeholder; if (event.target === nativeTextarea) { // stop the native event, as the semantic "input" would be fired. event.stopImmediatePropagation(); } + if (skipFiring) { + return; + } + this.value = nativeTextarea.value; this.fireEvent("input", {}); } From 69c057d9639e2257676c4f659ff9332f0fe97dd5 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Thu, 17 Oct 2019 09:51:38 +0300 Subject: [PATCH 5/6] resolve comments --- packages/main/src/TextArea.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index a2de34d11b07..b00b56864e0d 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -205,6 +205,7 @@ const metadata = { * something is pasted. * * @event + * @since 1.0.0-rc.5 * @public */ input: {}, @@ -321,8 +322,8 @@ class TextArea extends UI5Element { const nativeTextarea = this.getInputDomRef(); /* skip calling change event when an textarea with a placeholder is focused on IE - - value of the host and the internal textarea should be differnt in case of actual textarea - - textarea is called when a key is pressed => keyup should not be called yet + - value of the host and the internal textarea should be different in case of actual input + - input is called when a key is pressed => keyup should not be called yet */ const skipFiring = (this.getInputDomRef().value === this.value) && isIE() && !this._keyDown && !!this.placeholder; if (event.target === nativeTextarea) { From 5398a0975c7d995f06958d02b29f9b22555b7347 Mon Sep 17 00:00:00 2001 From: Filip Siderov Date: Wed, 23 Oct 2019 15:39:53 +0300 Subject: [PATCH 6/6] Add angular two way data binding support --- packages/main/src/TextArea.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/main/src/TextArea.js b/packages/main/src/TextArea.js index b00b56864e0d..241c9cdc8ff0 100644 --- a/packages/main/src/TextArea.js +++ b/packages/main/src/TextArea.js @@ -337,6 +337,9 @@ class TextArea extends UI5Element { this.value = nativeTextarea.value; this.fireEvent("input", {}); + + // Angular two way data binding + this.fireEvent("value-changed"); } _tokenizeText(value) {