Skip to content

Commit 17465e3

Browse files
authored
fix(ui5-input): refactor change event (#5296)
* fix(ui5-input): refactor change event * fix(ui5-input): correct clearIcon change event behavior * fix(ui5-input): change event should not be fired on clear icon press
1 parent a494f85 commit 17465e3

File tree

3 files changed

+18
-24
lines changed

3 files changed

+18
-24
lines changed

packages/main/src/Input.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
aria-label="{{accInfo.input.ariaLabel}}"
2929
aria-required="{{required}}"
3030
@input="{{_handleInput}}"
31-
@change="{{_handleNativeInputChange}}"
31+
@change="{{_handleChange}}"
3232
@keydown="{{_onkeydown}}"
3333
@keyup="{{_onkeyup}}"
3434
@click={{_click}}
@@ -40,7 +40,7 @@
4040
/>
4141

4242
{{#if effectiveShowClearIcon}}
43-
<ui5-icon @click={{_clear}} tabindex="-1" input-icon class="ui5-input-clear-icon" name="decline"></ui5-icon>
43+
<ui5-icon @click={{_clear}} @mousedown={{_iconMouseDown}} tabindex="-1" input-icon class="ui5-input-clear-icon" name="decline"></ui5-icon>
4444
{{/if}}
4545

4646
{{#if icon.length}}

packages/main/src/Input.js

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -767,11 +767,6 @@ class Input extends UI5Element {
767767
}
768768

769769
_onkeyup(event) {
770-
// The native Delete event does not update the value property "on time". So, the (native) change event is always fired with the old value
771-
if (isDelete(event)) {
772-
this.value = event.target.value;
773-
}
774-
775770
this._keyDown = false;
776771
this._backspaceKeyDown = false;
777772
}
@@ -913,7 +908,10 @@ class Input extends UI5Element {
913908
const focusedOutToSuggestions = this.Suggestions && event.relatedTarget && event.relatedTarget.shadowRoot && event.relatedTarget.shadowRoot.contains(this.Suggestions.responsivePopover);
914909
const focusedOutToValueStateMessage = event.relatedTarget && event.relatedTarget.shadowRoot && event.relatedTarget.shadowRoot.querySelector(".ui5-valuestatemessage-root");
915910

916-
this._preventNextChange = this.effectiveShowClearIcon && this.shadowRoot.contains(event.relatedTarget);
911+
if (this.showClearIcon && !this.effectiveShowClearIcon) {
912+
this._clearIconClicked = false;
913+
this._handleChange();
914+
}
917915

918916
// if focusout is triggered by pressing on suggestion item or value state message popover, skip invalidation, because re-rendering
919917
// will happen before "itemPress" event, which will make item "active" state not visualized
@@ -957,35 +955,30 @@ class Input extends UI5Element {
957955
}
958956
}
959957

960-
_handleNativeInputChange() {
961-
// The native change sometimes fires too early and getting input's value in the listener would return
962-
// the previous value instead of the most recent one. This would make things consistent.
963-
clearTimeout(this._nativeChangeDebounce);
964-
this._nativeChangeDebounce = setTimeout(() => this._handleChange(), 100);
965-
}
966-
967958
_handleChange() {
968-
if (this._preventNextChange) {
969-
this._preventNextChange = false;
959+
if (this._clearIconClicked) {
960+
this._clearIconClicked = false;
970961
return;
971962
}
972963

973-
if (this._changeFiredValue !== this.value) {
974-
this._changeFiredValue = this.value;
964+
if (this._changeFiredValue !== this.getInputDOMRefSync().value) {
965+
this._changeFiredValue = this.getInputDOMRefSync().value;
975966
this.fireEvent(this.EVENT_CHANGE);
976967
}
977968
}
978969

979970
_clear() {
980971
this.value = "";
981972
this.fireEvent(this.EVENT_INPUT);
982-
this._handleChange();
983-
984973
if (!this._isPhone) {
985974
this.focus();
986975
}
987976
}
988977

978+
_iconMouseDown() {
979+
this._clearIconClicked = true;
980+
}
981+
989982
_scroll(event) {
990983
const detail = event.detail;
991984
this.fireEvent("suggestion-scroll", {
@@ -1187,14 +1180,15 @@ class Input extends UI5Element {
11871180

11881181
const itemText = item.text || item.textContent; // keep textContent for compatibility
11891182
const fireInput = keyboardUsed
1190-
? this.valueBeforeItemSelection !== itemText : this.value !== itemText;
1183+
? this.valueBeforeItemSelection !== itemText : this.valueBeforeAutoComplete !== itemText;
11911184

11921185
this.hasSuggestionItemSelected = true;
11931186

11941187
if (fireInput) {
11951188
this.value = itemText;
11961189
this.valueBeforeItemSelection = itemText;
11971190
this.lastConfirmedValue = itemText;
1191+
this.getInputDOMRefSync().value = itemText;
11981192
this.fireEvent(this.EVENT_INPUT);
11991193
this._handleChange();
12001194
}

packages/main/test/specs/Input.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ describe("Input general interaction", () => {
692692

693693
assert.strictEqual(await input.getProperty("value"), "", "Clear icon clear the value");
694694
assert.notOk(await input.getProperty("effectiveShowClearIcon"), "Clear icon should not be shown");
695-
assert.strictEqual(await changeCounter.getText(), "0", "Change event not called yet");
695+
assert.strictEqual(await changeCounter.getText(), "0", "Change event should not be called on clearIcon click");
696696
assert.strictEqual(await inputCounter.getText(), "2", "Input event called when typing or clear action is done");
697697
});
698698

@@ -714,7 +714,7 @@ describe("Input general interaction", () => {
714714
// press clear icon
715715
await clearIcon.click();
716716

717-
assert.strictEqual(await changeCounter.getText(), "2", "Change event called twice (first - typing, second - clear icon)");
717+
assert.strictEqual(await changeCounter.getText(), "1", "Change event called once (typing)");
718718
assert.strictEqual(await inputCounter.getText(), "2", "Input event called when value is cleared by clear icon");
719719
});
720720

0 commit comments

Comments
 (0)