Skip to content

Commit 1294d44

Browse files
MapTo0ilhan007
authored andcommitted
fix(ui5-combobox): enable setting value programatically (#3253)
BREAKING CHANGE: filter value property is removed. FIXES: #2233
1 parent 46f54f8 commit 1294d44

File tree

5 files changed

+157
-75
lines changed

5 files changed

+157
-75
lines changed

packages/main/src/ComboBox.hbs

+1-1
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

+74-70
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ const metadata = {
6868
/**
6969
* Defines the "live" value of the <code>ui5-combobox</code>.
7070
* <br><br>
71-
* <b>Note:</b> The property is updated upon typing.
71+
* <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".
7272
*
7373
* <br><br>
7474
* <b>Note:</b> Initially the filter value is synced with value.
7575
*
7676
* @type {string}
7777
* @defaultvalue ""
78-
* @public
78+
* @private
7979
*/
8080
filterValue: {
8181
type: String,
@@ -214,11 +214,6 @@ const metadata = {
214214
noAttribute: true,
215215
},
216216

217-
_tempValue: {
218-
type: String,
219-
defaultValue: "",
220-
},
221-
222217
_filteredItems: {
223218
type: Object,
224219
},
@@ -389,27 +384,8 @@ class ComboBox extends UI5Element {
389384
}
390385

391386
onBeforeRendering() {
392-
let domValue;
393-
394387
if (this._initialRendering) {
395-
domValue = this.value;
396388
this._filteredItems = this.items;
397-
} else {
398-
domValue = this.filterValue;
399-
}
400-
401-
if (this._autocomplete && domValue !== "") {
402-
const item = this._autoCompleteValue(domValue);
403-
404-
if (!this._selectionChanged && (item && !item.selected)) {
405-
this.fireEvent("selection-change", {
406-
item,
407-
});
408-
409-
this._selectionChanged = false;
410-
}
411-
} else {
412-
this._tempValue = domValue;
413389
}
414390

415391
if (!this._initialRendering && this.popover && document.activeElement === this && !this._filteredItems.length) {
@@ -418,12 +394,6 @@ class ComboBox extends UI5Element {
418394

419395
this._selectMatchingItem();
420396

421-
if (this._isKeyNavigation && this.responsivePopover && this.responsivePopover.opened) {
422-
this.focused = false;
423-
} else if (this.shadowRoot.activeElement) {
424-
this.focused = this.shadowRoot.activeElement.id === "ui5-combobox-input";
425-
}
426-
427397
this._initialRendering = false;
428398
this._isKeyNavigation = false;
429399
}
@@ -452,28 +422,21 @@ class ComboBox extends UI5Element {
452422
_focusin(event) {
453423
this.focused = true;
454424

455-
if (this.filterValue !== this.value) {
456-
this.filterValue = this.value;
457-
}
425+
this._lastValue = this.value;
458426

459427
!isPhone() && event.target.setSelectionRange(0, this.value.length);
460428
}
461429

462430
_focusout() {
463431
this.focused = false;
464432

465-
this._inputChange();
433+
this._fireChangeEvent();
434+
466435
!isPhone() && this._closeRespPopover();
467436
}
468437

469438
_afterOpenPopover() {
470439
this._iconPressed = true;
471-
472-
if (isPhone() && this.value) {
473-
this.filterValue = this.value
474-
}
475-
476-
this._clearFocus();
477440
}
478441

479442
_afterClosePopover() {
@@ -485,6 +448,11 @@ class ComboBox extends UI5Element {
485448
if (isPhone()) {
486449
this.blur();
487450
}
451+
452+
if (this._selectionPerformed) {
453+
this._lastValue = this.value;
454+
this._selectionPerformed = false;
455+
}
488456
}
489457

490458
_toggleRespPopover() {
@@ -544,12 +512,28 @@ class ComboBox extends UI5Element {
544512
event.stopImmediatePropagation();
545513
}
546514

547-
this._clearFocus();
548-
this._tempFilterValue = value;
515+
this._filteredItems = this._filterItems(value);
516+
this.value = value;
549517
this.filterValue = value;
550-
this.fireEvent("input");
551518

552-
this._filteredItems = this._filterItems(value);
519+
this._clearFocus();
520+
521+
// autocomplete
522+
if (this._autocomplete && value !== "") {
523+
const item = this._autoCompleteValue(value);
524+
525+
if (!this._selectionChanged && (item && !item.selected)) {
526+
this.fireEvent("selection-change", {
527+
item,
528+
});
529+
530+
this._selectionChanged = false;
531+
532+
item.focused = true;
533+
}
534+
}
535+
536+
this.fireEvent("input");
553537

554538
if (isPhone()) {
555539
return;
@@ -598,14 +582,23 @@ class ComboBox extends UI5Element {
598582
indexOfItem = indexOfItem < 0 ? 0 : indexOfItem;
599583

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

610603
this._selectionChanged = true;
611604
}
@@ -619,7 +612,7 @@ class ComboBox extends UI5Element {
619612
}
620613

621614
if (isEnter(event)) {
622-
this._inputChange();
615+
this._fireChangeEvent();
623616
this._closeRespPopover();
624617
}
625618

@@ -640,7 +633,6 @@ class ComboBox extends UI5Element {
640633
if (isPhone() && event && event.target.classList.contains("ui5-responsive-popover-close-btn") && this._selectedItemText) {
641634
this.value = this._selectedItemText;
642635
this.filterValue = this._selectedItemText;
643-
this._tempValue = this._selectedItemText;
644636
}
645637

646638
this.responsivePopover.close();
@@ -655,23 +647,21 @@ class ComboBox extends UI5Element {
655647
}
656648

657649
_autoCompleteValue(current) {
658-
const currentValue = current;
659-
const matchingItems = this._startsWithMatchingItems(currentValue);
660-
const selectionValue = this._tempFilterValue ? this._tempFilterValue : currentValue;
650+
const matchingItems = this._startsWithMatchingItems(current);
661651

662652
if (matchingItems.length) {
663-
this._tempValue = matchingItems[0] ? matchingItems[0].text : current;
653+
this.value = matchingItems[0] ? matchingItems[0].text : current;
664654
} else {
665-
this._tempValue = current;
655+
this.value = current;
666656
}
667657

668-
if (matchingItems.length && (selectionValue !== this._tempValue && this.value !== this._tempValue)) {
658+
if (this._isKeyNavigation) {
669659
setTimeout(() => {
670-
this.inner.setSelectionRange(selectionValue.length, this._tempValue.length);
660+
this.inner.setSelectionRange(0, this.value.length);
671661
}, 0);
672-
} else if (this._isKeyNavigation) {
662+
} else if (matchingItems.length) {
673663
setTimeout(() => {
674-
this.inner.setSelectionRange(0, this._tempValue.length);
664+
this.inner.setSelectionRange(this.filterValue.length, this.value.length);
675665
}, 0);
676666
}
677667

@@ -682,30 +672,41 @@ class ComboBox extends UI5Element {
682672

683673
_selectMatchingItem() {
684674
this._filteredItems = this._filteredItems.map(item => {
685-
item.selected = (item.text === this._tempValue);
675+
item.selected = (item.text === this.value);
686676

687677
return item;
688678
});
689679
}
690680

691-
_inputChange() {
692-
if (this.value !== this._tempValue) {
693-
this.value = this._tempValue;
681+
_fireChangeEvent() {
682+
if (this.value !== this._lastValue) {
694683
this.fireEvent("change");
695-
this.inner.setSelectionRange(this.value.length, this.value.length);
684+
this._lastValue = this.value;
696685
}
697686
}
698687

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

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

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

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

724-
this._inputChange();
725+
this._fireChangeEvent();
725726
this._closeRespPopover();
727+
728+
// reset selection
729+
this.inner.setSelectionRange(this.value.length, this.value.length);
726730
}
727731

728732
_onItemFocus(event) {

packages/main/src/ComboBoxPopover.hbs

+1-1
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

+10-2
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)