Skip to content

Commit d85561a

Browse files
authored
fix(ui5-combobox): enable setting value programatically (#3253)
BREAKING CHANGE: filter value property is removed. FIXES: #2233
1 parent 658328a commit d85561a

File tree

5 files changed

+157
-75
lines changed

5 files changed

+157
-75
lines changed

packages/main/src/ComboBox.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{{/if}}
55

66
<input id="ui5-combobox-input"
7-
.value="{{_tempValue}}"
7+
.value="{{value}}"
88
inner-input
99
placeholder="{{placeholder}}"
1010
?disabled={{disabled}}

packages/main/src/ComboBox.js

Lines changed: 74 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ const metadata = {
7070
/**
7171
* Defines the "live" value of the component.
7272
* <br><br>
73-
* <b>Note:</b> The property is updated upon typing.
73+
* <b>Note:</b> If we have an item e.g. "Bulgaria", "B" is typed, "ulgaria" is typed ahead, value will be "Bulgaria", filterValue will be "B".
7474
*
7575
* <br><br>
7676
* <b>Note:</b> Initially the filter value is synced with value.
7777
*
7878
* @type {string}
7979
* @defaultvalue ""
80-
* @public
80+
* @private
8181
*/
8282
filterValue: {
8383
type: String,
@@ -216,11 +216,6 @@ const metadata = {
216216
noAttribute: true,
217217
},
218218

219-
_tempValue: {
220-
type: String,
221-
defaultValue: "",
222-
},
223-
224219
_filteredItems: {
225220
type: Object,
226221
},
@@ -384,27 +379,8 @@ class ComboBox extends UI5Element {
384379
}
385380

386381
onBeforeRendering() {
387-
let domValue;
388-
389382
if (this._initialRendering) {
390-
domValue = this.value;
391383
this._filteredItems = this.items;
392-
} else {
393-
domValue = this.filterValue;
394-
}
395-
396-
if (this._autocomplete && domValue !== "") {
397-
const item = this._autoCompleteValue(domValue);
398-
399-
if (!this._selectionChanged && (item && !item.selected)) {
400-
this.fireEvent("selection-change", {
401-
item,
402-
});
403-
404-
this._selectionChanged = false;
405-
}
406-
} else {
407-
this._tempValue = domValue;
408384
}
409385

410386
if (!this._initialRendering && this.popover && document.activeElement === this && !this._filteredItems.length) {
@@ -413,12 +389,6 @@ class ComboBox extends UI5Element {
413389

414390
this._selectMatchingItem();
415391

416-
if (this._isKeyNavigation && this.responsivePopover && this.responsivePopover.opened) {
417-
this.focused = false;
418-
} else if (this.shadowRoot.activeElement) {
419-
this.focused = this.shadowRoot.activeElement.id === "ui5-combobox-input";
420-
}
421-
422392
this._initialRendering = false;
423393
this._isKeyNavigation = false;
424394
}
@@ -447,28 +417,21 @@ class ComboBox extends UI5Element {
447417
_focusin(event) {
448418
this.focused = true;
449419

450-
if (this.filterValue !== this.value) {
451-
this.filterValue = this.value;
452-
}
420+
this._lastValue = this.value;
453421

454422
!isPhone() && event.target.setSelectionRange(0, this.value.length);
455423
}
456424

457425
_focusout() {
458426
this.focused = false;
459427

460-
this._inputChange();
428+
this._fireChangeEvent();
429+
461430
!isPhone() && this._closeRespPopover();
462431
}
463432

464433
_afterOpenPopover() {
465434
this._iconPressed = true;
466-
467-
if (isPhone() && this.value) {
468-
this.filterValue = this.value;
469-
}
470-
471-
this._clearFocus();
472435
}
473436

474437
_afterClosePopover() {
@@ -480,6 +443,11 @@ class ComboBox extends UI5Element {
480443
if (isPhone()) {
481444
this.blur();
482445
}
446+
447+
if (this._selectionPerformed) {
448+
this._lastValue = this.value;
449+
this._selectionPerformed = false;
450+
}
483451
}
484452

485453
_toggleRespPopover() {
@@ -539,12 +507,28 @@ class ComboBox extends UI5Element {
539507
event.stopImmediatePropagation();
540508
}
541509

542-
this._clearFocus();
543-
this._tempFilterValue = value;
510+
this._filteredItems = this._filterItems(value);
511+
this.value = value;
544512
this.filterValue = value;
545-
this.fireEvent("input");
546513

547-
this._filteredItems = this._filterItems(value);
514+
this._clearFocus();
515+
516+
// autocomplete
517+
if (this._autocomplete && value !== "") {
518+
const item = this._autoCompleteValue(value);
519+
520+
if (!this._selectionChanged && (item && !item.selected)) {
521+
this.fireEvent("selection-change", {
522+
item,
523+
});
524+
525+
this._selectionChanged = false;
526+
527+
item.focused = true;
528+
}
529+
}
530+
531+
this.fireEvent("input");
548532

549533
if (isPhone()) {
550534
return;
@@ -597,14 +581,23 @@ class ComboBox extends UI5Element {
597581
}
598582

599583
this._filteredItems[indexOfItem].focused = true;
600-
this.filterValue = this._filteredItems[indexOfItem].text;
584+
this._filteredItems[indexOfItem].selected = true;
585+
586+
this.value = this._filteredItems[indexOfItem].text;
587+
588+
// autocomplete
589+
const item = this._autoCompleteValue(this.value);
590+
591+
if ((item && !item.selected)) {
592+
this.fireEvent("selection-change", {
593+
item,
594+
});
595+
}
596+
601597
this._isKeyNavigation = true;
602598
this._itemFocused = true;
603599
this.fireEvent("input");
604-
605-
this.fireEvent("selection-change", {
606-
item: this._filteredItems[indexOfItem],
607-
});
600+
this._fireChangeEvent();
608601

609602
this._selectionChanged = true;
610603
}
@@ -618,7 +611,7 @@ class ComboBox extends UI5Element {
618611
}
619612

620613
if (isEnter(event)) {
621-
this._inputChange();
614+
this._fireChangeEvent();
622615
this._closeRespPopover();
623616
}
624617

@@ -639,7 +632,6 @@ class ComboBox extends UI5Element {
639632
if (isPhone() && event && event.target.classList.contains("ui5-responsive-popover-close-btn") && this._selectedItemText) {
640633
this.value = this._selectedItemText;
641634
this.filterValue = this._selectedItemText;
642-
this._tempValue = this._selectedItemText;
643635
}
644636

645637
this.responsivePopover.close();
@@ -654,23 +646,21 @@ class ComboBox extends UI5Element {
654646
}
655647

656648
_autoCompleteValue(current) {
657-
const currentValue = current;
658-
const matchingItems = this._startsWithMatchingItems(currentValue);
659-
const selectionValue = this._tempFilterValue ? this._tempFilterValue : currentValue;
649+
const matchingItems = this._startsWithMatchingItems(current);
660650

661651
if (matchingItems.length) {
662-
this._tempValue = matchingItems[0] ? matchingItems[0].text : current;
652+
this.value = matchingItems[0] ? matchingItems[0].text : current;
663653
} else {
664-
this._tempValue = current;
654+
this.value = current;
665655
}
666656

667-
if (matchingItems.length && (selectionValue !== this._tempValue && this.value !== this._tempValue)) {
657+
if (this._isKeyNavigation) {
668658
setTimeout(() => {
669-
this.inner.setSelectionRange(selectionValue.length, this._tempValue.length);
659+
this.inner.setSelectionRange(0, this.value.length);
670660
}, 0);
671-
} else if (this._isKeyNavigation) {
661+
} else if (matchingItems.length) {
672662
setTimeout(() => {
673-
this.inner.setSelectionRange(0, this._tempValue.length);
663+
this.inner.setSelectionRange(this.filterValue.length, this.value.length);
674664
}, 0);
675665
}
676666

@@ -681,30 +671,41 @@ class ComboBox extends UI5Element {
681671

682672
_selectMatchingItem() {
683673
this._filteredItems = this._filteredItems.map(item => {
684-
item.selected = (item.text === this._tempValue);
674+
item.selected = (item.text === this.value);
685675

686676
return item;
687677
});
688678
}
689679

690-
_inputChange() {
691-
if (this.value !== this._tempValue) {
692-
this.value = this._tempValue;
680+
_fireChangeEvent() {
681+
if (this.value !== this._lastValue) {
693682
this.fireEvent("change");
694-
this.inner.setSelectionRange(this.value.length, this.value.length);
683+
this._lastValue = this.value;
695684
}
696685
}
697686

687+
_inputChange(event) {
688+
event.preventDefault();
689+
}
690+
698691
_itemMousedown(event) {
699692
event.preventDefault();
700693
}
701694

702695
_selectItem(event) {
703696
const listItem = event.detail.item;
704697

705-
this._tempValue = listItem.mappedItem.text;
706698
this._selectedItemText = listItem.mappedItem.text;
707-
this.filterValue = this._tempValue;
699+
this._selectionPerformed = true;
700+
701+
const sameItemSelected = this.value === this._selectedItemText;
702+
const sameSelectionPerformed = this.value.toLowerCase() === this.filterValue.toLowerCase();
703+
704+
if (sameItemSelected && sameSelectionPerformed) {
705+
return this._closeRespPopover();
706+
}
707+
708+
this.value = this._selectedItemText;
708709

709710
if (!listItem.mappedItem.selected) {
710711
this.fireEvent("selection-change", {
@@ -720,8 +721,11 @@ class ComboBox extends UI5Element {
720721
return item;
721722
});
722723

723-
this._inputChange();
724+
this._fireChangeEvent();
724725
this._closeRespPopover();
726+
727+
// reset selection
728+
this.inner.setSelectionRange(this.value.length, this.value.length);
725729
}
726730

727731
_onItemFocus(event) {

packages/main/src/ComboBoxPopover.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
>
3434
<input
3535
class="ui5-input-inner-phone"
36-
.value="{{_tempValue}}"
36+
.value="{{value}}"
3737
inner-input
3838
placeholder="{{placeholder}}"
3939
value-state="{{valueState}}"

packages/main/test/pages/ComboBox.html

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
<ui5-cb-item text="Chile"></ui5-cb-item>
5656
</ui5-combobox>
5757

58+
<br>
59+
60+
<ui5-button id="value-set-btn" >Set value</ui5-button>
61+
5862
<ui5-combobox id="combo2" style="width: 360px;" aria-label="Select destination:">
5963
<ui5-cb-item text="Algeria"></ui5-cb-item>
6064
<ui5-cb-item text="Argentina"></ui5-cb-item>
@@ -197,7 +201,7 @@ <h3>ComboBox in Compact</h3>
197201

198202
<script type="module">
199203
document.getElementById("lazy").addEventListener("ui5-input", async event => {
200-
const { filterValue } = event.target;
204+
const { value } = event.target;
201205

202206
// set busy state
203207
event.target.loading = true;
@@ -238,9 +242,13 @@ <h3>ComboBox in Compact</h3>
238242
});
239243

240244
document.getElementById("input-cb").addEventListener("ui5-input", function(event) {
241-
document.getElementById("input-placeholder").innerHTML = event.target.filterValue;
245+
document.getElementById("input-placeholder").innerHTML = event.target.value;
242246
document.getElementById("input-count").innerHTML = parseInt(document.getElementById("input-count").innerHTML) + 1;
243247
});
248+
249+
document.getElementById("value-set-btn").addEventListener("click", function (event) {
250+
document.getElementById("combo").value = "new value";
251+
});
244252
</script>
245253

246254
</body>

0 commit comments

Comments
 (0)