You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2024/12/17 09:10:37 UTC
(myfaces-tobago) branch main updated: feat: Reimplement paginator for sheet (#5824)
This is an automated email from the ASF dual-hosted git repository.
lofwyr 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 b0a51ad997 feat: Reimplement paginator for sheet (#5824)
b0a51ad997 is described below
commit b0a51ad9975a74a14c38efa95faa93de78be0b9d
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Tue Dec 17 10:10:32 2024 +0100
feat: Reimplement paginator for sheet (#5824)
progress...
issue: TOBAGO-2243
---
.../apache/myfaces/tobago/component/Pageable.java | 60 -----
.../myfaces/tobago/event/PageActionEvent.java | 13 +-
.../internal/component/AbstractUIPaginator.java | 11 +-
.../tobago/internal/component/AbstractUISheet.java | 9 +-
.../renderkit/renderer/PaginatorListRenderer.java | 39 ++--
.../renderkit/renderer/PaginatorPageRenderer.java | 34 +--
.../renderkit/renderer/PaginatorRenderer.java | 52 +++--
.../renderkit/renderer/PaginatorRowRenderer.java | 25 +--
.../internal/renderkit/renderer/SheetRenderer.java | 173 +++++---------
.../taglib/component/SheetTagDeclaration.java | 2 +-
.../myfaces/tobago/internal/util/JsonUtils.java | 36 +++
.../tobago/renderkit/html/DataAttributes.java | 2 +
.../tobago/internal/util/JsonUtilsUnitTest.java | 19 ++
.../renderer/sheet/sheet-paginatorList.html | 11 +-
.../resources/renderer/sheet/sheet-paging.html | 47 ++--
.../080-sheet/10-sort/Sheet_Sorting.test.js | 250 ++++++++++++++++-----
.../content/080-sheet/15-paginator/Paginator.xhtml | 6 +-
.../25-selection/Sheet_Selectionchange.test.js | 5 +-
.../Sheet_Margin_Bottom.test.js | 2 +-
.../38-column-selector/Column_Selector.test.js | 28 +--
.../3000-sheet/40-paginator/Paginator.xhtml | 3 +-
.../3000-sheet/80-lazy-sort/Lazy_Sort.test.js | 2 +-
.../tobago-theme-standard/src/main/js/tobago.js | 6 +-
.../src/main/js/tobago.js.map | 2 +-
.../src/main/ts/tobago-init.ts | 1 +
.../src/main/ts/tobago-paginator-list.ts | 32 +++
.../src/main/ts/tobago-paginator.ts | 70 ++++--
.../resources/tobago/test/tobago-test-tool.js | 21 +-
28 files changed, 564 insertions(+), 397 deletions(-)
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Pageable.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Pageable.java
deleted file mode 100644
index d77fda9f62..0000000000
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Pageable.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.myfaces.tobago.component;
-
-import org.apache.myfaces.tobago.internal.component.AbstractUILink;
-import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
-import org.apache.myfaces.tobago.util.ComponentUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import jakarta.faces.component.UIComponent;
-import jakarta.faces.component.behavior.AjaxBehavior;
-import jakarta.faces.context.FacesContext;
-import java.lang.invoke.MethodHandles;
-import java.util.Map;
-
-public interface Pageable {
-
- Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- String SUFFIX_PAGE_ACTION = "pageAction"; // XXX may be renamed
-
- default AbstractUILink ensurePagingCommand(
- final FacesContext facesContext, final AbstractUISheet sheet, final String facet, final String id,
- final boolean disabled) {
-
- final Map<String, UIComponent> facets = sheet.getFacets();
- AbstractUILink command = (AbstractUILink) facets.get(facet);
- if (command == null) {
- command = (AbstractUILink) ComponentUtils.createComponent(facesContext, Tags.link.componentType(),
- RendererTypes.Link, SUFFIX_PAGE_ACTION + id);
- command.setRendered(true);
- command.setDisabled(disabled);
- command.setTransient(true);
- facets.put(facet, command);
-
- // add AjaxBehavior
- final AjaxBehavior behavior = sheet.createReloadBehavior(sheet);
- command.addClientBehavior("click", behavior);
- }
- return command;
- }
-}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/event/PageActionEvent.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/event/PageActionEvent.java
index b682b402af..311d45c32b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/event/PageActionEvent.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/event/PageActionEvent.java
@@ -19,6 +19,8 @@
package org.apache.myfaces.tobago.event;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
+
import jakarta.faces.event.ActionEvent;
import jakarta.faces.component.UIComponent;
@@ -26,7 +28,7 @@ public class PageActionEvent extends ActionEvent {
private static final long serialVersionUID = 3364193750247386220L;
- private SheetAction action;
+ private final SheetAction action;
private int value;
public PageActionEvent(final UIComponent component, final SheetAction action) {
@@ -34,6 +36,15 @@ public class PageActionEvent extends ActionEvent {
this.action = action;
}
+ public PageActionEvent(final UIComponent component, final JsonUtils.SheetActionRecord sheetActionRecord) {
+ super(component);
+ this.action = sheetActionRecord.action();
+ final Integer target = sheetActionRecord.target();
+ if (target != null) {
+ this.value = target;
+ }
+ }
+
/**
* Returns the action type ({@link SheetAction}).
*/
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginator.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginator.java
index d20ce65608..95f56824cc 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginator.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginator.java
@@ -19,19 +19,21 @@
package org.apache.myfaces.tobago.internal.component;
+import org.apache.myfaces.tobago.component.SupportFieldId;
import org.apache.myfaces.tobago.component.Visual;
import org.apache.myfaces.tobago.util.ComponentUtils;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.UIOutput;
+import jakarta.faces.context.FacesContext;
-public abstract class AbstractUIPaginator extends UIOutput implements Visual {
+public abstract class AbstractUIPaginator extends UIOutput implements Visual, SupportFieldId {
public abstract String getFor();
public abstract boolean isAlwaysVisible();
- // todo: might be an interface instead of AbstractUISheet
+ // todo: might be an interface instead of AbstractUISheet
public AbstractUISheet getPageable() {
final String forId = getFor();
if (forId != null) {
@@ -42,4 +44,9 @@ public abstract class AbstractUIPaginator extends UIOutput implements Visual {
}
return ComponentUtils.findAncestor(this, AbstractUISheet.class);
}
+
+ @Override
+ public String getFieldId(final FacesContext facesContext) {
+ return getClientId(facesContext) + ComponentUtils.SUB_SEPARATOR + "field";
+ }
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
index faa029ea09..2cc6dc2665 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
@@ -20,7 +20,6 @@
package org.apache.myfaces.tobago.internal.component;
import org.apache.myfaces.tobago.component.Attributes;
-import org.apache.myfaces.tobago.component.Pageable;
import org.apache.myfaces.tobago.component.Visual;
import org.apache.myfaces.tobago.event.PageActionEvent;
import org.apache.myfaces.tobago.event.SheetAction;
@@ -81,8 +80,7 @@ import java.util.function.BiConsumer;
*/
@ListenerFor(systemEventClass = PreRenderComponentEvent.class)
public abstract class AbstractUISheet extends AbstractUIData
- implements SheetStateChangeSource, SortActionSource, ClientBehaviorHolder, Visual, Pageable,
- ComponentSystemEventListener {
+ implements SheetStateChangeSource, SortActionSource, ClientBehaviorHolder, Visual, ComponentSystemEventListener {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -698,12 +696,13 @@ public abstract class AbstractUISheet extends AbstractUIData
final String clientId = getClientId(facesContext);
final String sheetClientIdWithAction =
- clientId + UINamingContainer.getSeparatorChar(facesContext) + Pageable.SUFFIX_PAGE_ACTION + SheetAction.lazy;
+ clientId + UINamingContainer.getSeparatorChar(facesContext) + "pageAction" + SheetAction.lazy;
+// TODO: please use something like this:
+// final String sheetClientIdWithAction = clientId + ComponentUtils.SUB_SEPARATOR + SheetAction.lazy;
return sheetClientIdWithAction.equals(sourceId);
}
-
public void init(final FacesContext facesContext) {
sort(facesContext, null);
layoutHeader();
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorListRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorListRenderer.java
index d2e6c0c610..b0f11ff038 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorListRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorListRenderer.java
@@ -26,7 +26,9 @@ import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
import org.apache.myfaces.tobago.layout.Arrows;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
import org.apache.myfaces.tobago.renderkit.css.Icons;
+import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
+import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
import org.apache.myfaces.tobago.util.ComponentUtils;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import org.slf4j.Logger;
@@ -41,10 +43,6 @@ public class PaginatorListRenderer<T extends AbstractUIPaginatorList> extends Pa
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- @Override
- public void decodeInternal(final FacesContext facesContext, final T paginator) {
- }
-
@Override
public void encodeBeginInternal(final FacesContext facesContext, final T paginator) throws IOException {
@@ -58,6 +56,13 @@ public class PaginatorListRenderer<T extends AbstractUIPaginatorList> extends Pa
writer.writeClassAttribute(
visible ? null : BootstrapClass.D_NONE,
paginator.getCustomClass());
+
+ writer.startElement(HtmlElements.INPUT);
+ writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
+ writer.writeIdAttribute(paginator.getFieldId(facesContext));
+ writer.writeNameAttribute(clientId);
+ writer.endElement(HtmlElements.INPUT);
+
if (sheet != null) {
writer.startElement(HtmlElements.UL);
writer.writeClassAttribute(BootstrapClass.PAGINATION);
@@ -104,44 +109,42 @@ public class PaginatorListRenderer<T extends AbstractUIPaginatorList> extends Pa
final Arrows arrows = paginator.getArrows();
if (arrows == Arrows.show || arrows == Arrows.auto) {
final boolean disabled = sheet.isAtBeginning();
- encodeLink(
- facesContext, sheet, disabled, SheetAction.first, null, Icons.SKIP_START, null);
- encodeLink(facesContext, sheet, disabled, SheetAction.prev, null, Icons.CARET_LEFT, null);
+ encodeLink(facesContext, disabled, SheetAction.first, null, Icons.SKIP_START, null);
+ encodeLink(facesContext, disabled, SheetAction.prev, null, Icons.CARET_LEFT, null);
}
- int skip = prevs.size() > 0 ? prevs.get(0) : 1;
+ int skip = !prevs.isEmpty() ? prevs.get(0) : 1;
if (!(arrows == Arrows.show || arrows == Arrows.auto) && skip > 1) {
skip -= linkCount - (linkCount / 2);
skip--;
if (skip < 1) {
skip = 1;
}
- encodeLink(facesContext, sheet, false, SheetAction.toPage, skip, Icons.THREE_DOTS, null);
+ encodeLink(facesContext, false, SheetAction.toPage, skip, Icons.THREE_DOTS, null);
}
for (final Integer prev : prevs) {
- encodeLink(facesContext, sheet, false, SheetAction.toPage, prev, null, null);
+ encodeLink(facesContext, false, SheetAction.toPage, prev, null, null);
}
- encodeLink(facesContext, sheet, false, SheetAction.toPage,
- sheet.getCurrentPage() + 1, null, BootstrapClass.ACTIVE);
+ encodeLink(facesContext, false, SheetAction.toPage, sheet.getCurrentPage() + 1, null, BootstrapClass.ACTIVE);
for (final Integer next : nexts) {
- encodeLink(facesContext, sheet, false, SheetAction.toPage, next, null, null);
+ encodeLink(facesContext, false, SheetAction.toPage, next, null, null);
}
- skip = nexts.size() > 0 ? nexts.get(nexts.size() - 1) : pages;
+ skip = !nexts.isEmpty() ? nexts.get(nexts.size() - 1) : pages;
if (!(arrows == Arrows.show || arrows == Arrows.auto) && skip < pages) {
skip += linkCount / 2;
skip++;
if (skip > pages) {
skip = pages;
}
- encodeLink(facesContext, sheet, false, SheetAction.toPage, skip, Icons.THREE_DOTS, null);
+ encodeLink(facesContext, false, SheetAction.toPage, skip, Icons.THREE_DOTS, null);
}
if (arrows == Arrows.show || arrows == Arrows.auto) {
final boolean disabled = sheet.isAtEnd();
- encodeLink(facesContext, sheet, disabled, SheetAction.next, null, Icons.CARET_RIGHT, null);
- encodeLink(facesContext, sheet, disabled || !sheet.hasRowCount(), SheetAction.last, null,
- Icons.SKIP_END, null);
+ final boolean disabledEnd = disabled || !sheet.hasRowCount();
+ encodeLink(facesContext, disabled, SheetAction.next, null, Icons.CARET_RIGHT, null);
+ encodeLink(facesContext, disabledEnd, SheetAction.last, null, Icons.SKIP_END, null);
}
writer.endElement(HtmlElements.UL);
} else {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPageRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPageRenderer.java
index 46ebcdfef7..02775e8a65 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPageRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPageRenderer.java
@@ -21,7 +21,6 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
import org.apache.myfaces.tobago.component.Facets;
import org.apache.myfaces.tobago.event.SheetAction;
-import org.apache.myfaces.tobago.internal.component.AbstractUILink;
import org.apache.myfaces.tobago.internal.component.AbstractUIPaginatorPage;
import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
@@ -33,23 +32,14 @@ import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
import org.apache.myfaces.tobago.util.ComponentUtils;
import org.apache.myfaces.tobago.util.ResourceUtils;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import jakarta.faces.context.FacesContext;
import java.io.IOException;
-import java.lang.invoke.MethodHandles;
import java.text.MessageFormat;
import java.util.Locale;
public class PaginatorPageRenderer<T extends AbstractUIPaginatorPage> extends PaginatorRenderer<T> {
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- @Override
- public void decodeInternal(final FacesContext facesContext, final T component) {
- }
-
@Override
public void encodeBeginInternal(final FacesContext facesContext, final T paginator) throws IOException {
@@ -58,21 +48,20 @@ public class PaginatorPageRenderer<T extends AbstractUIPaginatorPage> extends Pa
final boolean visible = paginator.isAlwaysVisible() || sheet.needMoreThanOnePage();
writer.startElement(HtmlElements.TOBAGO_PAGINATOR_PAGE);
- writer.writeIdAttribute(paginator.getClientId(facesContext));
+ final String clientId = paginator.getClientId(facesContext);
+ writer.writeIdAttribute(clientId);
writer.writeClassAttribute(
visible ? null : BootstrapClass.D_NONE,
- BootstrapClass.PAGINATION,
paginator.getCustomClass());
- final AbstractUILink command
- = sheet.ensurePagingCommand(facesContext, sheet, Facets.pagerPage.name(), SheetAction.toPage.name(), false);
- final String pagerCommandId = command.getClientId(facesContext);
+ writer.startElement(HtmlElements.UL);
+ writer.writeClassAttribute(BootstrapClass.PAGINATION);
if (sheet.isShowPageRangeArrows()) {
final boolean disabled = sheet.isAtBeginning();
encodeLink(
- facesContext, sheet, disabled, SheetAction.first, null, Icons.SKIP_START, null);
- encodeLink(facesContext, sheet, disabled, SheetAction.prev, null, Icons.CARET_LEFT, null);
+ facesContext, disabled, SheetAction.first, null, Icons.SKIP_START, null);
+ encodeLink(facesContext, disabled, SheetAction.prev, null, Icons.CARET_LEFT, null);
}
writer.startElement(HtmlElements.LI);
writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
@@ -105,8 +94,8 @@ public class PaginatorPageRenderer<T extends AbstractUIPaginatorPage> extends Pa
writer.writeText(Integer.toString(first));
writer.endElement(HtmlElements.SPAN);
writer.startElement(HtmlElements.INPUT);
- writer.writeIdAttribute(pagerCommandId);
- writer.writeNameAttribute(pagerCommandId);
+ writer.writeIdAttribute(paginator.getFieldId(facesContext));
+ writer.writeNameAttribute(clientId);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
writer.writeAttribute(HtmlAttributes.VALUE, first);
if (!unknown) {
@@ -123,10 +112,11 @@ public class PaginatorPageRenderer<T extends AbstractUIPaginatorPage> extends Pa
writer.endElement(HtmlElements.LI);
if (sheet.isShowPageRangeArrows()) {
final boolean disabled = sheet.isAtEnd();
- encodeLink(facesContext, sheet, disabled, SheetAction.next, null, Icons.CARET_RIGHT, null);
- encodeLink(facesContext, sheet, disabled || !sheet.hasRowCount(), SheetAction.last, null,
- Icons.SKIP_END, null);
+ encodeLink(facesContext, disabled, SheetAction.next, null, Icons.CARET_RIGHT, null);
+ encodeLink(facesContext, disabled || !sheet.hasRowCount(), SheetAction.last, null, Icons.SKIP_END, null);
}
+
+ writer.endElement(HtmlElements.UL);
}
@Override
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRenderer.java
index 5c7ccced0d..1312a4e968 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRenderer.java
@@ -18,42 +18,64 @@
*/
package org.apache.myfaces.tobago.internal.renderkit.renderer;
-import org.apache.myfaces.tobago.component.Attributes;
+import org.apache.myfaces.tobago.event.PageActionEvent;
import org.apache.myfaces.tobago.event.SheetAction;
-import org.apache.myfaces.tobago.internal.component.AbstractUILink;
import org.apache.myfaces.tobago.internal.component.AbstractUIPaginator;
import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
+import org.apache.myfaces.tobago.internal.util.JsonUtils;
import org.apache.myfaces.tobago.renderkit.RendererBase;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
import org.apache.myfaces.tobago.renderkit.css.CssItem;
import org.apache.myfaces.tobago.renderkit.css.Icons;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlButtonTypes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
-import org.apache.myfaces.tobago.util.ComponentUtils;
import org.apache.myfaces.tobago.util.ResourceUtils;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import jakarta.faces.context.FacesContext;
import java.io.IOException;
+import java.lang.invoke.MethodHandles;
import java.text.MessageFormat;
import java.util.Locale;
+import java.util.Map;
public abstract class PaginatorRenderer<T extends AbstractUIPaginator> extends RendererBase<T> {
+ private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ @Override
+ public void decodeInternal(final FacesContext facesContext, final T paginator) {
+ final Map<String, String> requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
+ final String sourceId = requestParameterMap.get("jakarta.faces.source");
+ final String clientId = paginator.getClientId(facesContext);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("clientId {}", clientId);
+ LOG.debug("jakarta.faces.source {}", sourceId);
+ }
+ if (clientId.equals(sourceId)) {
+ final String value = requestParameterMap.get(clientId);
+ if (value != null) {
+ final AbstractUISheet sheet = paginator.getPageable();
+ if (sheet != null) {
+ final JsonUtils.SheetActionRecord sheetActionRecord = JsonUtils.decodeSheetAction(value);
+ LOG.debug("record='{}'", sheetActionRecord);
+ sheet.queueEvent(new PageActionEvent(sheet, sheetActionRecord));
+ } else {
+ LOG.warn("No sheet found for paginator {}", clientId);
+ }
+ }
+ }
+ }
+
protected void encodeLink(
- final FacesContext facesContext, final AbstractUISheet data,
+ final FacesContext facesContext,
final boolean disabled, final SheetAction action, final Integer target, final Icons icon, final CssItem liClass)
throws IOException {
- final String facet = action == SheetAction.toPage || action == SheetAction.toRow
- ? action.name() + "-" + target
- : action.name();
- final AbstractUILink command = data.ensurePagingCommand(facesContext, data, facet, facet, disabled);
- if (target != null) {
- ComponentUtils.setAttribute(command, Attributes.pagingTarget, target);
- }
-
final Locale locale = facesContext.getViewRoot().getLocale();
final String message = ResourceUtils.getString(facesContext, action.getBundleKey());
final String tip = new MessageFormat(message, locale).format(new Integer[]{target}); // needed fot ToPage
@@ -64,9 +86,9 @@ public abstract class PaginatorRenderer<T extends AbstractUIPaginator> extends R
writer.startElement(HtmlElements.BUTTON);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON);
writer.writeClassAttribute(BootstrapClass.PAGE_LINK);
- writer.writeIdAttribute(command.getClientId(facesContext));
writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
+ writer.writeAttribute(DataAttributes.ACTION, JsonUtils.encode(action, target), false);
if (icon != null) {
writer.startElement(HtmlElements.I);
writer.writeClassAttribute(icon);
@@ -74,10 +96,6 @@ public abstract class PaginatorRenderer<T extends AbstractUIPaginator> extends R
} else {
writer.writeText(String.valueOf(target));
}
- if (!disabled) {
- encodeBehavior(writer, facesContext, command);
- }
- data.getFacets().remove(facet);
writer.endElement(HtmlElements.BUTTON);
writer.endElement(HtmlElements.LI);
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRowRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRowRenderer.java
index 8a15796cb6..a9f4460575 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRowRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRowRenderer.java
@@ -19,9 +19,6 @@
package org.apache.myfaces.tobago.internal.renderkit.renderer;
-import org.apache.myfaces.tobago.component.Facets;
-import org.apache.myfaces.tobago.event.SheetAction;
-import org.apache.myfaces.tobago.internal.component.AbstractUILink;
import org.apache.myfaces.tobago.internal.component.AbstractUIPaginatorRow;
import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
import org.apache.myfaces.tobago.internal.util.StringUtils;
@@ -29,26 +26,16 @@ import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
-import org.apache.myfaces.tobago.util.ComponentUtils;
import org.apache.myfaces.tobago.util.ResourceUtils;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import jakarta.faces.context.FacesContext;
import java.io.IOException;
-import java.lang.invoke.MethodHandles;
import java.text.MessageFormat;
import java.util.Locale;
public class PaginatorRowRenderer<T extends AbstractUIPaginatorRow> extends PaginatorRenderer<T> {
- private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- @Override
- public void decodeInternal(final FacesContext facesContext, final T component) {
- }
-
@Override
public void encodeBeginInternal(final FacesContext facesContext, final T paginator) throws IOException {
@@ -57,7 +44,8 @@ public class PaginatorRowRenderer<T extends AbstractUIPaginatorRow> extends Pagi
final boolean visible = paginator.isAlwaysVisible() || sheet.needMoreThanOnePage();
writer.startElement(HtmlElements.TOBAGO_PAGINATOR_ROW);
- writer.writeIdAttribute(paginator.getClientId(facesContext));
+ final String clientId = paginator.getClientId(facesContext);
+ writer.writeIdAttribute(clientId);
writer.writeClassAttribute(
visible ? null : BootstrapClass.D_NONE,
BootstrapClass.PAGINATION,
@@ -71,10 +59,6 @@ public class PaginatorRowRenderer<T extends AbstractUIPaginatorRow> extends Pagi
BootstrapClass.PAGE_LINK,
BootstrapClass.TEXT_NOWRAP);
- final AbstractUILink command
- = sheet.ensurePagingCommand(facesContext, sheet, Facets.pagerRow.name(), SheetAction.toRow.name(), false);
- final String pagerCommandId = command.getClientId(facesContext);
-
if (sheet.getRowCount() != 0) {
final Locale locale = facesContext.getViewRoot().getLocale();
final int first = sheet.getFirst() + 1;
@@ -99,8 +83,8 @@ public class PaginatorRowRenderer<T extends AbstractUIPaginatorRow> extends Pagi
writer.writeText(Integer.toString(first));
writer.endElement(HtmlElements.SPAN);
writer.startElement(HtmlElements.INPUT);
- writer.writeIdAttribute(pagerCommandId);
- writer.writeNameAttribute(pagerCommandId);
+ writer.writeIdAttribute(paginator.getFieldId(facesContext));
+ writer.writeNameAttribute(clientId);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
writer.writeAttribute(HtmlAttributes.VALUE, first);
final int maxLength = Integer.toString(sheet.getRowCount()).length();
@@ -114,7 +98,6 @@ public class PaginatorRowRenderer<T extends AbstractUIPaginatorRow> extends Pagi
writer.writeText(formatted);
}
}
- ComponentUtils.removeFacet(sheet, Facets.pagerRow);
writer.endElement(HtmlElements.SPAN);
writer.endElement(HtmlElements.SPAN);
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
index a3839ccd92..fe86f94939 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java
@@ -22,7 +22,6 @@ package org.apache.myfaces.tobago.internal.renderkit.renderer;
import org.apache.myfaces.tobago.component.Attributes;
import org.apache.myfaces.tobago.component.Facets;
import org.apache.myfaces.tobago.component.LabelLayout;
-import org.apache.myfaces.tobago.component.Pageable;
import org.apache.myfaces.tobago.component.RendererTypes;
import org.apache.myfaces.tobago.component.Tags;
import org.apache.myfaces.tobago.component.UIOut;
@@ -30,8 +29,6 @@ import org.apache.myfaces.tobago.component.UIPaginatorList;
import org.apache.myfaces.tobago.component.UIPaginatorPage;
import org.apache.myfaces.tobago.component.UIPaginatorRow;
import org.apache.myfaces.tobago.context.Markup;
-import org.apache.myfaces.tobago.event.PageActionEvent;
-import org.apache.myfaces.tobago.event.SheetAction;
import org.apache.myfaces.tobago.event.SortActionEvent;
import org.apache.myfaces.tobago.internal.component.AbstractUIColumn;
import org.apache.myfaces.tobago.internal.component.AbstractUIColumnBase;
@@ -77,12 +74,10 @@ import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import jakarta.faces.application.Application;
import jakarta.faces.component.NamingContainer;
import jakarta.faces.component.UIColumn;
import jakarta.faces.component.UIComponent;
import jakarta.faces.component.UIData;
-import jakarta.faces.component.UINamingContainer;
import jakarta.faces.component.behavior.AjaxBehavior;
import jakarta.faces.context.FacesContext;
import java.io.IOException;
@@ -158,7 +153,6 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
}
RenderUtils.decodedStateOfTreeData(facesContext, component);
- decodeSheetAction(facesContext, component);
decodeColumnAction(facesContext, columns);
/* this will be done by the jakarta.faces.component.UIData.processDecodes() because these are facets.
for (UIComponent facet : sheet.getFacets().values()) {
@@ -183,62 +177,6 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
}
}
- private void decodeSheetAction(final FacesContext facesContext, final AbstractUISheet component) {
- final String sourceId = facesContext.getExternalContext().getRequestParameterMap().get("jakarta.faces.source");
-
- final String clientId = component.getClientId(facesContext);
- if (LOG.isDebugEnabled()) {
- LOG.debug("sourceId = '{}'", sourceId);
- LOG.debug("clientId = '{}'", clientId);
- }
-
- final String sheetClientIdWithAction
- = clientId + UINamingContainer.getSeparatorChar(facesContext) + Pageable.SUFFIX_PAGE_ACTION;
- if (sourceId != null && sourceId.startsWith(sheetClientIdWithAction)) {
- String actionString = sourceId.substring(sheetClientIdWithAction.length());
- int index = actionString.indexOf('-');
- SheetAction action;
- if (index != -1) {
- action = SheetAction.valueOf(actionString.substring(0, index));
- } else {
- action = SheetAction.valueOf(actionString);
- }
- PageActionEvent event = null;
- switch (action) {
- case first:
- case prev:
- case next:
- case last:
- event = new PageActionEvent(component, action);
- break;
- case toPage:
- case toRow:
- case lazy:
- event = new PageActionEvent(component, action);
- final int target;
- final String value;
- if (index == -1) {
- final Map<String, String> map = facesContext.getExternalContext().getRequestParameterMap();
- value = map.get(sourceId);
- } else {
- value = actionString.substring(index + 1);
- }
- try {
- target = Integer.parseInt(value);
- } catch (final NumberFormatException e) {
- LOG.error("Can't parse integer value for action " + action.name() + ": " + value);
- break;
- }
- event.setValue(target);
- break;
- default:
- }
- if (event != null) {
- component.queueEvent(event);
- }
- }
- }
-
@Override
public void encodeBeginInternal(final FacesContext facesContext, final T component) throws IOException {
@@ -247,76 +185,81 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
final TobagoResponseWriter writer = getResponseWriter(facesContext);
final PaginatorMode paginator = component.getPaginator();
- LOG.info("paginator={}", paginator);
+ LOG.debug("paginator={}", paginator);
switch (paginator) {
case list, auto -> {
- final UIPaginatorList paginatorList = (UIPaginatorList) ComponentUtils.createComponent(
- facesContext, Tags.paginatorList.componentType(), RendererTypes.PaginatorList, "_paginator_list");
- paginatorList.setTransient(true);
-
final UIComponent after = ensureAfterFacetPaginator(facesContext, component);
- after.getChildren().add(paginatorList);
+ if (after.getChildCount() == 0) {
+ final UIPaginatorList paginatorList = (UIPaginatorList) ComponentUtils.createComponent(
+ facesContext, Tags.paginatorList.componentType(), RendererTypes.PaginatorList, "_paginator_list");
+ after.getChildren().add(paginatorList);
+ }
}
case page -> {
- final UIPaginatorPage paginatorPage = (UIPaginatorPage) ComponentUtils.createComponent(
- facesContext, Tags.paginatorPage.componentType(), RendererTypes.PaginatorPage, "_paginator_page");
- paginatorPage.setTransient(true);
-
final UIComponent after = ensureAfterFacetPaginator(facesContext, component);
- after.getChildren().add(paginatorPage);
+ if (after.getChildCount() == 0) {
+ final UIPaginatorPage paginatorPage = (UIPaginatorPage) ComponentUtils.createComponent(
+ facesContext, Tags.paginatorPage.componentType(), RendererTypes.PaginatorPage, "_paginator_page");
+ after.getChildren().add(paginatorPage);
+ }
}
case row -> {
- final UIPaginatorRow paginatorRow = (UIPaginatorRow) ComponentUtils.createComponent(
- facesContext, Tags.paginatorRow.componentType(), RendererTypes.PaginatorRow, "_paginator_row");
- paginatorRow.setTransient(true);
-
final UIComponent after = ensureAfterFacetPaginator(facesContext, component);
- after.getChildren().add(paginatorRow);
- }
- case useShowAttributes -> {
- final Map<ShowPosition, AbstractUIPaginator> paginatorMap = new HashMap<>();
-
- if (!ShowPosition.none.equals(component.getShowRowRange()) && component.isPagingVisible()) {
+ if (after.getChildCount() == 0) {
final UIPaginatorRow paginatorRow = (UIPaginatorRow) ComponentUtils.createComponent(
facesContext, Tags.paginatorRow.componentType(), RendererTypes.PaginatorRow, "_paginator_row");
- paginatorRow.setAlwaysVisible(component.isShowPagingAlways());
- paginatorRow.setTransient(true);
- paginatorMap.put(component.getShowRowRange(), paginatorRow);
+ after.getChildren().add(paginatorRow);
}
+ }
+ case useShowAttributes -> {
+ boolean initialized = component.getAttributes().get("useShowAttributesInitialized") != null;
- if (!ShowPosition.none.equals(component.getShowDirectLinks()) && component.isPagingVisible()) {
- final UIPaginatorList paginatorList = (UIPaginatorList) ComponentUtils.createComponent(
- facesContext, Tags.paginatorList.componentType(), RendererTypes.PaginatorList, "_paginator_list");
- paginatorList.setAlwaysVisible(component.isShowPagingAlways());
- paginatorList.setArrows(component.isShowDirectLinksArrows()? Arrows.show : Arrows.hide);
- paginatorList.setMax(component.getDirectLinkCount());
- paginatorList.setTransient(true);
- paginatorMap.put(component.getShowDirectLinks(), paginatorList);
- }
+ if (!initialized) {
+ final Map<ShowPosition, AbstractUIPaginator> paginatorMap = new HashMap<>();
- if (!ShowPosition.none.equals(component.getShowPageRange()) && component.isPagingVisible()) {
- final UIPaginatorPage paginatorPage = (UIPaginatorPage) ComponentUtils.createComponent(
- facesContext, Tags.paginatorPage.componentType(), RendererTypes.PaginatorPage, "_paginator_page");
- paginatorPage.setAlwaysVisible(component.isShowPagingAlways());
- paginatorPage.setTransient(true);
- paginatorMap.put(component.getShowPageRange(), paginatorPage);
- }
+ final ShowPosition rangePosition = component.getShowRowRange();
+ if (!ShowPosition.none.equals(rangePosition) && component.isPagingVisible()) {
+ final UIPaginatorRow paginatorRow = (UIPaginatorRow) ComponentUtils.createComponent(
+ facesContext, Tags.paginatorRow.componentType(), RendererTypes.PaginatorRow, "_paginator_row");
+ paginatorRow.setAlwaysVisible(component.isShowPagingAlways());
+ paginatorMap.put(rangePosition, paginatorRow);
+ }
+
+ final ShowPosition listPosition = component.getShowDirectLinks();
+ if (!ShowPosition.none.equals(listPosition) && component.isPagingVisible()) {
+ final UIPaginatorList paginatorList = (UIPaginatorList) ComponentUtils.createComponent(
+ facesContext, Tags.paginatorList.componentType(), RendererTypes.PaginatorList, "_paginator_list");
+ paginatorList.setAlwaysVisible(component.isShowPagingAlways());
+ paginatorList.setArrows(component.isShowDirectLinksArrows() ? Arrows.show : Arrows.hide);
+ paginatorList.setMax(component.getDirectLinkCount());
+ paginatorMap.put(listPosition, paginatorList);
+ }
- if (!paginatorMap.isEmpty()) {
- final UIComponent after = ensureAfterFacetPaginator(facesContext, component);
+ final ShowPosition pagePosition = component.getShowPageRange();
+ if (!ShowPosition.none.equals(pagePosition) && component.isPagingVisible()) {
+ final UIPaginatorPage paginatorPage = (UIPaginatorPage) ComponentUtils.createComponent(
+ facesContext, Tags.paginatorPage.componentType(), RendererTypes.PaginatorPage, "_paginator_page");
+ paginatorPage.setAlwaysVisible(component.isShowPagingAlways());
+ paginatorMap.put(pagePosition, paginatorPage);
+ }
- final ShowPosition[] order = {ShowPosition.left, ShowPosition.center, ShowPosition.right};
- for (ShowPosition showPosition : order) {
- if (paginatorMap.containsKey(showPosition)) {
- after.getChildren().add(paginatorMap.get(showPosition));
- } else {
- final UIOut space = (UIOut) ComponentUtils.createComponent(
- facesContext, Tags.out.componentType(), RendererTypes.Out, "_space_" + showPosition.name());
- space.setTransient(true);
- after.getChildren().add(space);
+ if (!paginatorMap.isEmpty()) {
+ final UIComponent after = ensureAfterFacetPaginator(facesContext, component);
+
+ final ShowPosition[] order = {ShowPosition.left, ShowPosition.center, ShowPosition.right};
+ for (ShowPosition showPosition : order) {
+ if (paginatorMap.containsKey(showPosition)) {
+ after.getChildren().add(paginatorMap.get(showPosition));
+ } else {
+ final UIOut space = (UIOut) ComponentUtils.createComponent(
+ facesContext, Tags.out.componentType(), RendererTypes.Out, "_space_" + showPosition.name());
+ after.getChildren().add(space);
+ }
}
}
+
+ component.getAttributes().put("useShowAttributesInitialized", Boolean.TRUE);
}
}
case custom -> {
@@ -406,7 +349,6 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
final String sheetId = component.getClientId(facesContext);
final Selectable selectable = component.getSelectable();
- final Application application = facesContext.getApplication();
final SheetState state = component.getSheetState(facesContext);
final List<Integer> columnWidths = component.getState().getColumnWidths();
final boolean definedColumnWidths = component.getState().isDefinedColumnWidths();
@@ -912,8 +854,7 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
writer.writeAttribute(HtmlAttributes.TITLE, tip, true);
encodeBehavior(writer, behaviorCommands);
- if (column instanceof AbstractUIColumnSelector) {
- final AbstractUIColumnSelector selector = (AbstractUIColumnSelector) column;
+ if (column instanceof AbstractUIColumnSelector selector) {
Selectable currentSelectable = getSelectionMode(selectable, selector);
writer.startElement(HtmlElements.INPUT);
if (currentSelectable.isMulti()) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
index 0e8529bc1a..8832f0166a 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
@@ -198,7 +198,7 @@ public interface SheetTagDeclaration
void setShowDirectLinks(String showDirectLinks);
/**
- * Flag indicating whether and where the range pages should
+ * Flag indicating whether and where the range pages should be
* rendered in the sheet's footer. Rendering this range also offers the
* capability to enter the index displayed page directly.
*
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java
index 3064ac2335..3f80ea2977 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/JsonUtils.java
@@ -21,6 +21,7 @@ package org.apache.myfaces.tobago.internal.util;
import org.apache.myfaces.tobago.component.ClientBehaviors;
import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.event.SheetAction;
import org.apache.myfaces.tobago.internal.renderkit.Collapse;
import org.apache.myfaces.tobago.internal.renderkit.Command;
import org.apache.myfaces.tobago.internal.renderkit.CommandMap;
@@ -355,7 +356,42 @@ public class JsonUtils {
return builder.toString();
}
+ public static String encode(final SheetAction sheetAction, final Integer target) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("{");
+ encode(builder, "action", sheetAction.name());
+ if (target != null) {
+ encode(builder, "target", target);
+ }
+ builder.deleteCharAt(builder.length() - 1); // remove last comma
+ builder.append("}");
+ return builder.toString();
+ }
+
+ public static SheetActionRecord decodeSheetAction(final String json) {
+ if (json == null) {
+ return null;
+ }
+ SheetAction action = null;
+ Integer target = null;
+ final String[] split = json.replaceAll("[^a-zA-Z0-9]", " ").split("\\s+");
+ for (int i = 0; i < split.length - 1; i++) {
+ if (split[i].equals("action")) {
+ i++;
+ action = SheetAction.valueOf(split[i]);
+ }
+ if (split[i].equals("target")) {
+ i++;
+ target = Integer.parseInt(split[i]);
+ }
+ }
+ return new SheetActionRecord(action, target);
+ }
+
public static String encodeEmptyArray() {
return "[]";
}
+
+ // todo: rename - find a better name
+ public record SheetActionRecord(SheetAction action, Integer target) {}
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
index ad5aa76b75..625fcd6dc6 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
@@ -26,6 +26,8 @@ package org.apache.myfaces.tobago.renderkit.html;
*/
public enum DataAttributes implements MarkupLanguageAttributes {
+ ACTION("data-tobago-action"),
+
BS_CONTENT("data-bs-content"),
BS_DISMISS("data-bs-dismiss"),
BS_TOGGLE("data-bs-toggle"),
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java
index d3fcb74f8a..5fcb3a0367 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/util/JsonUtilsUnitTest.java
@@ -24,6 +24,7 @@ import org.apache.myfaces.tobago.component.ClientBehaviors;
import org.apache.myfaces.tobago.component.RendererTypes;
import org.apache.myfaces.tobago.component.Tags;
import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.event.SheetAction;
import org.apache.myfaces.tobago.internal.component.AbstractUICommand;
import org.apache.myfaces.tobago.internal.config.AbstractTobagoTestBase;
import org.apache.myfaces.tobago.internal.renderkit.Collapse;
@@ -235,6 +236,24 @@ public class JsonUtilsUnitTest extends AbstractTobagoTestBase {
Assertions.assertEquals("[]", JsonUtils.encode(new ArrayList<>()));
}
+ @Test
+ public void encodeSheetAction() {
+ final SheetAction action = SheetAction.last;
+ final Integer target = 42;
+
+ Assertions.assertEquals("{\"action\":\"last\",\"target\":42}", JsonUtils.encode(action, target));
+ Assertions.assertEquals("{\"action\":\"last\"}", JsonUtils.encode(action, null));
+ }
+
+ @Test
+ public void decodeSheetAction() {
+ JsonUtils.SheetActionRecord last = new JsonUtils.SheetActionRecord(SheetAction.last, null);
+ Assertions.assertEquals(last, JsonUtils.decodeSheetAction("{\"action\":\"last\"}"));
+
+ JsonUtils.SheetActionRecord toPage = new JsonUtils.SheetActionRecord(SheetAction.toPage, 42);
+ Assertions.assertEquals(toPage, JsonUtils.decodeSheetAction("{\"action\":\"toPage\",\"target\":42}"));
+ }
+
@Test
public void encodeEmptyArray() {
Assertions.assertEquals("[]", JsonUtils.encodeEmptyArray());
diff --git a/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html b/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html
index d90f1b3215..b1b18b8e28 100644
--- a/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html
+++ b/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html
@@ -49,21 +49,22 @@
</footer>
<tobago-paginator-panel id='sheet:panel' class='d-flex justify-content-center'>
<tobago-paginator-list id='sheet:list'>
+ <input type='hidden' id='sheet:list::field' name='sheet:list'>
<ul class='pagination'>
<li class='active page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-1' title='Page 1'>1<tobago-behavior event='click' client-id='sheet:pageActiontoPage-1' execute='sheet sheet:pageActiontoPage-1' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 1' data-tobago-action='{"action":"toPage","target":1}'>1</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-2' title='Page 2'>2<tobago-behavior event='click' client-id='sheet:pageActiontoPage-2' execute='sheet sheet:pageActiontoPage-2' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 2' data-tobago-action='{"action":"toPage","target":2}'>2</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-3' title='Page 3'>3<tobago-behavior event='click' client-id='sheet:pageActiontoPage-3' execute='sheet sheet:pageActiontoPage-3' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 3' data-tobago-action='{"action":"toPage","target":3}'>3</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-4' title='Page 4'>4<tobago-behavior event='click' client-id='sheet:pageActiontoPage-4' execute='sheet sheet:pageActiontoPage-4' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 4' data-tobago-action='{"action":"toPage","target":4}'>4</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-5' title='Page 5'>5<tobago-behavior event='click' client-id='sheet:pageActiontoPage-5' execute='sheet sheet:pageActiontoPage-5' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 5' data-tobago-action='{"action":"toPage","target":5}'>5</button>
</li>
</ul>
</tobago-paginator-list>
diff --git a/tobago-core/src/test/resources/renderer/sheet/sheet-paging.html b/tobago-core/src/test/resources/renderer/sheet/sheet-paging.html
index bc71bf407d..7650f9a5b6 100644
--- a/tobago-core/src/test/resources/renderer/sheet/sheet-paging.html
+++ b/tobago-core/src/test/resources/renderer/sheet/sheet-paging.html
@@ -49,43 +49,46 @@
</footer>
<tobago-paginator-panel id='sheet:_after' class='d-flex justify-content-between'>
<tobago-paginator-row id='sheet:_paginator_row' class='pagination'>
- <span class='page-item' title='Click here, to change the first displayed row'><span class='page-link text-nowrap'>Rows <span>1</span><input id='sheet:pageActiontoRow' name='sheet:pageActiontoRow' type='text' value='1' maxlength='2' pattern='[1-9][0-9]?'> to 2 of 10</span></span>
+ <span class='page-item' title='Click here, to change the first displayed row'><span class='page-link text-nowrap'>Rows <span>1</span><input id='sheet:_paginator_row::field' name='sheet:_paginator_row' type='text' value='1' maxlength='2' pattern='[1-9][0-9]?'> to 2 of 10</span></span>
</tobago-paginator-row>
<tobago-paginator-list id='sheet:_paginator_list'>
+ <input type='hidden' id='sheet:_paginator_list::field' name='sheet:_paginator_list'>
<ul class='pagination'>
<li class='active page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-1' title='Page 1'>1<tobago-behavior event='click' client-id='sheet:pageActiontoPage-1' execute='sheet sheet:pageActiontoPage-1' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 1' data-tobago-action='{"action":"toPage","target":1}'>1</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-2' title='Page 2'>2<tobago-behavior event='click' client-id='sheet:pageActiontoPage-2' execute='sheet sheet:pageActiontoPage-2' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 2' data-tobago-action='{"action":"toPage","target":2}'>2</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-3' title='Page 3'>3<tobago-behavior event='click' client-id='sheet:pageActiontoPage-3' execute='sheet sheet:pageActiontoPage-3' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 3' data-tobago-action='{"action":"toPage","target":3}'>3</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-4' title='Page 4'>4<tobago-behavior event='click' client-id='sheet:pageActiontoPage-4' execute='sheet sheet:pageActiontoPage-4' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 4' data-tobago-action='{"action":"toPage","target":4}'>4</button>
</li>
<li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActiontoPage-5' title='Page 5'>5<tobago-behavior event='click' client-id='sheet:pageActiontoPage-5' execute='sheet sheet:pageActiontoPage-5' render='sheet'></tobago-behavior></button>
+ <button type='button' class='page-link' title='Page 5' data-tobago-action='{"action":"toPage","target":5}'>5</button>
</li>
</ul>
</tobago-paginator-list>
- <tobago-paginator-page id='sheet:_paginator_page' class='pagination'>
- <li class='disabled page-item'>
- <button type='button' class='page-link' id='sheet:pageActionfirst' title='First Page' disabled='disabled'><i class='bi-skip-start'></i></button>
- </li>
- <li class='disabled page-item'>
- <button type='button' class='page-link' id='sheet:pageActionprev' title='Previous Page' disabled='disabled'><i class='bi-caret-left'></i></button>
- </li>
- <li class='page-item'>
- <span class='tobago-paging page-link text-nowrap' title='Click here, to change the displayed page'>Page <span>1</span><input id='sheet:pageActiontoPage' name='sheet:pageActiontoPage' type='text' value='1' maxlength='1'> of 5</span>
- </li>
- <li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActionnext' title='Next Page'><i class='bi-caret-right'></i><tobago-behavior event='click' client-id='sheet:pageActionnext' execute='sheet sheet:pageActionnext' render='sheet'></tobago-behavior></button>
- </li>
- <li class='page-item'>
- <button type='button' class='page-link' id='sheet:pageActionlast' title='Last Page'><i class='bi-skip-end'></i><tobago-behavior event='click' client-id='sheet:pageActionlast' execute='sheet sheet:pageActionlast' render='sheet'></tobago-behavior></button>
- </li>
+ <tobago-paginator-page id='sheet:_paginator_page'>
+ <ul class='pagination'>
+ <li class='disabled page-item'>
+ <button type='button' class='page-link' title='First Page' disabled='disabled' data-tobago-action='{"action":"first"}'><i class='bi-skip-start'></i></button>
+ </li>
+ <li class='disabled page-item'>
+ <button type='button' class='page-link' title='Previous Page' disabled='disabled' data-tobago-action='{"action":"prev"}'><i class='bi-caret-left'></i></button>
+ </li>
+ <li class='page-item'>
+ <span class='tobago-paging page-link text-nowrap' title='Click here, to change the displayed page'>Page <span>1</span><input id='sheet:_paginator_page::field' name='sheet:_paginator_page' type='text' value='1' maxlength='1'> of 5</span>
+ </li>
+ <li class='page-item'>
+ <button type='button' class='page-link' title='Next Page' data-tobago-action='{"action":"next"}'><i class='bi-caret-right'></i></button>
+ </li>
+ <li class='page-item'>
+ <button type='button' class='page-link' title='Last Page' data-tobago-action='{"action":"last"}'><i class='bi-skip-end'></i></button>
+ </li>
+ </ul>
</tobago-paginator-page>
</tobago-paginator-panel>
</tobago-sheet>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.test.js
index 078fae8b60..3f99a8acb9 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/10-sort/Sheet_Sorting.test.js
@@ -21,9 +21,18 @@ import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
it("Basics: Name", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s1:columnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s1 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s1:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s1:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colName sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -60,9 +69,18 @@ it("Basics: Name", function (done) {
it("Basics: Period", function (done) {
let colPeriodFn = querySelectorFn("#page\\:mainForm\\:s1\\:columnPeriod_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s1 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s1:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s1:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colPeriodFn() === null) {
+ test.fail("colPeriod sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colPeriodFn().classList.contains("tobago-ascending"),
null, "click", colPeriodFn);
@@ -99,9 +117,18 @@ it("Basics: Period", function (done) {
it("Basics: Year", function (done) {
let colYearFn = querySelectorFn("#page\\:mainForm\\:s1\\:columnDiscoverYear_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s1 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s1:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s1:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colYearFn() === null) {
+ test.fail("colYear sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colYearFn().classList.contains("tobago-ascending"),
null, "click", colYearFn);
@@ -127,16 +154,24 @@ it("Basics: Year", function (done) {
test.start();
});
-/**
- * 1. goto line 8
- * 2. goto line 9
- */
+ // 1. goto line 8
+ // 2. goto line 9
+
it("Basics: left paging", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s1:columnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s1 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s1:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s1:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colName sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -172,20 +207,28 @@ it("Basics: left paging", function (done) {
test.start();
});
-/**
- * 1. goto page 7
- * 2. goto page 16
- * 3. goto page 13
- */
+ // 1. goto page 7
+ // 2. goto page 16
+ // 3. goto page 13
+
it("Basics: center paging", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s1:columnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s1 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s1:pageActiontoRow");
- let centerPaging7Fn = elementByIdFn("page:mainForm:s1:pageActiontoPage-7");
- let centerPaging14Fn = elementByIdFn("page:mainForm:s1:pageActiontoPage-14");
- let centerPaging16Fn = elementByIdFn("page:mainForm:s1:pageActiontoPage-16");
+ let leftPagingFn = elementByIdFn("page:mainForm:s1:_paginator_row::field");
+ let centerPaging7Fn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='\\:7\\}']");
+ let centerPaging14Fn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='\\:14\\}']");
+ let centerPaging16Fn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='\\:16\\}']");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colNameFn sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -229,24 +272,44 @@ it("Basics: center paging", function (done) {
test.start();
});
-/**
- * 1. goto first page
- * 2. goto page 2 by pressing arrow-right
- * 3. goto last page
- * 4. goto page 21 by pressing arrow-left
- * 5. goto page 14
- */
+ // 1. goto first page
+ // 2. goto page 2 by pressing arrow-right
+ // 3. goto last page
+ // 4. goto page 21 by pressing arrow-left
+ // 5. goto page 14
+
it("Basics: right paging", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s1:columnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s1 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s1:pageActiontoRow");
- let rightPagingFirstFn = elementByIdFn("page:mainForm:s1:pageActionfirst");
- let rightPagingPrevFn = elementByIdFn("page:mainForm:s1:pageActionprev");
- let rightPagingNextFn = elementByIdFn("page:mainForm:s1:pageActionnext");
- let rightPagingLastFn = elementByIdFn("page:mainForm:s1:pageActionlast");
- let jumpToPageFn = elementByIdFn("page:mainForm:s1:pageActiontoPage");
+ let leftPagingFn = elementByIdFn("page:mainForm:s1:_paginator_row::field");
+ let rightPagingFirstFn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='first']");
+ let rightPagingPrevFn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='prev']");
+ let rightPagingNextFn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='next']");
+ let rightPagingLastFn = querySelectorFn("#page\\:mainForm\\:s1 [data-tobago-action*='last']");
+ let jumpToPageFn = elementByIdFn("page:mainForm:s1:_paginator_page::field");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colNameFn sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
+ if (rightPagingFirstFn() === null) {
+ test.fail("rightPagingFirst button not found!");
+ }
+ if (rightPagingPrevFn() === null) {
+ test.fail("rightPagingPrev button not found!");
+ }
+ if (rightPagingNextFn() === null) {
+ test.fail("rightPagingNext button not found!");
+ }
+ if (rightPagingLastFn() === null) {
+ test.fail("rightPagingLast button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -310,12 +373,22 @@ it("Basics: right paging", function (done) {
"Ophelia", "0.38", "1986"));
test.start();
});
+
it("Custom Sorting: Name", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s2:customColumnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s2 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s2:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s2:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colName sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -352,9 +425,18 @@ it("Custom Sorting: Name", function (done) {
it("Custom Sorting: Period", function (done) {
let colPeriodFn = querySelectorFn("#page\\:mainForm\\:s2\\:customColumnPeriod_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s2 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s2:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s2:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colPeriodFn() === null) {
+ test.fail("colPeriod sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colPeriodFn().classList.contains("tobago-ascending"),
null, "click", colPeriodFn);
@@ -391,9 +473,18 @@ it("Custom Sorting: Period", function (done) {
it("Custom Sorting: Year", function (done) {
let colYearFn = querySelectorFn("#page\\:mainForm\\:s2\\:customColumnYear_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s2 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s2:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s2:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colYearFn() === null) {
+ test.fail("colYear sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colYearFn().classList.contains("tobago-ascending"),
null, "click", colYearFn);
@@ -419,16 +510,24 @@ it("Custom Sorting: Year", function (done) {
test.start();
});
-/**
- * 1. goto line 8
- * 2. goto line 9
- */
+ // 1. goto line 8
+ // 2. goto line 9
+
it("Custom Sorting: left paging", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s2:customColumnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s2 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s2:pageActiontoRow");
+ let leftPagingFn = elementByIdFn("page:mainForm:s2:_paginator_row::field");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colName sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -464,20 +563,28 @@ it("Custom Sorting: left paging", function (done) {
test.start();
});
-/**
- * 1. goto page 7
- * 2. goto page 16
- * 3. goto page 13
- */
+ // 1. goto page 7
+ // 2. goto page 16
+ // 3. goto page 13
+
it("Custom Sorting: center paging", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s2:customColumnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s2 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s2:pageActiontoRow");
- let centerPaging7Fn = elementByIdFn("page:mainForm:s2:pageActiontoPage-7");
- let centerPaging14Fn = elementByIdFn("page:mainForm:s2:pageActiontoPage-14");
- let centerPaging16Fn = elementByIdFn("page:mainForm:s2:pageActiontoPage-16");
+ let leftPagingFn = elementByIdFn("page:mainForm:s2:_paginator_row::field");
+ let centerPaging7Fn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='\\:7\\}']");
+ let centerPaging14Fn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='\\:14\\}']");
+ let centerPaging16Fn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='\\:16\\}']");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colName sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
@@ -521,24 +628,47 @@ it("Custom Sorting: center paging", function (done) {
test.start();
});
-/**
- * 1. goto first page
- * 2. goto page 2 by pressing arrow-right
- * 3. goto last page
- * 4. goto page 21 by pressing arrow-left
- * 5. goto page 14
- */
+ // 1. goto first page
+ // 2. goto page 2 by pressing arrow-right
+ // 3. goto last page
+ // 4. goto page 21 by pressing arrow-left
+ // 5. goto page 14
+
it("Custom Sorting: right paging", function (done) {
let colNameFn = elementByIdFn("page:mainForm:s2:customColumnName_sorter");
let rowsFn = querySelectorAllFn("#page\\:mainForm\\:s2 .tobago-body tbody tr");
- let leftPagingFn = elementByIdFn("page:mainForm:s2:pageActiontoRow");
- let rightPagingFirstFn = elementByIdFn("page:mainForm:s2:pageActionfirst");
- let rightPagingPrevFn = elementByIdFn("page:mainForm:s2:pageActionprev");
- let rightPagingNextFn = elementByIdFn("page:mainForm:s2:pageActionnext");
- let rightPagingLastFn = elementByIdFn("page:mainForm:s2:pageActionlast");
- let rightPagingToPageFn = elementByIdFn("page:mainForm:s2:pageActiontoPage");
+ let leftPagingFn = elementByIdFn("page:mainForm:s2:_paginator_row::field");
+ let rightPagingFirstFn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='first']");
+ let rightPagingPrevFn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='prev']");
+ let rightPagingNextFn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='next']");
+ let rightPagingLastFn = querySelectorFn("#page\\:mainForm\\:s2 [data-tobago-action*='last']");
+ let rightPagingToPageFn = elementByIdFn("page:mainForm:s2:_paginator_page::field");
let test = new JasmineTestTool(done);
+ if (colNameFn() === null) {
+ test.fail("colName sorter not found!");
+ }
+ if (rowsFn().length !== 4) {
+ test.fail("Not 4 rows!");
+ }
+ if (leftPagingFn() === null) {
+ test.fail("leftPaging button not found!");
+ }
+ if (rightPagingFirstFn() === null) {
+ test.fail("rightPagingFirst button not found!");
+ }
+ if (rightPagingPrevFn() === null) {
+ test.fail("rightPagingPrev button not found!");
+ }
+ if (rightPagingNextFn() === null) {
+ test.fail("rightPagingNext button not found!");
+ }
+ if (rightPagingLastFn() === null) {
+ test.fail("rightPagingLast button not found!");
+ }
+ if (rightPagingToPageFn() === null) {
+ test.fail("rightPagingToPage input not found!");
+ }
test.setup(
() => colNameFn().classList.contains("tobago-ascending"),
null, "click", colNameFn);
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/15-paginator/Paginator.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/15-paginator/Paginator.xhtml
index edc800cba1..78e63dd71a 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/15-paginator/Paginator.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/15-paginator/Paginator.xhtml
@@ -38,11 +38,12 @@
</li>
</ul>
- <tc:badge markup="warning">Todo: Check if 2 or more of the same controls will work on same page!</tc:badge>
+ An alternative way to define the paginator is to use the new tags <code>tc:paginatorPanel</code>,
+ and inside of it <code>tc:paginatorRow</code>, <code>tc:paginatorList</code> and <code>tc:paginatorPage</code>.
+ This way is much more flexible, because you can define the paginators and combinations of it in any way you like.
<tc:sheet id="s1" value="#{sheetController.solarList}" var="object" rows="5"
paginator="custom">
- <!--
<f:facet name="before">
<tc:paginatorPanel>
<tc:paginatorRow />
@@ -50,7 +51,6 @@
<tc:paginatorPage />
</tc:paginatorPanel>
</f:facet>
- -->
<f:facet name="after">
<tc:paginatorPanel>
<tc:paginatorRow/>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.test.js
index 1b400a32a5..0bba82c3d9 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.test.js
@@ -27,9 +27,12 @@ it("select 'Sun', select 'Venus', select all, deselect 'Mercury'", function (don
const mercury = querySelectorFn("tr[row-index='1']");
const venus = querySelectorFn("tr[row-index='2']");
const earth = querySelectorFn("tr[row-index='3']");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
+ if (firstPageButton() === null) {
+ test.fail("firstPageButton button not found!");
+ }
test.setup(() => hiddenSelectedField().value === "[]", null, "click", resetSelected);
test.setup(() => firstPageButton().disabled, null, "click", firstPageButton);
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/30-sheet-margin-bottom/Sheet_Margin_Bottom.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/30-sheet-margin-bottom/Sheet_Margin_Bottom.test.js
index b26fbb80b2..ccd4e009b2 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/30-sheet-margin-bottom/Sheet_Margin_Bottom.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/30-sheet-margin-bottom/Sheet_Margin_Bottom.test.js
@@ -19,7 +19,7 @@ import {elementByIdFn, querySelectorFn} from "/script/tobago-test.js";
import {JasmineTestTool} from "/tobago/test/tobago-test-tool.js";
it("Margin from button to sheet/paging must be the same", function (done) {
- const sheet1pagingFn = querySelectorFn("#page\\:mainForm\\:sheet1 .ms-auto.pagination");
+ const sheet1pagingFn = querySelectorFn("#page\\:mainForm\\:sheet1 .pagination");
const button1Fn = elementByIdFn("page:mainForm:button1");
const sheet2Fn = elementByIdFn("page:mainForm:sheet2");
const button2Fn = elementByIdFn("page:mainForm:button2");
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/38-column-selector/Column_Selector.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/38-column-selector/Column_Selector.test.js
index f77e2e6013..f60bd28927 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/38-column-selector/Column_Selector.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/38-column-selector/Column_Selector.test.js
@@ -27,7 +27,7 @@ it("Default sheet: select row 2; select row4", function (done) {
const setupDefaultSheet = elementByIdFn("page:mainForm:defaultSheet");
const row2 = querySelectorFn("tr[row-index='2']");
const row4 = querySelectorFn("tr[row-index='4']");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "multi"
@@ -65,7 +65,7 @@ it("selectable=none + no column selector: select row 3 cannot happen", function
const columnPanelRendered = elementByIdFn("page:mainForm:columnPanelRendered::field");
const setupSelectableNone = elementByIdFn("page:mainForm:selectableNone");
const row3 = querySelectorFn("tr[row-index='3']");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "none"
@@ -92,8 +92,8 @@ it("selectable=single: page 1; select row 3; page 4; select row 18; page 1", fun
const selectAllCheckbox = querySelectorFn("input[name='page:mainForm:sheet::columnSelector']");
const row3 = querySelectorFn("tr[row-index='3']");
const row18 = querySelectorFn("tr[row-index='18']");
- const page4 = elementByIdFn("page:mainForm:sheet:pageActiontoPage-4");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const page4 = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='\\:4\\}']");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "single"
@@ -136,8 +136,8 @@ it("selectable=singleOrNone: page 1; select row 3; deselect row 3", function (do
const selectAllCheckbox = querySelectorFn("input[name='page:mainForm:sheet::columnSelector']");
const row3 = querySelectorFn("tr[row-index='3']");
const row18 = querySelectorFn("tr[row-index='18']");
- const page4 = elementByIdFn("page:mainForm:sheet:pageActiontoPage-4");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const page4 = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='\\:4\\}']");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "singleOrNone"
@@ -168,8 +168,8 @@ it("selectable=multi: page 1; select row 4; page 4; select row 17; page 1", func
const selectAllCheckbox = querySelectorFn("input[name='page:mainForm:sheet::columnSelector']");
const row4 = querySelectorFn("tr[row-index='4']");
const row17 = querySelectorFn("tr[row-index='17']");
- const page4 = elementByIdFn("page:mainForm:sheet:pageActiontoPage-4");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const page4 = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='\\:4\\}']");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "multi"
@@ -216,8 +216,8 @@ it("selectable=multi: select all; page 4; select row 17; page 1", function (done
const row3 = querySelectorFn("tr[row-index='3']");
const row4 = querySelectorFn("tr[row-index='4']");
const row17 = querySelectorFn("tr[row-index='17']");
- const page4 = elementByIdFn("page:mainForm:sheet:pageActiontoPage-4");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const page4 = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='\\:4\\}']");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "multi"
@@ -288,7 +288,7 @@ it("selectable=multi: select all; deselect row 3; select row 3", function (done)
const row2 = querySelectorFn("tr[row-index='2']");
const row3 = querySelectorFn("tr[row-index='3']");
const row4 = querySelectorFn("tr[row-index='4']");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "multi"
@@ -359,7 +359,7 @@ it("disabled column selector", function (done) {
const rowSelector = querySelectorFn("input[name='page:mainForm:sheet_data_row_selector_0']");
const row2 = querySelectorFn("tr[row-index='2']");
const row4 = querySelectorFn("tr[row-index='4']");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "multi"
@@ -396,8 +396,8 @@ it("column panel: page 1; select row 4; page 4; select row 17; page 1", function
const row17 = querySelectorFn("tr[row-index='17']");
const columnPanel4 = querySelectorFn(".tobago-column-panel[name='4']");
const columnPanel17 = querySelectorFn(".tobago-column-panel[name='17']");
- const page4 = elementByIdFn("page:mainForm:sheet:pageActiontoPage-4");
- const firstPageButton = elementByIdFn("page:mainForm:sheet:pageActionfirst");
+ const page4 = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='\\:4\\}']");
+ const firstPageButton = querySelectorFn("#page\\:mainForm\\:sheet [data-tobago-action*='first']");
const test = new JasmineTestTool(done);
test.setup(() => rows().value === "5" && !lazy().checked && sheetSelectable().value === "multi"
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/40-paginator/Paginator.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/40-paginator/Paginator.xhtml
index 1ae72af8d4..54cbb19cc8 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/40-paginator/Paginator.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/40-paginator/Paginator.xhtml
@@ -56,7 +56,7 @@
</tc:sheet>
</tc:section>
- <tc:section label="Page">
+ <tc:section label="Row">
<tc:sheet id="r1" value="#{sheetController.solarList}" var="object" rows="5" paginator="row">
<tc:column label="Id">
<tc:out value="#{object.id}"/>
@@ -85,5 +85,4 @@
</tc:sheet>
</tc:section>
-
</ui:composition>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/80-lazy-sort/Lazy_Sort.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/80-lazy-sort/Lazy_Sort.test.js
index 4270569070..bb88b7f15c 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/80-lazy-sort/Lazy_Sort.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/80-lazy-sort/Lazy_Sort.test.js
@@ -97,7 +97,7 @@ it("focus row index 1000 and go down", function (done) {
test.do(() => expect(isLoaded(1020)).toBeFalse());
test.do(() => focusRowIndex(1001));
- test.wait(() => isLoaded(1001));
+ test.wait(() => isLoaded(1020));
test.do(() => expect(isLoaded(999)).toBeFalse());
test.do(() => expect(isLoaded(1000, 1039)).toBeTrue());
test.do(() => expect(isLoaded(1040)).toBeFalse());
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
index 78ce2d70cf..0739bea2b2 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
@@ -4,16 +4,16 @@
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
-const pt=new Map,gt={set(e,t,s){pt.has(e)||pt.set(e,new Map);const i=pt.get(e);i.has(t)||0===i.size?i.set(t,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(i.keys())[0]}.`)},get:(e,t)=>pt.has(e)&&pt.get(e).get(t)||null,remove(e,t){if(!pt.has(e))return;const s=pt.get(e);s.delete(t),0===s.size&&pt.delete(e)}},ft="transitionend",mt=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,((e,t)=>`#${CSS.escape(t)}`))),e),b [...]
+const pt=new Map,gt={set(e,t,s){pt.has(e)||pt.set(e,new Map);const i=pt.get(e);i.has(t)||0===i.size?i.set(t,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(i.keys())[0]}.`)},get:(e,t)=>pt.has(e)&&pt.get(e).get(t)||null,remove(e,t){if(!pt.has(e))return;const s=pt.get(e);s.delete(t),0===s.size&&pt.delete(e)}},ft="transitionend",mt=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,((e,t)=>`#${CSS.escape(t)}`))),e),b [...]
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
- */const dr=globalThis,ur=dr.trustedTypes,hr=ur?ur.createPolicy("lit-html",{createHTML:e=>e}):void 0,pr="$lit$",gr=`lit$${Math.random().toFixed(9).slice(2)}$`,fr="?"+gr,mr=`<${fr}>`,br=document,vr=()=>br.createComment(""),_r=e=>null===e||"object"!=typeof e&&"function"!=typeof e,yr=Array.isArray,wr="[ \t\n\f\r]",Er=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Ar=/-->/g,Sr=/>/g,Lr=RegExp(`>|${wr}(?:([^\\s"'>=/]+)(${wr}*=${wr}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),Or=/'/g,xr [...]
+ */const ur=globalThis,hr=ur.trustedTypes,pr=hr?hr.createPolicy("lit-html",{createHTML:e=>e}):void 0,gr="$lit$",fr=`lit$${Math.random().toFixed(9).slice(2)}$`,mr="?"+fr,br=`<${mr}>`,vr=document,_r=()=>vr.createComment(""),yr=e=>null===e||"object"!=typeof e&&"function"!=typeof e,wr=Array.isArray,Er="[ \t\n\f\r]",Ar=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Sr=/-->/g,Lr=/>/g,Or=RegExp(`>|${Er}(?:([^\\s"'>=/]+)(${Er}*=${Er}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),xr=/'/g,Tr [...]
<button type='button'
class='tobago-button btn btn-secondary badge' aria-label='deselect ${e}'
${s>0?" tabindex='"+String(s)+"'":""}
@click="${this.removeBadge.bind(this)}"
@focus="${this.focusEvent.bind(this)}"
- @blur="${this.blurEvent.bind(this)}"><i class='bi-x-lg'></i></button>`}removeBadge(e){var t;const s=e.target.closest(".btn-group").dataset.tobagoValue,i=this.hiddenSelect.querySelector(`[value="${s}"]`);i.selected=!1;const n=this.badges.querySelector(`[data-tobago-value="${s}"]`),o=n.previousElementSibling,r="SPAN"===(null===(t=n.nextElementSibling)||void 0===t?void 0:t.tagName)?n.nextElementSibling:null;o?o.querySelector("button.btn.badge").focus():r?r.querySelector("button.btn.ba [...]
+ @blur="${this.blurEvent.bind(this)}"><i class='bi-x-lg'></i></button>`}removeBadge(e){var t;const s=e.target.closest(".btn-group").dataset.tobagoValue,i=this.hiddenSelect.querySelector(`[value="${s}"]`);i.selected=!1;const n=this.badges.querySelector(`[data-tobago-value="${s}"]`),o=n.previousElementSibling,r="SPAN"===(null===(t=n.nextElementSibling)||void 0===t?void 0:t.tagName)?n.nextElementSibling:null;o?o.querySelector("button.btn.badge").focus():r?r.querySelector("button.btn.ba [...]
//# sourceMappingURL=tobago.js.map
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
index 10c7a8020c..43af6bb8be 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
@@ -1 +1 @@
-{"version":3,"file":"tobago.js","sources":["../ts/tobago-css.ts","../ts/tobago-key.ts","../ts/tobago-bar.ts","../ts/tobago-date.ts","../ts/tobago-menu-store.ts","../../../../node_modules/@popperjs/core/lib/enums.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../../../node_modules/@popperjs/core/lib/modifiers/applyStyles [...]
\ No newline at end of file
+{"version":3,"file":"tobago.js","sources":["../ts/tobago-css.ts","../ts/tobago-key.ts","../ts/tobago-bar.ts","../ts/tobago-date.ts","../ts/tobago-menu-store.ts","../../../../node_modules/@popperjs/core/lib/enums.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../../../node_modules/@popperjs/core/lib/modifiers/applyStyles [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-init.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-init.ts
index 3607fa9419..117c6d6944 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-init.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-init.ts
@@ -31,6 +31,7 @@ import "./tobago-in";
import "./tobago-messages";
import "./tobago-overlay";
import "./tobago-page";
+import "./tobago-paginator-list";
import "./tobago-paginator-page";
import "./tobago-paginator-row";
import "./tobago-panel";
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-list.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-list.ts
new file mode 100644
index 0000000000..440a6fdbbb
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-list.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 {TobagoPaginator} from "./tobago-paginator";
+import {Key} from "./tobago-key";
+
+export class TobagoPaginatorList extends TobagoPaginator {
+
+ constructor() {
+ super();
+ }
+}
+
+document.addEventListener("tobago.init", function (event: Event): void {
+ if (window.customElements.get("tobago-paginator-list") == null) {
+ window.customElements.define("tobago-paginator-list", TobagoPaginatorList);
+ }
+});
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator.ts
index 893a1a1a89..253bc48b94 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator.ts
@@ -32,7 +32,7 @@ export class TobagoPaginator extends HTMLElement {
}
get input(): HTMLInputElement {
- return this.querySelector(".page-link input");
+ return this.querySelector("input");
}
get sheet(): HTMLElement {
@@ -45,29 +45,42 @@ export class TobagoPaginator extends HTMLElement {
}
}
+ get buttons(): NodeListOf<Element> {
+ return this.querySelectorAll("li.page-item:not(.disabled)>button");
+ }
+
+ get action(): HTMLInputElement {
+ return this.querySelector("input[type=hidden]");
+ }
+
connectedCallback(): void {
- console.warn("register -------------- click on paging", this.tagName);
- this.text.addEventListener("click", this.clickOnPaging.bind(this));
+ const text = this.text;
+ if (text) {
+ text.addEventListener("click", this.clickOnPaging.bind(this));
+ }
const input = this.input;
- console.warn("register -------------- blur on paging", this.tagName);
- input.addEventListener("blur", this.blurPaging.bind(this));
-
- console.warn("register -------------- keydown on paging", this.tagName);
- input.addEventListener("keydown", function (event: KeyboardEvent): void {
- if (event.key === Key.ENTER) {
- event.stopPropagation();
- event.preventDefault();
- event.currentTarget.dispatchEvent(new Event("blur"));
- }
- }.bind(this));
+ if (input) {
+ input.addEventListener("blur", this.blurPaging.bind(this));
+ input.addEventListener("keydown", function (event: KeyboardEvent): void {
+ if (event.key === Key.ENTER) {
+ event.stopPropagation();
+ event.preventDefault();
+ event.currentTarget.dispatchEvent(new Event("blur"));
+ }
+ }.bind(this));
+ }
+
+ const buttons = this.buttons;
+ if (buttons) {
+ buttons.forEach(item => item.addEventListener("click", this.clickOnButton.bind(this)));
+ }
}
clickOnPaging(event: MouseEvent): void {
const output: HTMLElement = this.output;
output.style.display = "none";
- console.warn("execute -------------- click on paging", this.tagName);
const input: HTMLInputElement = this.input;
input.style.display = "initial";
input.focus();
@@ -75,15 +88,16 @@ export class TobagoPaginator extends HTMLElement {
}
blurPaging(event: FocusEvent): void {
- console.warn("execute -------------- blur on paging", this.tagName);
const input = event.currentTarget as HTMLInputElement;
const output: HTMLElement = this.output;
const number = Number.parseInt(input.value); // sanitizing
if (number > 0 && number.toString() !== output.innerHTML) {
console.debug("Reloading sheet '%s' old value='%s' new value='%s'", this.id, output.innerHTML, number);
output.innerHTML = number.toString();
+ const action = this.tagName == "TOBAGO-PAGINATOR-ROW" ? "toRow" : "toPage";
+ input.value = `{"action":"${action}","target":${number}}`;
faces.ajax.request(
- input.id,
+ this.id,
null,
{
params: {
@@ -94,9 +108,25 @@ export class TobagoPaginator extends HTMLElement {
});
} else {
console.info("no update needed");
- input.value = output.innerHTML;
- input.style.display = "none";
- output.style.display = "initial";
}
+ input.style.display = "none";
+ output.style.display = "initial";
+ }
+
+ clickOnButton(event: MouseEvent): void {
+ const button = event.currentTarget as HTMLButtonElement;
+ const input = this.input;
+ input.value = button.dataset.tobagoAction;
+
+ faces.ajax.request(
+ this.id,
+ null,
+ {
+ params: {
+ "javax.faces.behavior.event": "reload"
+ },
+ execute: this.sheet.id,
+ render: this.sheet.id
+ });
}
}
diff --git a/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js b/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js
index 9aeeb98e64..4acb96c4b1 100644
--- a/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js
+++ b/tobago-tool/tobago-tool-test/src/main/resources/META-INF/resources/tobago/test/tobago-test-tool.js
@@ -65,6 +65,7 @@ class JasmineTestTool {
done;
timeout;
waitTimestamp;
+ message;
/**
* @param done function from Jasmine; must called if all Steps done or timeout
@@ -75,6 +76,13 @@ class JasmineTestTool {
this.timeout = timeout ? timeout : 20000;
}
+ /**
+ * Set hard to fail!
+ */
+ fail(message) {
+ this.message = message;
+ }
+
/**
* Setup a test.
* @param startConditionFn the desired start condition
@@ -195,10 +203,21 @@ class JasmineTestTool {
const timeout = this.timeout;
let lastStepExecution;
+ if (this.message != null) {
+ fail(this.message);
+ done();
+ return;
+ }
+
console.debug("[JasmineTestTool] start");
registerAjaxReadyStateListener();
resetTimeout();
- cycle();
+ try {
+ cycle();
+ } catch (e) {
+ fail(e);
+ done();
+ }
function cycle() {
const nextStep = getNextStep();