Skip to content

Commit 7a4a7e1

Browse files
authored
feat(ui5-multi-combobox): adjust validation behavior (#12707)
* feat(ui5-multi-combobox): adjust validation behavior JIRA: BGSOFUIRILA-4167
1 parent f13ccc4 commit 7a4a7e1

File tree

2 files changed

+121
-29
lines changed

2 files changed

+121
-29
lines changed

packages/main/cypress/specs/MultiComboBox.cy.tsx

Lines changed: 115 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,18 +1495,18 @@ describe("Validation & Value State", () => {
14951495
cy.realType("4");
14961496

14971497
cy.get("@input")
1498-
.should("have.value", "1");
1498+
.should("have.value", "14");
14991499

15001500
cy.get("@mcb")
15011501
.should("have.attr", "value-state", "Negative");
15021502
});
15031503

1504-
it("Reset value state validation after 2500ms", () => {
1504+
it("Invalid input persists - no automatic clearing", () => {
15051505
cy.mount(
15061506
<MultiComboBox>
1507-
<MultiComboBoxItem text="112"></MultiComboBoxItem>
1508-
<MultiComboBoxItem text="12"></MultiComboBoxItem>
1509-
<MultiComboBoxItem text="3"></MultiComboBoxItem>
1507+
<MultiComboBoxItem text="Item 1"></MultiComboBoxItem>
1508+
<MultiComboBoxItem text="Item 2"></MultiComboBoxItem>
1509+
<MultiComboBoxItem text="Item 3"></MultiComboBoxItem>
15101510
</MultiComboBox>
15111511
);
15121512

@@ -1517,21 +1517,73 @@ describe("Validation & Value State", () => {
15171517
cy.get("@mcb")
15181518
.should("be.focused");
15191519

1520-
cy.realType("4");
1520+
cy.realType("InvalidText");
15211521

15221522
cy.get("@mcb")
15231523
.should("have.attr", "value-state", "Negative");
15241524

1525-
cy.wait(2500);
1525+
cy.get("@mcb")
1526+
.shadow()
1527+
.find("input")
1528+
.as("input")
1529+
.should("have.value", "InvalidText");
1530+
1531+
// Wait to test that the value state persists after some time
1532+
cy.wait(2500)
1533+
1534+
cy.get("@input")
1535+
.should("have.value", "InvalidText");
1536+
1537+
cy.get("@mcb")
1538+
.should("have.attr", "value-state", "Negative");
1539+
});
1540+
1541+
it("Value state resets when valid entry is entered after invalid input", () => {
1542+
cy.mount(
1543+
<MultiComboBox>
1544+
<MultiComboBoxItem text="Item 1"></MultiComboBoxItem>
1545+
<MultiComboBoxItem text="Item 2"></MultiComboBoxItem>
1546+
<MultiComboBoxItem text="Item 3"></MultiComboBoxItem>
1547+
</MultiComboBox>
1548+
);
1549+
1550+
cy.get("[ui5-multi-combobox]")
1551+
.as("mcb")
1552+
.realClick();
1553+
1554+
cy.get("@mcb")
1555+
.should("be.focused");
1556+
1557+
// Type invalid text
1558+
cy.realType("xyz");
1559+
1560+
cy.get("@mcb")
1561+
.should("have.attr", "value-state", "Negative");
1562+
1563+
cy.get("@mcb")
1564+
.shadow()
1565+
.find("input")
1566+
.as("input")
1567+
.should("have.value", "xyz");
1568+
1569+
// Clear and type valid text
1570+
cy.get("@input")
1571+
.clear();
1572+
1573+
cy.realType("Item");
15261574

15271575
cy.get("@mcb")
15281576
.should("have.attr", "value-state", "None");
1577+
1578+
cy.get("@input")
1579+
.should("have.value", "Item 1");
15291580
});
15301581

1531-
it("Built in validation by typing a non existing option", () => {
1582+
it("Value state resets when input is cleared after invalid entry", () => {
15321583
cy.mount(
15331584
<MultiComboBox>
1534-
<MultiComboBoxItem text="Cosy"></MultiComboBoxItem>
1585+
<MultiComboBoxItem text="Item 1"></MultiComboBoxItem>
1586+
<MultiComboBoxItem text="Item 2"></MultiComboBoxItem>
15351587
</MultiComboBox>
15361588
);
15371589

@@ -1542,12 +1594,64 @@ describe("Validation & Value State", () => {
15421594
cy.get("@mcb")
15431595
.should("be.focused");
15441596

1545-
cy.realType("CCo");
1597+
// Type invalid text
1598+
cy.realType("InvalidValue");
1599+
1600+
cy.get("@mcb")
1601+
.should("have.attr", "value-state", "Negative");
15461602

15471603
cy.get("@mcb")
15481604
.shadow()
15491605
.find("input")
1550-
.should("have.value", "Cosy");
1606+
.as("input")
1607+
.should("have.value", "InvalidValue");
1608+
1609+
// Clear the input
1610+
cy.get("@input")
1611+
.clear();
1612+
1613+
cy.get("@mcb")
1614+
.should("have.attr", "value-state", "None");
1615+
1616+
cy.get("@input")
1617+
.should("have.value", "");
1618+
});
1619+
1620+
it("Value state preserved when switching between valid and invalid", () => {
1621+
cy.mount(
1622+
<MultiComboBox valueState="Critical">
1623+
<MultiComboBoxItem text="Item 1"></MultiComboBoxItem>
1624+
<MultiComboBoxItem text="Item 2"></MultiComboBoxItem>
1625+
</MultiComboBox>
1626+
);
1627+
1628+
cy.get("[ui5-multi-combobox]")
1629+
.as("mcb")
1630+
.realClick();
1631+
1632+
cy.get("@mcb")
1633+
.should("be.focused");
1634+
1635+
cy.get("@mcb")
1636+
.should("have.attr", "value-state", "Critical");
1637+
1638+
// Type invalid text
1639+
cy.realType("xyz");
1640+
1641+
cy.get("@mcb")
1642+
.should("have.attr", "value-state", "Negative");
1643+
1644+
cy.get("@mcb")
1645+
.shadow()
1646+
.find("input")
1647+
.as("input");
1648+
1649+
// Clear and verify original state is restored
1650+
cy.get("@input")
1651+
.clear();
1652+
1653+
cy.get("@mcb")
1654+
.should("have.attr", "value-state", "Critical");
15511655
});
15521656

15531657
it("Tests if item is created when enter is pressed while validation is ongoing", () => {
@@ -4214,7 +4318,6 @@ describe("MultiComboBox Composition", () => {
42144318
simulateCompositionStages(["ㄲ", "ㄲㅏ"], "까");
42154319

42164320
cy.get("@mcb").should("have.attr", "value-state", "Negative");
4217-
cy.get("@input").should("have.value", "");
42184321
cy.get("@mcb")
42194322
.shadow()
42204323
.find("[ui5-tokenizer] [ui5-token]")
@@ -4248,7 +4351,6 @@ describe("MultiComboBox Composition", () => {
42484351

42494352
simulateCompositionStages(["ず", "ずx"], "ずx");
42504353
cy.get("@mcb").should("have.attr", "value-state", "Negative");
4251-
cy.get("@input").should("have.value", "");
42524354
cy.get("@mcb")
42534355
.shadow()
42544356
.find("[ui5-tokenizer] [ui5-token]")
@@ -4284,7 +4386,6 @@ describe("MultiComboBox Composition", () => {
42844386

42854387
simulateCompositionStages(["p", "pi", "pin"], "品味");
42864388
cy.get("@mcb").should("have.attr", "value-state", "Negative");
4287-
cy.get("@input").should("have.value", "");
42884389
cy.get("@mcb")
42894390
.shadow()
42904391
.find("[ui5-tokenizer] [ui5-token]")

packages/main/src/MultiComboBox.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,6 @@ class MultiComboBox extends UI5Element implements IFormInputElement {
708708
const input = e.target as HTMLInputElement;
709709
const value: string = input.value;
710710
const filteredItems: Array<IMultiComboBoxItem> = this._filterItems(value);
711-
const oldValueState: `${ValueState}` = this.valueState;
712711

713712
this._shouldFilterItems = true;
714713

@@ -721,24 +720,20 @@ class MultiComboBox extends UI5Element implements IFormInputElement {
721720
this.valueState = this._effectiveValueState;
722721
this._validationTimeout = null;
723722
} else {
724-
input.value = this._inputLastValue;
725723
return;
726724
}
727725
}
728726

729-
this._effectiveValueState = this.valueState;
727+
// Save the original value state before setting validation error
728+
if (this.valueState !== ValueState.Negative) {
729+
this._effectiveValueState = this.valueState;
730+
}
730731

731732
if (!this._isComposing && !filteredItems.length && value && !this.noValidation) {
732-
const newValue = this.valueBeforeAutoComplete || this._inputLastValue;
733-
734-
input.value = newValue;
735-
this.value = newValue;
736733
this.valueState = ValueState.Negative;
737-
738734
this._shouldAutocomplete = false;
739-
this._resetValueState(oldValueState);
740-
741-
return;
735+
} else if ((filteredItems.length || !value) && this.valueState === ValueState.Negative) {
736+
this.valueState = this._effectiveValueState;
742737
}
743738

744739
if (!this._isComposing) {
@@ -1938,10 +1933,6 @@ class MultiComboBox extends UI5Element implements IFormInputElement {
19381933
}
19391934

19401935
this._tokenizer.expanded = this.open;
1941-
// remove the value if user focus out the input and focus is not going in the popover
1942-
if (!isPhone() && !this.noValidation && !focusIsGoingInPopover) {
1943-
this.value = "";
1944-
}
19451936
}
19461937
}
19471938
/**

0 commit comments

Comments
 (0)