You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2025/11/25 19:40:20 UTC
(myfaces-tobago) branch main updated: fix(selectManyList): deselect
This is an automated email from the ASF dual-hosted git repository.
hnoeth pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git
The following commit(s) were added to refs/heads/main by this push:
new f420217a19 fix(selectManyList): deselect
f420217a19 is described below
commit f420217a19b1c858f3732335179a102939eda9bc
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Nov 25 14:49:15 2025 +0100
fix(selectManyList): deselect
* add test
* fix
Issue: TOBAGO-2450
---
.../2100-selectManyList/deselect/deselect.xhtml | 31 ++++++++++++++
.../src/test/typescript/selectManyList.test.ts | 50 ++++++++++++++++++++++
.../src/main/ts/tobago-select-many-list.ts | 26 ++++++++++-
3 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/2100-selectManyList/deselect/deselect.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/2100-selectManyList/deselect/deselect.xhtml
new file mode 100644
index 0000000000..b7733265e0
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/2100-selectManyList/deselect/deselect.xhtml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<ui:composition template="/main.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tc="http://myfaces.apache.org/tobago/component"
+ xmlns:ui="jakarta.faces.facelets">
+
+ <tc:button id="reset" label="Reset" action="#{selectManyListController.resetSelectedPlanets()}"/>
+
+ <tc:selectManyList id="selectManyList" value="#{selectManyListController.selectedPlanets}">
+ <tc:selectItems value="#{selectManyListController.planets}" var="planet"
+ itemLabel="#{planet.name}" itemValue="#{planet}" itemDisabled="#{planet.name == 'Earth'}"/>
+ </tc:selectManyList>
+</ui:composition>
diff --git a/tobago-example/tobago-example-demo/src/test/typescript/selectManyList.test.ts b/tobago-example/tobago-example-demo/src/test/typescript/selectManyList.test.ts
new file mode 100644
index 0000000000..6c6cbb767c
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/test/typescript/selectManyList.test.ts
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import {expect, test} from "@playwright/test";
+
+test.describe("900-test/2100-selectManyList/deselect/deselect.xhtml", () => {
+
+ test.beforeEach(async ({page}) => {
+ await page.goto("http://localhost:8080/content/900-test/2100-selectManyList/deselect/deselect.xhtml");
+ });
+
+ test("tc:selectManyList: deselect", async ({page}) => {
+ const reset = page.locator("button[id='page:mainForm:reset']");
+ await reset.click();
+
+ const selectManyList = page.locator("tobago-select-many-list[id='page:mainForm:selectManyList']");
+ const venus = selectManyList.locator(".btn-group[data-tobago-value='Venus']");
+ const earth = selectManyList.locator(".btn-group[data-tobago-value='Earth']");
+ const jupiter = selectManyList.locator(".btn-group[data-tobago-value='Jupiter']");
+ await expect(venus).toBeVisible();
+ await expect(earth).toBeVisible();
+ await expect(jupiter).toBeVisible();
+
+ await venus.locator(".tobago-button").click();
+ await expect(venus).not.toBeVisible();
+ await expect(earth).toBeVisible();
+ await expect(jupiter).toBeVisible();
+
+ await jupiter.locator(".tobago-button").click();
+ await expect(venus).not.toBeVisible();
+ await expect(earth).toBeVisible();
+ await expect(jupiter).not.toBeVisible();
+ });
+});
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts
index 879e870cf6..df1999c0f8 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts
@@ -135,8 +135,8 @@ class SelectManyList extends SelectListBase {
option.selected = false;
const badge = this.badges.querySelector(`[data-tobago-value="${itemValue}"]`);
- const previousBadge = badge.previousElementSibling;
- const nextBadge = badge.nextElementSibling?.tagName === "SPAN" ? badge.nextElementSibling : null;
+ const previousBadge = this.getPreviousEnabledBadge(badge);
+ const nextBadge = this.getNextEnabledBadge(badge);
if (previousBadge) {
previousBadge.querySelector<HTMLButtonElement>("button.btn.badge").focus();
} else if (nextBadge) {
@@ -162,6 +162,28 @@ class SelectManyList extends SelectListBase {
this.hiddenSelect.dispatchEvent(new Event("change", {bubbles: true}));
}
+ private getPreviousEnabledBadge(currentBadge: Element): Element {
+ const previousElementSibling = currentBadge.previousElementSibling;
+ if (previousElementSibling === null) {
+ return null;
+ } else if (previousElementSibling.querySelector<HTMLButtonElement>(".tobago-button")) {
+ return previousElementSibling;
+ } else {
+ return this.getPreviousEnabledBadge(previousElementSibling);
+ }
+ }
+
+ private getNextEnabledBadge(currentBadge: Element): Element {
+ const NextElementSibling = currentBadge.nextElementSibling;
+ if (NextElementSibling === null) {
+ return null;
+ } else if (NextElementSibling.querySelector<HTMLButtonElement>(".tobago-button")) {
+ return NextElementSibling;
+ } else {
+ return this.getNextEnabledBadge(NextElementSibling);
+ }
+ }
+
protected leaveComponent(): void {
if (this.focused) {
if (!this.serverSideFiltering || (this.lastSuccessfulSearchQuery && this.lastSuccessfulSearchQuery.length > 0)) {