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/11/04 15:26:56 UTC
(myfaces-tobago) branch main updated: feat: Reimplement paginator for sheet (#5675)
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 69b26f8453 feat: Reimplement paginator for sheet (#5675)
69b26f8453 is described below
commit 69b26f84531ac558732cac73f563037fdda888e1
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Mon Nov 4 16:26:51 2024 +0100
feat: Reimplement paginator for sheet (#5675)
* feat: Reimplement paginator for sheet
issue: TOBAGO-2243
---
README.md | 4 +
.../myfaces/tobago/component/Attributes.java | 3 +
.../apache/myfaces/tobago/component/Pageable.java | 60 +++
.../myfaces/tobago/component/RendererTypes.java | 8 +
.../org/apache/myfaces/tobago/component/Tags.java | 8 +
.../internal/component/AbstractUIPaginator.java | 45 ++
.../component/AbstractUIPaginatorList.java | 28 ++
.../component/AbstractUIPaginatorPage.java | 23 +
.../component/AbstractUIPaginatorPanel.java | 23 +
.../internal/component/AbstractUIPaginatorRow.java | 23 +
.../tobago/internal/component/AbstractUISheet.java | 44 +-
.../renderkit/renderer/PaginatorListRenderer.java | 157 +++++++
.../renderkit/renderer/PaginatorPageRenderer.java | 137 ++++++
.../renderkit/renderer/PaginatorPanelRenderer.java | 55 +++
.../renderkit/renderer/PaginatorRenderer.java | 85 ++++
.../renderkit/renderer/PaginatorRowRenderer.java | 127 ++++++
.../internal/renderkit/renderer/SheetRenderer.java | 468 ++++++---------------
.../component/PaginatorListTagDeclaration.java | 58 +++
.../component/PaginatorPageTagDeclaration.java | 58 +++
.../component/PaginatorPanelTagDeclaration.java | 52 +++
.../component/PaginatorRowTagDeclaration.java | 48 +++
.../taglib/component/SheetTagDeclaration.java | 81 +++-
.../internal/taglib/declaration/HasArrows.java | 39 ++
.../taglib/declaration/IsAlwaysVisible.java | 33 ++
.../org/apache/myfaces/tobago/layout/Arrows.java | 61 +++
.../myfaces/tobago/layout/PaginatorMode.java | 86 ++++
.../tobago/renderkit/css/BootstrapClass.java | 1 +
.../tobago/renderkit/html/HtmlElements.java | 4 +
.../internal/config/AbstractTobagoTestBase.java | 25 +-
.../renderkit/renderer/SheetRendererUnitTest.java | 38 ++
.../myfaces/tobago/layout/ArrowsUnitTest.java | 31 ++
.../tobago/layout/PaginatorModeUnitTest.java | 31 ++
.../renderer/sheet/sheet-paginatorList.html | 71 ++++
.../resources/renderer/sheet/sheet-paging.html | 54 +--
.../myfaces/tobago/example/demo/AstroData.java | 7 +-
.../tobago/example/demo/SheetController.java | 17 +
.../myfaces/tobago/example/demo/SolarObject.java | 18 +-
.../content/080-sheet/15-paginator/Paginator.xhtml | 78 ++++
.../3000-sheet/40-paginator/Paginator.xhtml | 89 ++++
.../Paginator_Backward_Compatibility.xhtml | 217 ++++++++++
tobago-theme/src/main/scss/_tobago.scss | 73 ++++
.../src/main/css/tobago.css | 36 ++
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../src/main/css/tobago.css | 36 ++
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../src/main/css/tobago.css | 36 ++
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../tobago-theme-speyside/src/main/css/tobago.css | 36 ++
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../tobago-theme-standard/src/main/css/tobago.css | 36 ++
.../src/main/css/tobago.css.map | 2 +-
.../src/main/css/tobago.min.css | 2 +-
.../src/main/css/tobago.min.css.map | 2 +-
.../tobago-theme-standard/src/main/js/tobago.js | 8 +-
.../src/main/js/tobago.js.map | 2 +-
.../src/main/ts/tobago-init.ts | 2 +
.../src/main/ts/tobago-page.ts | 10 +-
.../src/main/ts/tobago-paginator-page.ts | 31 ++
.../src/main/ts/tobago-paginator-row.ts | 31 ++
.../src/main/ts/tobago-paginator.ts | 102 +++++
.../src/main/ts/tobago-sheet.ts | 11 +
.../org/apache/myfaces/tobago/apt/component.stg | 8 +
70 files changed, 2573 insertions(+), 410 deletions(-)
diff --git a/README.md b/README.md
index 4dc41d1a88..e5d25e5cc5 100644
--- a/README.md
+++ b/README.md
@@ -62,6 +62,10 @@ If you want to run the demo locally you need to run the following command
mvn -f tobago-example/tobago-example-demo/pom.xml clean package tomee:run -Ptomee -Pdev
```
+* Mode 1: old | compatible | classic | useShowAttributes
+* Mode 2: auto
+* Mode 3: custom
+
Browse to the local URL http://localhost:8080/
You can also run the demo with different servers and JSF implementations
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
index f329628a1a..03b89f3a8c 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
@@ -37,6 +37,8 @@ public enum Attributes {
align,
alignItems,
alt,
+ alwaysVisible,
+ arrows,
autocomplete,
autoReload,
autoSpacing,
@@ -324,6 +326,7 @@ public enum Attributes {
* Used by a layout manager
*/
paddingTop,
+ paginator,
pagingTarget,
password,
placeholder,
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
new file mode 100644
index 0000000000..d77fda9f62
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Pageable.java
@@ -0,0 +1,60 @@
+/*
+ * 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/component/RendererTypes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
index bad01f551a..b7643cf2e9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
@@ -57,6 +57,10 @@ public enum RendererTypes {
Operation,
Out,
Page,
+ PaginatorList,
+ PaginatorPage,
+ PaginatorPanel,
+ PaginatorRow,
Panel,
Popover,
Popup,
@@ -131,6 +135,10 @@ public enum RendererTypes {
public static final String OPERATION = "Operation";
public static final String OUT = "Out";
public static final String PAGE = "Page";
+ public static final String PAGINATOR_LIST = "PaginatorList";
+ public static final String PAGINATOR_PAGE = "PaginatorPage";
+ public static final String PAGINATOR_PANEL = "PaginatorPanel";
+ public static final String PAGINATOR_ROW = "PaginatorRow";
public static final String PANEL = "Panel";
public static final String POPOVER = "Popover";
public static final String POPUP = "Popup";
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
index a49cee0068..273fab6bc2 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
@@ -62,6 +62,10 @@ public enum Tags {
operation,
out,
page,
+ paginatorList,
+ paginatorPage,
+ paginatorPanel,
+ paginatorRow,
panel,
popover,
popup,
@@ -138,6 +142,10 @@ public enum Tags {
public static final String OPERATION = "operation";
public static final String OUT = "out";
public static final String PAGE = "page";
+ public static final String PAGINATOR_LIST = "paginatorList";
+ public static final String PAGINATOR_PAGE = "paginatorPage";
+ public static final String PAGINATOR_PANEL = "paginatorPanel";
+ public static final String PAGINATOR_ROW = "paginatorRow";
public static final String PANEL = "panel";
public static final String POPOVER = "popover";
public static final String POPUP = "popup";
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
new file mode 100644
index 0000000000..d20ce65608
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.internal.component;
+
+import org.apache.myfaces.tobago.component.Visual;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+
+import jakarta.faces.component.UIComponent;
+import jakarta.faces.component.UIOutput;
+
+public abstract class AbstractUIPaginator extends UIOutput implements Visual {
+
+ public abstract String getFor();
+
+ public abstract boolean isAlwaysVisible();
+
+ // todo: might be an interface instead of AbstractUISheet
+ public AbstractUISheet getPageable() {
+ final String forId = getFor();
+ if (forId != null) {
+ final UIComponent component = findComponent(forId);
+ if (component != null) {
+ return (AbstractUISheet) component;
+ }
+ }
+ return ComponentUtils.findAncestor(this, AbstractUISheet.class);
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorList.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorList.java
new file mode 100644
index 0000000000..619a885f19
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorList.java
@@ -0,0 +1,28 @@
+/*
+ * 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.internal.component;
+
+import org.apache.myfaces.tobago.layout.Arrows;
+
+public abstract class AbstractUIPaginatorList extends AbstractUIPaginator {
+
+ public abstract Arrows getArrows();
+
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorPage.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorPage.java
new file mode 100644
index 0000000000..3d22f1515f
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorPage.java
@@ -0,0 +1,23 @@
+/*
+ * 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.internal.component;
+
+public abstract class AbstractUIPaginatorPage extends AbstractUIPaginator {
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorPanel.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorPanel.java
new file mode 100644
index 0000000000..39ab1911ee
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorPanel.java
@@ -0,0 +1,23 @@
+/*
+ * 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.internal.component;
+
+public abstract class AbstractUIPaginatorPanel extends AbstractUIPanelBase {
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorRow.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorRow.java
new file mode 100644
index 0000000000..26cc7c0f69
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIPaginatorRow.java
@@ -0,0 +1,23 @@
+/*
+ * 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.internal.component;
+
+public abstract class AbstractUIPaginatorRow extends AbstractUIPaginator {
+}
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 d7d5974667..6036c9115a 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,6 +20,7 @@
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.SheetStateChangeEvent;
@@ -32,6 +33,7 @@ import org.apache.myfaces.tobago.internal.layout.OriginCell;
import org.apache.myfaces.tobago.internal.util.SortingUtils;
import org.apache.myfaces.tobago.layout.Measure;
import org.apache.myfaces.tobago.layout.MeasureList;
+import org.apache.myfaces.tobago.layout.PaginatorMode;
import org.apache.myfaces.tobago.layout.ShowPosition;
import org.apache.myfaces.tobago.model.ExpandedState;
import org.apache.myfaces.tobago.model.ScrollPosition;
@@ -46,6 +48,8 @@ import jakarta.el.MethodExpression;
import jakarta.el.ValueExpression;
import jakarta.faces.component.UIColumn;
import jakarta.faces.component.UIComponent;
+import jakarta.faces.component.behavior.AjaxBehavior;
+import jakarta.faces.component.behavior.ClientBehavior;
import jakarta.faces.component.behavior.ClientBehaviorHolder;
import jakarta.faces.context.FacesContext;
import jakarta.faces.event.AbortProcessingException;
@@ -66,7 +70,7 @@ import java.util.List;
*/
@ListenerFor(systemEventClass = PreRenderComponentEvent.class)
public abstract class AbstractUISheet extends AbstractUIData
- implements SheetStateChangeSource, SortActionSource, ClientBehaviorHolder, Visual,
+ implements SheetStateChangeSource, SortActionSource, ClientBehaviorHolder, Visual, Pageable,
ComponentSystemEventListener {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -568,6 +572,34 @@ public abstract class AbstractUISheet extends AbstractUIData
this.lazyFirstRow = lazyFirstRow;
}
+ public AjaxBehavior createReloadBehavior(final AbstractUISheet sheet) {
+ final AjaxBehavior reloadBehavior = findReloadBehavior(sheet);
+ final ArrayList<String> renderIds = new ArrayList<>();
+ renderIds.add(sheet.getId());
+ if (reloadBehavior != null) {
+ renderIds.addAll(reloadBehavior.getRender());
+ }
+ final ArrayList<String> executeIds = new ArrayList<>();
+ executeIds.add(sheet.getId());
+ if (reloadBehavior != null) {
+ executeIds.addAll(reloadBehavior.getExecute());
+ }
+ final AjaxBehavior behavior = new AjaxBehavior();
+ behavior.setExecute(executeIds);
+ behavior.setRender(renderIds);
+ behavior.setTransient(true);
+ return behavior;
+ }
+
+ private AjaxBehavior findReloadBehavior(final ClientBehaviorHolder holder) {
+ final List<ClientBehavior> reload = holder.getClientBehaviors().get("reload");
+ if (reload != null && !reload.isEmpty() && reload.get(0) instanceof AjaxBehavior) {
+ return (AjaxBehavior) reload.get(0);
+ } else {
+ return null;
+ }
+ }
+
@Override
public boolean isRendersRowContainer() {
return true;
@@ -593,19 +625,29 @@ public abstract class AbstractUISheet extends AbstractUIData
this.headerGrid = headerGrid;
}
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
public abstract boolean isShowDirectLinksArrows();
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
public abstract boolean isShowPageRangeArrows();
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
public abstract ShowPosition getShowRowRange();
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
public abstract ShowPosition getShowPageRange();
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
public abstract ShowPosition getShowDirectLinks();
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
+ public abstract Integer getDirectLinkCount();
+
public abstract boolean isLazy();
public abstract Integer getMaxSortColumns();
public abstract Integer getLazyRows();
+
+ public abstract PaginatorMode getPaginator();
}
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
new file mode 100644
index 0000000000..d2e6c0c610
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorListRenderer.java
@@ -0,0 +1,157 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.component.Attributes;
+import org.apache.myfaces.tobago.event.SheetAction;
+import org.apache.myfaces.tobago.internal.component.AbstractUIPaginatorList;
+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.HtmlElements;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+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.util.ArrayList;
+
+public class PaginatorListRenderer<T extends AbstractUIPaginatorList> extends PaginatorRenderer<T> {
+
+ 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 {
+
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ final String clientId = paginator.getClientId(facesContext);
+ final AbstractUISheet sheet = paginator.getPageable();
+ final boolean visible = paginator.isAlwaysVisible() || sheet.needMoreThanOnePage();
+
+ writer.startElement(HtmlElements.TOBAGO_PAGINATOR_LIST);
+ writer.writeIdAttribute(clientId);
+ writer.writeClassAttribute(
+ visible ? null : BootstrapClass.D_NONE,
+ paginator.getCustomClass());
+ if (sheet != null) {
+ writer.startElement(HtmlElements.UL);
+ writer.writeClassAttribute(BootstrapClass.PAGINATION);
+
+ int linkCount = ComponentUtils.getIntAttribute(sheet, Attributes.directLinkCount);
+ linkCount--; // current page needs no link
+ final ArrayList<Integer> prevs = new ArrayList<>(linkCount);
+ int page = sheet.getCurrentPage() + 1;
+ for (int i = 0; i < linkCount && page > 1; i++) {
+ page--;
+ if (page > 0) {
+ prevs.add(0, page);
+ }
+ }
+
+ final ArrayList<Integer> nexts = new ArrayList<>(linkCount);
+ page = sheet.getCurrentPage() + 1;
+ final int pages = sheet.hasRowCount() || sheet.isRowsUnlimited() ? sheet.getPages() : Integer.MAX_VALUE;
+ for (int i = 0; i < linkCount && page < pages; i++) {
+ page++;
+ if (page > 1) {
+ nexts.add(page);
+ }
+ }
+
+ if (prevs.size() > (linkCount / 2)
+ && nexts.size() > (linkCount - (linkCount / 2))) {
+ while (prevs.size() > (linkCount / 2)) {
+ prevs.remove(0);
+ }
+ while (nexts.size() > (linkCount - (linkCount / 2))) {
+ nexts.remove(nexts.size() - 1);
+ }
+ } else if (prevs.size() <= (linkCount / 2)) {
+ while (prevs.size() + nexts.size() > linkCount) {
+ nexts.remove(nexts.size() - 1);
+ }
+ } else {
+ while (prevs.size() + nexts.size() > linkCount) {
+ prevs.remove(0);
+ }
+ }
+
+ 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);
+ }
+
+ int skip = prevs.size() > 0 ? 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);
+ }
+ for (final Integer prev : prevs) {
+ encodeLink(facesContext, sheet, false, SheetAction.toPage, prev, null, null);
+ }
+ encodeLink(facesContext, sheet, false, SheetAction.toPage,
+ sheet.getCurrentPage() + 1, null, BootstrapClass.ACTIVE);
+
+ for (final Integer next : nexts) {
+ encodeLink(facesContext, sheet, false, SheetAction.toPage, next, null, null);
+ }
+
+ skip = nexts.size() > 0 ? 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);
+ }
+ 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);
+ }
+ writer.endElement(HtmlElements.UL);
+ } else {
+ LOG.warn("No sheet found for paginator with clientId='{}'!", clientId);
+ }
+ }
+
+ @Override
+ public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ writer.endElement(HtmlElements.TOBAGO_PAGINATOR_LIST);
+ }
+}
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
new file mode 100644
index 0000000000..46ebcdfef7
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPageRenderer.java
@@ -0,0 +1,137 @@
+/*
+ * 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.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;
+import org.apache.myfaces.tobago.renderkit.css.Icons;
+import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+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 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 {
+
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ final AbstractUISheet sheet = paginator.getPageable();
+ final boolean visible = paginator.isAlwaysVisible() || sheet.needMoreThanOnePage();
+
+ writer.startElement(HtmlElements.TOBAGO_PAGINATOR_PAGE);
+ writer.writeIdAttribute(paginator.getClientId(facesContext));
+ 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);
+
+ 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);
+ }
+ writer.startElement(HtmlElements.LI);
+ writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
+ writer.startElement(HtmlElements.SPAN);
+ writer.writeClassAttribute(
+ TobagoClass.PAGING,
+ BootstrapClass.PAGE_LINK,
+ BootstrapClass.TEXT_NOWRAP);
+ writer.writeAttribute(HtmlAttributes.TITLE,
+ ResourceUtils.getString(facesContext, "sheet.setPage"), true);
+ if (sheet.getRowCount() != 0) {
+ final Locale locale = facesContext.getViewRoot().getLocale();
+ final int first = sheet.getCurrentPage() + 1;
+ final boolean unknown = !sheet.hasRowCount();
+ final int pages = unknown ? -1 : sheet.getPages();
+ final String key;
+ if (unknown) {
+ key = first == pages ? "sheet.pageX" : "sheet.pageXtoY";
+ } else {
+ key = first == pages ? "sheet.pageXofZ" : "sheet.pageXtoYofZ";
+ }
+ final String inputMarker = "{#}";
+ final Object[] args = {inputMarker, pages == -1 ? "?" : pages};
+ final MessageFormat detail = new MessageFormat(ResourceUtils.getString(facesContext, key), locale);
+ final String formatted = detail.format(args);
+ final int pos = formatted.indexOf(inputMarker);
+ if (pos >= 0) {
+ writer.writeText(formatted.substring(0, pos));
+ writer.startElement(HtmlElements.SPAN);
+ writer.writeText(Integer.toString(first));
+ writer.endElement(HtmlElements.SPAN);
+ writer.startElement(HtmlElements.INPUT);
+ writer.writeIdAttribute(pagerCommandId);
+ writer.writeNameAttribute(pagerCommandId);
+ writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
+ writer.writeAttribute(HtmlAttributes.VALUE, first);
+ if (!unknown) {
+ writer.writeAttribute(HtmlAttributes.MAXLENGTH, Integer.toString(pages).length());
+ }
+ writer.endElement(HtmlElements.INPUT);
+ writer.writeText(formatted.substring(pos + inputMarker.length()));
+ } else {
+ writer.writeText(formatted);
+ }
+ }
+ ComponentUtils.removeFacet(sheet, Facets.pagerPage);
+ writer.endElement(HtmlElements.SPAN);
+ 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);
+ }
+ }
+
+ @Override
+ public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ writer.endElement(HtmlElements.TOBAGO_PAGINATOR_PAGE);
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPanelRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPanelRenderer.java
new file mode 100644
index 0000000000..367eb4c3d8
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorPanelRenderer.java
@@ -0,0 +1,55 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.internal.component.AbstractUIPaginatorPanel;
+import org.apache.myfaces.tobago.renderkit.RendererBase;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+
+import jakarta.faces.context.FacesContext;
+import java.io.IOException;
+
+public class PaginatorPanelRenderer<T extends AbstractUIPaginatorPanel> extends RendererBase<T> {
+
+ @Override
+ public void decodeInternal(final FacesContext facesContext, final T component) {
+ }
+
+ @Override
+ public void encodeBeginInternal(final FacesContext facesContext, final T paginator) throws IOException {
+
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ writer.startElement(HtmlElements.TOBAGO_PAGINATOR_PANEL);
+ writer.writeIdAttribute(paginator.getClientId(facesContext));
+ final int childCount = paginator.getChildCount();
+ writer.writeClassAttribute(
+ BootstrapClass.D_FLEX,
+ childCount > 1 ? BootstrapClass.JUSTIFY_CONTENT_BETWEEN : BootstrapClass.JUSTIFY_CONTENT_CENTER,
+ paginator.getCustomClass());
+ }
+
+ @Override
+ public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ writer.endElement(HtmlElements.TOBAGO_PAGINATOR_PANEL);
+ }
+}
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
new file mode 100644
index 0000000000..5c7ccced0d
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRenderer.java
@@ -0,0 +1,85 @@
+/*
+ * 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.internal.renderkit.renderer;
+
+import org.apache.myfaces.tobago.component.Attributes;
+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.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.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 jakarta.faces.context.FacesContext;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Locale;
+
+public abstract class PaginatorRenderer<T extends AbstractUIPaginator> extends RendererBase<T> {
+
+ protected void encodeLink(
+ final FacesContext facesContext, final AbstractUISheet data,
+ 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
+
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ writer.startElement(HtmlElements.LI);
+ writer.writeClassAttribute(liClass, disabled ? BootstrapClass.DISABLED : null, BootstrapClass.PAGE_ITEM);
+ 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);
+ if (icon != null) {
+ writer.startElement(HtmlElements.I);
+ writer.writeClassAttribute(icon);
+ writer.endElement(HtmlElements.I);
+ } 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
new file mode 100644
index 0000000000..8a15796cb6
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/PaginatorRowRenderer.java
@@ -0,0 +1,127 @@
+/*
+ * 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.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;
+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 {
+
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ final AbstractUISheet sheet = paginator.getPageable();
+ final boolean visible = paginator.isAlwaysVisible() || sheet.needMoreThanOnePage();
+
+ writer.startElement(HtmlElements.TOBAGO_PAGINATOR_ROW);
+ writer.writeIdAttribute(paginator.getClientId(facesContext));
+ writer.writeClassAttribute(
+ visible ? null : BootstrapClass.D_NONE,
+ BootstrapClass.PAGINATION,
+ paginator.getCustomClass());
+ writer.startElement(HtmlElements.SPAN);
+ writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
+ writer.writeAttribute(HtmlAttributes.TITLE,
+ ResourceUtils.getString(facesContext, "sheet.setRow"), true);
+ writer.startElement(HtmlElements.SPAN);
+ writer.writeClassAttribute(
+ 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;
+ final int last1 = sheet.hasRowCount()
+ ? sheet.getLastRowIndexOfCurrentPage()
+ : -1;
+ final boolean unknown = !sheet.hasRowCount();
+ final String key; // plural
+ if (unknown) {
+ key = first == last1 ? "sheet.rowX" : "sheet.rowXtoY";
+ } else {
+ key = first == last1 ? "sheet.rowXofZ" : "sheet.rowXtoYofZ";
+ }
+ final String inputMarker = "{#}";
+ final Object[] args = {inputMarker, last1 == -1 ? "?" : last1, unknown ? "" : sheet.getRowCount()};
+ final MessageFormat detail = new MessageFormat(ResourceUtils.getString(facesContext, key), locale);
+ final String formatted = detail.format(args);
+ final int pos = formatted.indexOf(inputMarker);
+ if (pos >= 0) {
+ writer.writeText(formatted.substring(0, pos));
+ writer.startElement(HtmlElements.SPAN);
+ writer.writeText(Integer.toString(first));
+ writer.endElement(HtmlElements.SPAN);
+ writer.startElement(HtmlElements.INPUT);
+ writer.writeIdAttribute(pagerCommandId);
+ writer.writeNameAttribute(pagerCommandId);
+ writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
+ writer.writeAttribute(HtmlAttributes.VALUE, first);
+ final int maxLength = Integer.toString(sheet.getRowCount()).length();
+ if (!unknown) {
+ writer.writeAttribute(HtmlAttributes.MAXLENGTH, maxLength);
+ }
+ writer.writeAttribute(HtmlAttributes.PATTERN, StringUtils.positiveNumberRegexp(maxLength), true);
+ writer.endElement(HtmlElements.INPUT);
+ writer.writeText(formatted.substring(pos + inputMarker.length()));
+ } else {
+ writer.writeText(formatted);
+ }
+ }
+ ComponentUtils.removeFacet(sheet, Facets.pagerRow);
+ writer.endElement(HtmlElements.SPAN);
+ writer.endElement(HtmlElements.SPAN);
+ }
+
+ @Override
+ public void encodeEndInternal(final FacesContext facesContext, final T component) throws IOException {
+ final TobagoResponseWriter writer = getResponseWriter(facesContext);
+ writer.endElement(HtmlElements.TOBAGO_PAGINATOR_ROW);
+ }
+}
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 61593ea266..60c92e603a 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
@@ -19,22 +19,16 @@
package org.apache.myfaces.tobago.internal.renderkit.renderer;
-import jakarta.el.ValueExpression;
-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.component.behavior.ClientBehavior;
-import jakarta.faces.component.behavior.ClientBehaviorHolder;
-import jakarta.faces.context.FacesContext;
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;
+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;
@@ -47,6 +41,7 @@ import org.apache.myfaces.tobago.internal.component.AbstractUIColumnSelector;
import org.apache.myfaces.tobago.internal.component.AbstractUIData;
import org.apache.myfaces.tobago.internal.component.AbstractUILink;
import org.apache.myfaces.tobago.internal.component.AbstractUIOut;
+import org.apache.myfaces.tobago.internal.component.AbstractUIPaginator;
import org.apache.myfaces.tobago.internal.component.AbstractUIReload;
import org.apache.myfaces.tobago.internal.component.AbstractUIRow;
import org.apache.myfaces.tobago.internal.component.AbstractUISheet;
@@ -58,7 +53,8 @@ import org.apache.myfaces.tobago.internal.renderkit.CommandMap;
import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
import org.apache.myfaces.tobago.internal.util.JsonUtils;
import org.apache.myfaces.tobago.internal.util.RenderUtils;
-import org.apache.myfaces.tobago.internal.util.StringUtils;
+import org.apache.myfaces.tobago.layout.Arrows;
+import org.apache.myfaces.tobago.layout.PaginatorMode;
import org.apache.myfaces.tobago.layout.ShowPosition;
import org.apache.myfaces.tobago.layout.TextAlign;
import org.apache.myfaces.tobago.model.ExpandedState;
@@ -70,13 +66,11 @@ import org.apache.myfaces.tobago.model.TreePath;
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.css.TobagoClass;
import org.apache.myfaces.tobago.renderkit.html.Arias;
import org.apache.myfaces.tobago.renderkit.html.CustomAttributes;
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.renderkit.html.HtmlInputTypes;
import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -85,13 +79,21 @@ import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.el.ValueExpression;
+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;
import java.lang.invoke.MethodHandles;
-import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -105,7 +107,6 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
private static final String SUFFIX_SELECTED = ComponentUtils.SUB_SEPARATOR + "selected";
private static final String SUFFIX_LAZY = NamingContainer.SEPARATOR_CHAR + "pageActionlazy";
private static final String SUFFIX_LAZY_SCROLL_POSITION = ComponentUtils.SUB_SEPARATOR + "lazyScrollPosition";
- private static final String SUFFIX_PAGE_ACTION = "pageAction";
private static final String SUFFIX_COLUMN_SELECTOR = ComponentUtils.SUB_SEPARATOR + "columnSelector";
@Override
@@ -193,7 +194,7 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
}
final String sheetClientIdWithAction
- = clientId + UINamingContainer.getSeparatorChar(facesContext) + SUFFIX_PAGE_ACTION;
+ = clientId + UINamingContainer.getSeparatorChar(facesContext) + Pageable.SUFFIX_PAGE_ACTION;
if (sourceId != null && sourceId.startsWith(sheetClientIdWithAction)) {
String actionString = sourceId.substring(sheetClientIdWithAction.length());
int index = actionString.indexOf('-');
@@ -245,7 +246,85 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
final String sheetId = component.getClientId(facesContext);
final Markup markup = component.getMarkup();
final TobagoResponseWriter writer = getResponseWriter(facesContext);
- final AbstractUIReload reload = ComponentUtils.getReloadFacet(component);
+
+ final PaginatorMode paginator = component.getPaginator();
+ LOG.info("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);
+ }
+ 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);
+ }
+ 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()) {
+ 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);
+ }
+
+ 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 (!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);
+ }
+
+ 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());
+ space.setTransient(true);
+ after.getChildren().add(space);
+ }
+ }
+ }
+ }
+ case custom -> {
+ // nothing to do
+ }
+ default -> throw new IllegalStateException("Unknown paginator mode: " + paginator);
+ }
UIComponent header = component.getHeader();
if (header == null) {
@@ -303,11 +382,23 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
encodeBehavior(writer, facesContext, component);
+ final AbstractUIReload reload = ComponentUtils.getReloadFacet(component);
if (reload != null) {
reload.encodeAll(facesContext);
}
}
+ private static <T extends AbstractUISheet> UIComponent ensureAfterFacetPaginator(
+ final FacesContext facesContext, final T component) {
+ UIComponent after = component.getFacet(Facets.AFTER);
+ if (after == null) {
+ after = ComponentUtils.createComponent(
+ facesContext, Tags.paginatorPanel.componentType(), RendererTypes.PaginatorPanel, "_after");
+ component.getFacets().put(Facets.AFTER, after);
+ }
+ return after;
+ }
+
@Override
public void encodeChildrenInternal(final FacesContext facesContext, final T component) throws IOException {
for (final UIComponent child : component.getChildren()) {
@@ -372,169 +463,14 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
if (component.isPagingVisible()) {
writer.startElement(HtmlElements.FOOTER);
-
- // show row range
- final ShowPosition showPositionRowRange = component.getShowRowRange();
- if (showPositionRowRange != ShowPosition.none) {
- final AbstractUILink command
- = ensurePagingCommand(facesContext, component, Facets.pagerRow.name(), SheetAction.toRow.name(), false);
- final String pagerCommandId = command.getClientId(facesContext);
-
- writer.startElement(HtmlElements.UL);
- writer.writeClassAttribute(
- cssForLeftCenterRight(showPositionRowRange),
- BootstrapClass.PAGINATION);
- writer.startElement(HtmlElements.LI);
- writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
- writer.writeAttribute(HtmlAttributes.TITLE,
- ResourceUtils.getString(facesContext, "sheet.setRow"), true);
- writer.startElement(HtmlElements.SPAN);
- writer.writeClassAttribute(
- TobagoClass.PAGING,
- BootstrapClass.PAGE_LINK);
- if (component.getRowCount() != 0) {
- final Locale locale = facesContext.getViewRoot().getLocale();
- final int first = component.getFirst() + 1;
- final int last1 = component.hasRowCount()
- ? component.getLastRowIndexOfCurrentPage()
- : -1;
- final boolean unknown = !component.hasRowCount();
- final String key; // plural
- if (unknown) {
- key = first == last1 ? "sheet.rowX" : "sheet.rowXtoY";
- } else {
- key = first == last1 ? "sheet.rowXofZ" : "sheet.rowXtoYofZ";
- }
- final String inputMarker = "{#}";
- final Object[] args = {inputMarker, last1 == -1 ? "?" : last1, unknown ? "" : component.getRowCount()};
- final MessageFormat detail = new MessageFormat(ResourceUtils.getString(facesContext, key), locale);
- final String formatted = detail.format(args);
- final int pos = formatted.indexOf(inputMarker);
- if (pos >= 0) {
- writer.writeText(formatted.substring(0, pos));
- writer.startElement(HtmlElements.SPAN);
- writer.writeText(Integer.toString(first));
- writer.endElement(HtmlElements.SPAN);
- writer.startElement(HtmlElements.INPUT);
- writer.writeIdAttribute(pagerCommandId);
- writer.writeNameAttribute(pagerCommandId);
- writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
- writer.writeAttribute(HtmlAttributes.VALUE, first);
- final int maxLength = Integer.toString(component.getRowCount()).length();
- if (!unknown) {
- writer.writeAttribute(HtmlAttributes.MAXLENGTH, maxLength);
- }
- writer.writeAttribute(HtmlAttributes.PATTERN, StringUtils.positiveNumberRegexp(maxLength), true);
- writer.endElement(HtmlElements.INPUT);
- writer.writeText(formatted.substring(pos + inputMarker.length()));
- } else {
- writer.writeText(formatted);
- }
- }
- ComponentUtils.removeFacet(component, Facets.pagerRow);
- writer.endElement(HtmlElements.SPAN);
- writer.endElement(HtmlElements.LI);
- writer.endElement(HtmlElements.UL);
- }
-
- // show direct links
- final ShowPosition showPositionDirectLinks = component.getShowDirectLinks();
- if (showPositionDirectLinks != ShowPosition.none) {
- writer.startElement(HtmlElements.UL);
- writer.writeClassAttribute(
- cssForLeftCenterRight(showPositionDirectLinks),
- BootstrapClass.PAGINATION);
- if (component.isShowDirectLinksArrows()) {
- final boolean disabled = component.isAtBeginning();
- encodeLink(
- facesContext, component, application, disabled, SheetAction.first, null, Icons.SKIP_START, null);
- encodeLink(facesContext, component, application, disabled, SheetAction.prev, null, Icons.CARET_LEFT, null);
- }
- encodeDirectPagingLinks(facesContext, application, component);
- if (component.isShowDirectLinksArrows()) {
- final boolean disabled = component.isAtEnd();
- encodeLink(facesContext, component, application, disabled, SheetAction.next, null, Icons.CARET_RIGHT, null);
- encodeLink(facesContext, component, application, disabled || !component.hasRowCount(), SheetAction.last, null,
- Icons.SKIP_END, null);
- }
- writer.endElement(HtmlElements.UL);
- }
-
- // show page range
- final ShowPosition showPositionPageRange = component.getShowPageRange();
- if (showPositionPageRange != ShowPosition.none) {
- final AbstractUILink command
- = ensurePagingCommand(facesContext, component, Facets.pagerPage.name(), SheetAction.toPage.name(), false);
- final String pagerCommandId = command.getClientId(facesContext);
-
- writer.startElement(HtmlElements.UL);
- writer.writeClassAttribute(
- cssForLeftCenterRight(showPositionPageRange),
- BootstrapClass.PAGINATION);
- if (component.isShowPageRangeArrows()) {
- final boolean disabled = component.isAtBeginning();
- encodeLink(
- facesContext, component, application, disabled, SheetAction.first, null, Icons.SKIP_START, null);
- encodeLink(facesContext, component, application, disabled, SheetAction.prev, null, Icons.CARET_LEFT, null);
- }
- writer.startElement(HtmlElements.LI);
- writer.writeClassAttribute(BootstrapClass.PAGE_ITEM);
- writer.startElement(HtmlElements.SPAN);
- writer.writeClassAttribute(
- TobagoClass.PAGING,
- BootstrapClass.PAGE_LINK);
- writer.writeAttribute(HtmlAttributes.TITLE,
- ResourceUtils.getString(facesContext, "sheet.setPage"), true);
- if (component.getRowCount() != 0) {
- final Locale locale = facesContext.getViewRoot().getLocale();
- final int first = component.getCurrentPage() + 1;
- final boolean unknown = !component.hasRowCount();
- final int pages = unknown ? -1 : component.getPages();
- final String key;
- if (unknown) {
- key = first == pages ? "sheet.pageX" : "sheet.pageXtoY";
- } else {
- key = first == pages ? "sheet.pageXofZ" : "sheet.pageXtoYofZ";
- }
- final String inputMarker = "{#}";
- final Object[] args = {inputMarker, pages == -1 ? "?" : pages};
- final MessageFormat detail = new MessageFormat(ResourceUtils.getString(facesContext, key), locale);
- final String formatted = detail.format(args);
- final int pos = formatted.indexOf(inputMarker);
- if (pos >= 0) {
- writer.writeText(formatted.substring(0, pos));
- writer.startElement(HtmlElements.SPAN);
- writer.writeText(Integer.toString(first));
- writer.endElement(HtmlElements.SPAN);
- writer.startElement(HtmlElements.INPUT);
- writer.writeIdAttribute(pagerCommandId);
- writer.writeNameAttribute(pagerCommandId);
- writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
- writer.writeAttribute(HtmlAttributes.VALUE, first);
- if (!unknown) {
- writer.writeAttribute(HtmlAttributes.MAXLENGTH, Integer.toString(pages).length());
- }
- writer.endElement(HtmlElements.INPUT);
- writer.writeText(formatted.substring(pos + inputMarker.length()));
- } else {
- writer.writeText(formatted);
- }
- }
- ComponentUtils.removeFacet(component, Facets.pagerPage);
- writer.endElement(HtmlElements.SPAN);
- writer.endElement(HtmlElements.LI);
- if (component.isShowPageRangeArrows()) {
- final boolean disabled = component.isAtEnd();
- encodeLink(facesContext, component, application, disabled, SheetAction.next, null, Icons.CARET_RIGHT, null);
- encodeLink(facesContext, component, application, disabled || !component.hasRowCount(), SheetAction.last, null,
- Icons.SKIP_END, null);
- }
- writer.endElement(HtmlElements.UL);
- }
-
writer.endElement(HtmlElements.FOOTER);
}
+ final UIComponent after = component.getFacet(Facets.AFTER);
+ if (after != null) {
+ after.encodeAll(facesContext);
+ }
+
if (component.isTreeModel()) {
writer.startElement(HtmlElements.INPUT);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
@@ -565,6 +501,11 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
final Markup sheetMarkup = sheet.getMarkup() != null ? sheet.getMarkup() : Markup.NULL;
final ExpandedState expandedState = sheet.isTreeModel() ? sheet.getExpandedState() : null;
+ final UIComponent before = sheet.getFacet(Facets.BEFORE);
+ if (before != null) {
+ before.encodeAll(facesContext);
+ }
+
if (showHeader && !autoLayout) {
// if no autoLayout, we render the header in a separate table.
@@ -915,7 +856,7 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
sortCommand = (AbstractUILink) ComponentUtils.createComponent(
facesContext, Tags.link.componentType(), RendererTypes.Link, sorterId);
sortCommand.setTransient(true);
- final AjaxBehavior reloadBehavior = createReloadBehavior(sheet);
+ final AjaxBehavior reloadBehavior = sheet.createReloadBehavior(sheet);
sortCommand.addClientBehavior("click", reloadBehavior);
ComponentUtils.setFacet(column, Facets.sorter, sortCommand);
}
@@ -1108,51 +1049,6 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
return selected;
}
- private void encodeLink(
- final FacesContext facesContext, final AbstractUISheet data, final Application application,
- 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 = 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
-
- final TobagoResponseWriter writer = getResponseWriter(facesContext);
- writer.startElement(HtmlElements.LI);
- writer.writeClassAttribute(liClass, disabled ? BootstrapClass.DISABLED : null, BootstrapClass.PAGE_ITEM);
- 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);
- if (icon != null) {
- writer.startElement(HtmlElements.I);
- writer.writeClassAttribute(icon);
- writer.endElement(HtmlElements.I);
- } else {
- writer.writeText(String.valueOf(target));
- }
- if (!disabled) {
- encodeBehavior(writer, facesContext, command);
- }
- data.getFacets().remove(facet);
- writer.endElement(HtmlElements.BUTTON);
- writer.endElement(HtmlElements.LI);
- }
-
- // TODO sheet.getColumnLayout() may return the wrong number of column...
- // TODO
- // TODO
-
private void encodeResizing(final TobagoResponseWriter writer, final AbstractUISheet sheet, final int columnIndex)
throws IOException {
writer.startElement(HtmlElements.SPAN);
@@ -1161,126 +1057,4 @@ public class SheetRenderer<T extends AbstractUISheet> extends RendererBase<T> {
writer.write(" "); // is needed for IE
writer.endElement(HtmlElements.SPAN);
}
-
- private void encodeDirectPagingLinks(
- final FacesContext facesContext, final Application application, final AbstractUISheet sheet)
- throws IOException {
-
- int linkCount = ComponentUtils.getIntAttribute(sheet, Attributes.directLinkCount);
- linkCount--; // current page needs no link
- final ArrayList<Integer> prevs = new ArrayList<>(linkCount);
- int page = sheet.getCurrentPage() + 1;
- for (int i = 0; i < linkCount && page > 1; i++) {
- page--;
- if (page > 0) {
- prevs.add(0, page);
- }
- }
-
- final ArrayList<Integer> nexts = new ArrayList<>(linkCount);
- page = sheet.getCurrentPage() + 1;
- final int pages = sheet.hasRowCount() || sheet.isRowsUnlimited() ? sheet.getPages() : Integer.MAX_VALUE;
- for (int i = 0; i < linkCount && page < pages; i++) {
- page++;
- if (page > 1) {
- nexts.add(page);
- }
- }
-
- if (prevs.size() > (linkCount / 2)
- && nexts.size() > (linkCount - (linkCount / 2))) {
- while (prevs.size() > (linkCount / 2)) {
- prevs.remove(0);
- }
- while (nexts.size() > (linkCount - (linkCount / 2))) {
- nexts.remove(nexts.size() - 1);
- }
- } else if (prevs.size() <= (linkCount / 2)) {
- while (prevs.size() + nexts.size() > linkCount) {
- nexts.remove(nexts.size() - 1);
- }
- } else {
- while (prevs.size() + nexts.size() > linkCount) {
- prevs.remove(0);
- }
- }
-
- int skip = prevs.size() > 0 ? prevs.get(0) : 1;
- if (!sheet.isShowDirectLinksArrows() && skip > 1) {
- skip -= linkCount - (linkCount / 2);
- skip--;
- if (skip < 1) {
- skip = 1;
- }
- encodeLink(facesContext, sheet, application, false, SheetAction.toPage, skip, Icons.THREE_DOTS, null);
- }
- for (final Integer prev : prevs) {
- encodeLink(facesContext, sheet, application, false, SheetAction.toPage, prev, null, null);
- }
- encodeLink(facesContext, sheet, application, false, SheetAction.toPage,
- sheet.getCurrentPage() + 1, null, BootstrapClass.ACTIVE);
-
- for (final Integer next : nexts) {
- encodeLink(facesContext, sheet, application, false, SheetAction.toPage, next, null, null);
- }
-
- skip = nexts.size() > 0 ? nexts.get(nexts.size() - 1) : pages;
- if (!sheet.isShowDirectLinksArrows() && skip < pages) {
- skip += linkCount / 2;
- skip++;
- if (skip > pages) {
- skip = pages;
- }
- encodeLink(facesContext, sheet, application, false, SheetAction.toPage, skip, Icons.THREE_DOTS, null);
- }
- }
-
- private 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 = createReloadBehavior(sheet);
- command.addClientBehavior("click", behavior);
- }
- return command;
- }
-
- private AjaxBehavior createReloadBehavior(final AbstractUISheet sheet) {
- final AjaxBehavior reloadBehavior = findReloadBehavior(sheet);
- final ArrayList<String> renderIds = new ArrayList<>();
- renderIds.add(sheet.getId());
- if (reloadBehavior != null) {
- renderIds.addAll(reloadBehavior.getRender());
- }
- final ArrayList<String> executeIds = new ArrayList<>();
- executeIds.add(sheet.getId());
- if (reloadBehavior != null) {
- executeIds.addAll(reloadBehavior.getExecute());
- }
- final AjaxBehavior behavior = new AjaxBehavior();
- behavior.setExecute(executeIds);
- behavior.setRender(renderIds);
- behavior.setTransient(true);
- return behavior;
- }
-
- private AjaxBehavior findReloadBehavior(final ClientBehaviorHolder holder) {
- final List<ClientBehavior> reload = holder.getClientBehaviors().get("reload");
- if (reload != null && !reload.isEmpty() && reload.get(0) instanceof AjaxBehavior) {
- return (AjaxBehavior) reload.get(0);
- } else {
- return null;
- }
- }
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorListTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorListTagDeclaration.java
new file mode 100644
index 0000000000..fed7c0429f
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorListTagDeclaration.java
@@ -0,0 +1,58 @@
+/*
+ * 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.internal.taglib.component;
+
+import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasArrows;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasFor;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsAlwaysVisible;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
+
+import jakarta.faces.component.UIOutput;
+
+/**
+ * Renders a paginator for direct links.
+ */
+@Tag(name = "paginatorList")
+@UIComponentTag(
+ uiComponent = "org.apache.myfaces.tobago.component.UIPaginatorList",
+ uiComponentFacesClass = "jakarta.faces.component.UIOutput",
+ componentFamily = UIOutput.COMPONENT_FAMILY,
+ rendererType = RendererTypes.PAGINATOR_LIST,
+ allowedChildComponenents = "NONE"
+)
+
+public interface PaginatorListTagDeclaration
+ extends HasIdBindingAndRendered, HasTip, IsVisual, IsAlwaysVisible, HasArrows, HasFor {
+
+ /**
+ * Show this amount of links, if available.
+ */
+ @TagAttribute
+ @UIComponentTagAttribute(
+ type = {"java.lang.Integer"})
+ void setMax(String max);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorPageTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorPageTagDeclaration.java
new file mode 100644
index 0000000000..1b575a819c
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorPageTagDeclaration.java
@@ -0,0 +1,58 @@
+/*
+ * 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.internal.taglib.component;
+
+import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasArrows;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasFor;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsAlwaysVisible;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
+
+import jakarta.faces.component.UIOutput;
+
+/**
+ * Renders a paginator to show and change the page number.
+ */
+@Tag(name = "paginatorPage")
+@UIComponentTag(
+ uiComponent = "org.apache.myfaces.tobago.component.UIPaginatorPage",
+ uiComponentFacesClass = "jakarta.faces.component.UIOutput",
+ componentFamily = UIOutput.COMPONENT_FAMILY,
+ rendererType = RendererTypes.PAGINATOR_PAGE,
+ allowedChildComponenents = "NONE"
+)
+
+public interface PaginatorPageTagDeclaration
+ extends HasIdBindingAndRendered, HasTip, IsVisual, IsAlwaysVisible, HasArrows, HasFor {
+
+ /**
+ * Show this amount of links, if available.
+ */
+ @TagAttribute
+ @UIComponentTagAttribute(
+ type = {"java.lang.Integer"})
+ void setMax(String max);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorPanelTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorPanelTagDeclaration.java
new file mode 100644
index 0000000000..31f9681ddc
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorPanelTagDeclaration.java
@@ -0,0 +1,52 @@
+/*
+ * 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.internal.taglib.component;
+
+import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasFor;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsAlwaysVisible;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
+
+import jakarta.faces.component.UIOutput;
+
+/**
+ * Renders a panel to put paginators in it.
+ */
+@Tag(name = "paginatorPanel")
+@UIComponentTag(
+ uiComponent = "org.apache.myfaces.tobago.component.UIPaginatorPanel",
+ uiComponentFacesClass = "jakarta.faces.component.UIOutput",
+ componentFamily = UIOutput.COMPONENT_FAMILY,
+ rendererType = RendererTypes.PAGINATOR_PANEL,
+ allowedChildComponenents = {
+ "org.apache.myfaces.tobago.PaginatorList",
+ "org.apache.myfaces.tobago.PaginatorPage",
+ "org.apache.myfaces.tobago.PaginatorRow"
+ }
+)
+
+public interface PaginatorPanelTagDeclaration
+ extends HasIdBindingAndRendered, HasTip, IsVisual, IsReadonly, IsAlwaysVisible, HasFor {
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorRowTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorRowTagDeclaration.java
new file mode 100644
index 0000000000..f4ece58fe6
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/PaginatorRowTagDeclaration.java
@@ -0,0 +1,48 @@
+/*
+ * 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.internal.taglib.component;
+
+import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasFor;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsAlwaysVisible;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
+
+import jakarta.faces.component.UIOutput;
+
+/**
+ * Renders a paginator to show and change the row position.
+ */
+@Tag(name = "paginatorRow")
+@UIComponentTag(
+ uiComponent = "org.apache.myfaces.tobago.component.UIPaginatorRow",
+ uiComponentFacesClass = "jakarta.faces.component.UIOutput",
+ componentFamily = UIOutput.COMPONENT_FAMILY,
+ rendererType = RendererTypes.PAGINATOR_ROW,
+ allowedChildComponenents = "NONE"
+)
+
+public interface PaginatorRowTagDeclaration
+ extends HasIdBindingAndRendered, HasTip, IsVisual, IsReadonly, IsAlwaysVisible, HasFor {
+}
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 4affc52cd7..9af7a4d4ac 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
@@ -36,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasVar;
import org.apache.myfaces.tobago.internal.taglib.declaration.IsShowRoot;
import org.apache.myfaces.tobago.internal.taglib.declaration.IsShowRootJunction;
import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
+import org.apache.myfaces.tobago.layout.PaginatorMode;
import org.apache.myfaces.tobago.layout.ShowPosition;
import org.apache.myfaces.tobago.model.Selectable;
@@ -58,7 +59,14 @@ import jakarta.faces.component.UIData;
@Facet(
name = Facets.RELOAD,
description = "Contains an instance of UIReload",
- allowedChildComponenents = "org.apache.myfaces.tobago.Reload")},
+ allowedChildComponenents = "org.apache.myfaces.tobago.Reload"),
+ @Facet(
+ name = Facets.BEFORE,
+ description = "Components to be rendered before the sheet, e.g. paginators"),
+ @Facet(
+ name = Facets.AFTER,
+ description = "Components to be rendered after the sheet, e.g. paginators")
+ },
behaviors = {
@Behavior(
name = ClientBehaviors.RELOAD, // XXX replace by click
@@ -154,14 +162,20 @@ public interface SheetTagDeclaration
* </ul>
* <li>showPagingAlways="true" means, that the paging footer should be displayed in any case.
* </ul>
+ *
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(type = "boolean", defaultValue = "false")
void setShowPagingAlways(String showPagingAlways);
/**
- * The count of rendered direct paging links in the sheet's footer.<br>
+ * The count of rendered direct paging links in the sheet's footer.
+ *
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(type = "java.lang.Integer", defaultValue = "9")
void setDirectLinkCount(String directLinkCount);
@@ -169,7 +183,10 @@ public interface SheetTagDeclaration
/**
* Flag indicating whether or not a range of direct paging links should be
* rendered in the sheet's footer.
+ *
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(
type = "org.apache.myfaces.tobago.layout.ShowPosition",
@@ -184,7 +201,10 @@ public interface SheetTagDeclaration
* Flag indicating whether and where the range pages should
* rendered in the sheet's footer. Rendering this range also offers the
* capability to enter the index displayed page directly.
+ *
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(
type = "org.apache.myfaces.tobago.layout.ShowPosition",
@@ -199,7 +219,10 @@ public interface SheetTagDeclaration
* Flag indicating whether or not the range of displayed rows should
* rendered in the sheet's footer. Rendering this range also offers the
* capability to enter the index of the start row directly.
+ *
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(
type = "org.apache.myfaces.tobago.layout.ShowPosition",
@@ -276,13 +299,15 @@ public interface SheetTagDeclaration
*/
@TagAttribute
@UIComponentTagAttribute(type = "java.lang.Integer", defaultValue = "50")
- void setLazyRows(String lazy);
+ void setLazyRows(String lazyRows);
/**
* Flag indicating if paging arrows are shown near direct links
*
* @since 2.0.0
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(type = "boolean", defaultValue = "false")
void setShowDirectLinksArrows(String showDirectLinksArrows);
@@ -291,7 +316,9 @@ public interface SheetTagDeclaration
* Flag indicating if paging arrows are shown near page range
*
* @since 2.0.0
+ * @deprecated Use paginator attribute or paginator tags instead.
*/
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
@TagAttribute
@UIComponentTagAttribute(type = "boolean", defaultValue = "true")
void setShowPageRangeArrows(String showPageRangeArrows);
@@ -305,4 +332,52 @@ public interface SheetTagDeclaration
@UIComponentTagAttribute(type = "java.lang.Integer", defaultValue = "0")
void setMaxSortColumns(String maxSortColumns);
+ /**
+ * Create paginator components automatically or do it manually.
+ * <ul>
+ * <li>
+ * <b>custom</b>: no paginator is created automatically, you have to do it manually.
+ * This can be done
+ * using a <code><tc:paginatorPanel></code>
+ * with e.g. a <code><tc:paginatorList></code> and/or some other
+ * paginator components.
+ * </li>
+ * <li>
+ * <b>auto</b>: a appropriate paginator is used.
+ * </li>
+ * <li>
+ * <b>list</b>: a <code><tc:paginatorList></code> is used.
+ * </li>
+ * <li>
+ * <b>page</b>: a <code><tc:paginatorPage></code> is used.
+ * </li>
+ * <li>
+ * <b>row</b>: a <code><tc:paginatorRow></code> is used.
+ * </li>
+ * <li>
+ * <b>useShowAttributes</b> (default):
+ * is deprecated, use for compatibility.
+ * The used paginators are defined by the show-attributes:
+ * <code>showDirectLinks</code>,
+ * <code>showPageRange</code>,
+ * <code>showRowRange</code>,
+ * <code>directLinkCount</code>,
+ * <code>showDirectLinksArrows</code>,
+ * <code>showPageRangeArrows</code>,
+ * <code>showPagingAlways</code>.
+ * </li>
+ * </ul>
+ *
+ * @since 5.15.0, 6.7.0
+ */
+ @TagAttribute
+ @UIComponentTagAttribute(
+ type = "org.apache.myfaces.tobago.layout.PaginatorMode",
+ defaultValue = PaginatorMode.USE_SHOW_ATTRIBUTES,
+ allowedValues = {
+ PaginatorMode.AUTO, PaginatorMode.CUSTOM, PaginatorMode.LIST, PaginatorMode.PAGE, PaginatorMode.ROW,
+ PaginatorMode.USE_SHOW_ATTRIBUTES
+ },
+ defaultCode = "org.apache.myfaces.tobago.layout.PaginatorMode.useShowAttributes")
+ void setPaginator(String paginator);
}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/HasArrows.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/HasArrows.java
new file mode 100644
index 0000000000..618dab48a8
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/HasArrows.java
@@ -0,0 +1,39 @@
+/*
+ * 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.internal.taglib.declaration;
+
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
+import org.apache.myfaces.tobago.layout.Arrows;
+
+public interface HasArrows {
+ /**
+ * Show arrows at this control.
+ */
+ @TagAttribute
+ @UIComponentTagAttribute(
+ type = "org.apache.myfaces.tobago.layout.Arrows",
+ defaultValue = Arrows.AUTO,
+ allowedValues = {
+ Arrows.AUTO, Arrows.SHOW, Arrows.HIDE
+ },
+ defaultCode = "org.apache.myfaces.tobago.layout.Arrows.auto")
+ void setArrows(String arrows);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/IsAlwaysVisible.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/IsAlwaysVisible.java
new file mode 100644
index 0000000000..8a72daa13e
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/IsAlwaysVisible.java
@@ -0,0 +1,33 @@
+/*
+ * 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.internal.taglib.declaration;
+
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
+
+public interface IsAlwaysVisible {
+ /**
+ * Flag indicating that the control show should be displayed in call cases,
+ * whether it is necessary or not (if there are a low number of rows).
+ */
+ @TagAttribute
+ @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
+ void setAlwaysVisible(String alwaysVisible);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Arrows.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Arrows.java
new file mode 100644
index 0000000000..3c333df3c8
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/Arrows.java
@@ -0,0 +1,61 @@
+/*
+ * 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.layout;
+
+/**
+ * Show Arrows, or not.
+ *
+ * @since 5.15.0, 6.7.0
+ */
+public enum Arrows {
+
+ /**
+ * Show arrows at this control.
+ */
+ show,
+
+ /**
+ * Hide arrows at this control.
+ */
+ hide,
+
+ /**
+ * Arrows will be shown automatically (currently the same as {@link #show}).
+ */
+ auto;
+
+ public static final String SHOW = "show";
+ public static final String HIDE = "hide";
+ public static final String AUTO = "auto";
+
+ /**
+ * @param name Name of the Arrows.
+ * @throws IllegalArgumentException When the name doesn't match any {@link Arrows}.
+ */
+ public static Arrows parse(final Object name) throws IllegalArgumentException {
+ if (name == null) {
+ return null;
+ }
+ if (name instanceof Arrows) {
+ return (Arrows) name;
+ }
+ return valueOf(name.toString());
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/PaginatorMode.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/PaginatorMode.java
new file mode 100644
index 0000000000..a7c9581742
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/layout/PaginatorMode.java
@@ -0,0 +1,86 @@
+/*
+ * 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.layout;
+
+/**
+ * Describes the mode of automatically displayed paginator.
+ *
+ * @since 5.15.0, 6.7.0
+ */
+public enum PaginatorMode {
+
+ /**
+ * A paginator is selected and displayed automatically.
+ * Will be the default in future versions.
+ */
+ auto,
+
+ /**
+ * If a paginator is desired, it must be specified on the page, e.g. with a
+ * <code><tc:paginatorList></code> inside of a <code><tc:paginatorPanel></code> tag.
+ */
+ custom,
+
+ /**
+ * The paginator is displayed as a list.
+ */
+ list,
+
+ /**
+ * The page can be selected directly.
+ */
+ page,
+
+ /**
+ * The row can be selected directly.
+ */
+ row,
+
+ /**
+ * The show attributes of the sheet (e.g. showDirectLinks, showPageRange, showPageLinks, showRowCount)
+ * are used to display the paginator. This is the default, and emulates the old behavior.
+ *
+ * @deprecated Please use {@link #auto} if possible, or write a custom paginator.
+ */
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
+ useShowAttributes;
+
+ public static final String AUTO = "auto";
+ public static final String CUSTOM = "custom";
+ public static final String LIST = "list";
+ public static final String PAGE = "page";
+ public static final String ROW = "row";
+ @Deprecated(since = "5.15.0, 6.7.0", forRemoval = true)
+ public static final String USE_SHOW_ATTRIBUTES = "useShowAttributes";
+
+ /**
+ * @param name Name of the PaginatorMode.
+ * @throws IllegalArgumentException When the name doesn't match any {@link PaginatorMode}.
+ */
+ public static PaginatorMode parse(final Object name) throws IllegalArgumentException {
+ if (name == null) {
+ return null;
+ }
+ if (name instanceof PaginatorMode) {
+ return (PaginatorMode) name;
+ }
+ return valueOf(name.toString());
+ }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
index 9926f439bd..669f399d25 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
@@ -606,6 +606,7 @@ public enum BootstrapClass implements CssItem {
TEXT_DARK("text-dark"),
TEXT_INFO("text-info"),
TEXT_LIGHT("text-light"),
+ TEXT_NOWRAP("text-nowrap"),
TEXT_PRIMARY("text-primary"),
TEXT_SECONDARY("text-secondary"),
TEXT_SUCCESS("text-success"),
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
index 17d7d46557..d2edee378f 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
@@ -157,6 +157,10 @@ public enum HtmlElements {
TOBAGO_MESSAGES("tobago-messages"),
TOBAGO_OUT("tobago-out", Qualifier.INLINE),
TOBAGO_PAGE("tobago-page"),
+ TOBAGO_PAGINATOR_LIST("tobago-paginator-list"),
+ TOBAGO_PAGINATOR_PAGE("tobago-paginator-page"),
+ TOBAGO_PAGINATOR_PANEL("tobago-paginator-panel"),
+ TOBAGO_PAGINATOR_ROW("tobago-paginator-row"),
TOBAGO_PANEL("tobago-panel"),
TOBAGO_POPOVER("tobago-popover"),
TOBAGO_POPUP("tobago-popup"),
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
index fca7c572bc..b67e11b62a 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
@@ -45,6 +45,10 @@ import org.apache.myfaces.tobago.component.UILink;
import org.apache.myfaces.tobago.component.UILinks;
import org.apache.myfaces.tobago.component.UIOut;
import org.apache.myfaces.tobago.component.UIPage;
+import org.apache.myfaces.tobago.component.UIPaginatorList;
+import org.apache.myfaces.tobago.component.UIPaginatorPage;
+import org.apache.myfaces.tobago.component.UIPaginatorPanel;
+import org.apache.myfaces.tobago.component.UIPaginatorRow;
import org.apache.myfaces.tobago.component.UIPanel;
import org.apache.myfaces.tobago.component.UIPopup;
import org.apache.myfaces.tobago.component.UIRange;
@@ -74,6 +78,7 @@ import org.apache.myfaces.tobago.component.UITreeListbox;
import org.apache.myfaces.tobago.component.UITreeNode;
import org.apache.myfaces.tobago.component.UITreeSelect;
import org.apache.myfaces.tobago.config.TobagoConfig;
+import static org.apache.myfaces.tobago.config.TobagoConfig.TOBAGO_CONFIG;
import org.apache.myfaces.tobago.context.TobagoContext;
import org.apache.myfaces.tobago.internal.behavior.EventBehavior;
import org.apache.myfaces.tobago.internal.renderkit.renderer.BadgeRenderer;
@@ -91,6 +96,10 @@ import org.apache.myfaces.tobago.internal.renderkit.renderer.LinkRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.LinksRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.OutRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.PageRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.PaginatorListRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.PaginatorPageRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.PaginatorPanelRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.PaginatorRowRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.PanelRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.PopupRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.RangeRenderer;
@@ -120,6 +129,7 @@ import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeNodeRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeRenderer;
import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeSelectRenderer;
import org.apache.myfaces.tobago.internal.webapp.HtmlResponseWriter;
+import static org.apache.myfaces.tobago.util.ResourceUtils.TOBAGO_RESOURCE_BUNDLE;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -129,9 +139,6 @@ import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Locale;
-import static org.apache.myfaces.tobago.config.TobagoConfig.TOBAGO_CONFIG;
-import static org.apache.myfaces.tobago.util.ResourceUtils.TOBAGO_RESOURCE_BUNDLE;
-
/**
* <p>Abstract JUnit test case base class, which sets up the JavaServer Faces
* mock object environment for a particular simulated request.
@@ -185,6 +192,10 @@ public abstract class AbstractTobagoTestBase extends AbstractJsfTestCase {
application.addComponent(Tags.links.componentType(), UILinks.class.getName());
application.addComponent(Tags.out.componentType(), UIOut.class.getName());
application.addComponent(Tags.page.componentType(), UIPage.class.getName());
+ application.addComponent(Tags.paginatorList.componentType(), UIPaginatorList.class.getName());
+ application.addComponent(Tags.paginatorPage.componentType(), UIPaginatorPage.class.getName());
+ application.addComponent(Tags.paginatorPanel.componentType(), UIPaginatorPanel.class.getName());
+ application.addComponent(Tags.paginatorRow.componentType(), UIPaginatorRow.class.getName());
application.addComponent(Tags.panel.componentType(), UIPanel.class.getName());
application.addComponent(Tags.popup.componentType(), UIPopup.class.getName());
application.addComponent(Tags.range.componentType(), UIRange.class.getName());
@@ -238,6 +249,14 @@ public abstract class AbstractTobagoTestBase extends AbstractJsfTestCase {
renderKit.addRenderer(UILinks.COMPONENT_FAMILY, RendererTypes.LINKS, new LinksRenderer<UILinks>());
renderKit.addRenderer(UIOut.COMPONENT_FAMILY, RendererTypes.OUT, new OutRenderer<UIOut>());
renderKit.addRenderer(UIPage.COMPONENT_FAMILY, RendererTypes.PAGE, new PageRenderer<UIPage>());
+ renderKit.addRenderer(UIPaginatorList.COMPONENT_FAMILY, RendererTypes.PAGINATOR_LIST,
+ new PaginatorListRenderer<UIPaginatorList>());
+ renderKit.addRenderer(UIPaginatorPage.COMPONENT_FAMILY, RendererTypes.PAGINATOR_PAGE,
+ new PaginatorPageRenderer<UIPaginatorPage>());
+ renderKit.addRenderer(UIPaginatorPanel.COMPONENT_FAMILY, RendererTypes.PAGINATOR_PANEL,
+ new PaginatorPanelRenderer<UIPaginatorPanel>());
+ renderKit.addRenderer(UIPaginatorRow.COMPONENT_FAMILY, RendererTypes.PAGINATOR_ROW,
+ new PaginatorRowRenderer<UIPaginatorRow>());
renderKit.addRenderer(UIPanel.COMPONENT_FAMILY, RendererTypes.PANEL, new PanelRenderer<UIPanel>());
renderKit.addRenderer(UIPopup.COMPONENT_FAMILY, RendererTypes.POPUP, new PopupRenderer<UIPopup>());
renderKit.addRenderer(UIRange.COMPONENT_FAMILY, RendererTypes.RANGE, new RangeRenderer<UIRange>());
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRendererUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRendererUnitTest.java
index 61d48616e2..ee67aae2a7 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRendererUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRendererUnitTest.java
@@ -25,11 +25,15 @@ import org.apache.myfaces.tobago.component.RendererTypes;
import org.apache.myfaces.tobago.component.Tags;
import org.apache.myfaces.tobago.component.UIColumn;
import org.apache.myfaces.tobago.component.UIOut;
+import org.apache.myfaces.tobago.component.UIPaginatorList;
import org.apache.myfaces.tobago.component.UISheet;
+import org.apache.myfaces.tobago.layout.Arrows;
+import org.apache.myfaces.tobago.layout.PaginatorMode;
import org.apache.myfaces.tobago.util.ComponentUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import jakarta.faces.component.UIComponent;
import java.io.IOException;
public class SheetRendererUnitTest extends RendererTestBase {
@@ -104,4 +108,38 @@ public class SheetRendererUnitTest extends RendererTestBase {
Assertions.assertEquals(loadHtml("renderer/sheet/sheet-paging.html"), formattedResult());
}
+
+ @Test
+ public void sheetPaginatorList() throws IOException {
+ final UISheet sheet = (UISheet) ComponentUtils.createComponent(
+ facesContext, Tags.sheet.componentType(), RendererTypes.Sheet, "sheet");
+ sheet.setVar("item");
+ sheet.setValue(getSheetSample(10));
+ sheet.setRows(2);
+ sheet.setPaginator(PaginatorMode.custom);
+
+ final UIColumn column = (UIColumn) ComponentUtils.createComponent(
+ facesContext, Tags.column.componentType(), RendererTypes.Column, "column");
+ column.setLabel("Alphabet");
+ sheet.getChildren().add(column);
+
+ final UIOut out = (UIOut) ComponentUtils.createComponent(
+ facesContext, Tags.out.componentType(), RendererTypes.Out, "out");
+ out.setValueExpression("value", new MockValueExpression("#{item.name}", String.class));
+ out.setLabelLayout(LabelLayout.skip);
+ column.getChildren().add(out);
+
+ final UIComponent panel = ComponentUtils.createComponent(
+ facesContext, Tags.paginatorPanel.componentType(), RendererTypes.PaginatorPanel, "panel");
+ sheet.getFacets().put("after", panel);
+
+ final UIPaginatorList paginatorList = (UIPaginatorList) ComponentUtils.createComponent(
+ facesContext, Tags.paginatorList.componentType(), RendererTypes.PaginatorList, "list");
+ paginatorList.setArrows(Arrows.hide);
+ panel.getChildren().add(paginatorList);
+
+ sheet.encodeAll(facesContext);
+
+ Assertions.assertEquals(loadHtml("renderer/sheet/sheet-paginatorList.html"), formattedResult());
+ }
}
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/layout/ArrowsUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/layout/ArrowsUnitTest.java
new file mode 100644
index 0000000000..70cc20e8ed
--- /dev/null
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/layout/ArrowsUnitTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.layout;
+
+import org.apache.myfaces.tobago.util.EnumUnitTest;
+import org.junit.jupiter.api.Test;
+
+public class ArrowsUnitTest extends EnumUnitTest {
+
+ @Test
+ public void testNames() throws IllegalAccessException, NoSuchFieldException {
+ testNames(Arrows.class);
+ }
+}
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/layout/PaginatorModeUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/layout/PaginatorModeUnitTest.java
new file mode 100644
index 0000000000..bead6d84ef
--- /dev/null
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/layout/PaginatorModeUnitTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.layout;
+
+import org.apache.myfaces.tobago.util.EnumUnitTest;
+import org.junit.jupiter.api.Test;
+
+public class PaginatorModeUnitTest extends EnumUnitTest {
+
+ @Test
+ public void testNames() throws IllegalAccessException, NoSuchFieldException {
+ testNames(PaginatorMode.class);
+ }
+}
diff --git a/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html b/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html
new file mode 100644
index 0000000000..d90f1b3215
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/sheet/sheet-paginatorList.html
@@ -0,0 +1,71 @@
+<!--
+ * 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.
+-->
+
+<tobago-sheet id='sheet' data-tobago-selection-mode='multi' data-tobago-first='0' rows='2' row-count='10'>
+ <input id='sheet::scrollPosition' name='sheet::scrollPosition' type='hidden' value='[0,0]'>
+ <input id='sheet::selected' name='sheet::selected' type='hidden' value='[]'>
+ <div class='tobago-body'>
+ <table cellspacing='0' cellpadding='0' summary='' class='table'>
+ <thead>
+ <tr>
+ <th>
+ <span><tobago-out id='sheet:_col0'><span class='form-control-plaintext'>Alphabet</span></tobago-out></span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr row-index='0'>
+ <td>
+ <tobago-out id='sheet:0:out'><span class='form-control-plaintext'>Name 0</span></tobago-out>
+ </td>
+ <td class='tobago-behavior-container'>
+ </td>
+ </tr>
+ <tr row-index='1'>
+ <td>
+ <tobago-out id='sheet:1:out'><span class='form-control-plaintext'>Name 1</span></tobago-out>
+ </td>
+ <td class='tobago-behavior-container'>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <footer>
+ </footer>
+ <tobago-paginator-panel id='sheet:panel' class='d-flex justify-content-center'>
+ <tobago-paginator-list id='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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </li>
+ </ul>
+ </tobago-paginator-list>
+ </tobago-paginator-panel>
+</tobago-sheet>
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 b3b08b874e..bc71bf407d 100644
--- a/tobago-core/src/test/resources/renderer/sheet/sheet-paging.html
+++ b/tobago-core/src/test/resources/renderer/sheet/sheet-paging.html
@@ -46,29 +46,31 @@
</table>
</div>
<footer>
- <ul class='me-auto pagination'>
- <li class='page-item' title='Click here, to change the first displayed row'>
- <span class='tobago-paging page-link'>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>
- </li>
- </ul>
- <ul class='mx-auto 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>
- </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>
- </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>
- </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>
- </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>
- </li>
- </ul>
- <ul class='ms-auto pagination'>
+ </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>
+ </tobago-paginator-row>
+ <tobago-paginator-list id='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>
+ </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>
+ </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>
+ </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>
+ </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>
+ </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>
@@ -76,7 +78,7 @@
<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' 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>
+ <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>
@@ -84,6 +86,6 @@
<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>
- </ul>
- </footer>
+ </tobago-paginator-page>
+ </tobago-paginator-panel>
</tobago-sheet>
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/AstroData.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/AstroData.java
index fb89714149..31e97a4ad7 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/AstroData.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/AstroData.java
@@ -36,6 +36,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -73,7 +74,11 @@ public class AstroData implements Serializable {
}
public Stream<SolarObject> findAll() {
- return dataList.stream();
+ final AtomicInteger counter = new AtomicInteger(0);
+ return dataList.stream().map(object -> {
+ object.setId(counter.incrementAndGet());
+ return object;
+ });
}
public Map<String, SolarObject> findAllAsMap() {
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
index 51a3cf28bc..f50c6e10b0 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
@@ -68,6 +68,8 @@ public class SheetController implements Serializable {
private List<SolarObject> solarList;
private List<SolarObject> hugeSolarList;
+ private List<SolarObject> smallSolarList;
+ private List<SolarObject> emptySolarList;
private SheetState sheetState;
private SolarObject selectedSolarObject;
private boolean automaticLayout;
@@ -83,6 +85,13 @@ public class SheetController implements Serializable {
private void init() {
solarList = astroData.findAll().collect(Collectors.toList());
+ smallSolarList = new ArrayList<>();
+ smallSolarList.add(solarList.get(0));
+ smallSolarList.add(solarList.get(1));
+ smallSolarList.add(solarList.get(2));
+
+ emptySolarList = new ArrayList<>();
+
int j = 1;
hugeSolarList = new ArrayList<>();
while (true) {
@@ -106,6 +115,14 @@ public class SheetController implements Serializable {
return hugeSolarList;
}
+ public List<SolarObject> getSmallSolarList() {
+ return smallSolarList;
+ }
+
+ public List<SolarObject> getEmptySolarList() {
+ return emptySolarList;
+ }
+
public SheetState getSheetState() {
return sheetState;
}
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SolarObject.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SolarObject.java
index 352dcf7e0a..3a6734d471 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SolarObject.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SolarObject.java
@@ -34,6 +34,8 @@ public class SolarObject implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private Integer id;
+
private String name;
private String number;
@@ -89,14 +91,22 @@ public class SolarObject implements Serializable {
: null;
}
- public String getName() {
- return name;
- }
-
public void update(final AjaxBehaviorEvent event) {
LOG.info("AjaxBehaviorEvent called. New value: '{}' event: {}", name, event);
}
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
public void setName(final String name) {
this.name = name;
}
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
new file mode 100644
index 0000000000..edc800cba1
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/15-paginator/Paginator.xhtml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<ui:composition template="/main.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tc="http://myfaces.apache.org/tobago/component"
+ xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+ xmlns:f="http://xmlns.jcp.org/jsf/core">
+
+ <tc:section label="New implementation of paginators">
+
+ Since Tobago 5.15.0 and 6.7.0 there are new Paginator tags. You can use them to define the paginator by
+ using the new attribute <code>paginator</code>. Possible values are
+ <ul>
+ <li><code>auto</code> automatically select an paginator</li>
+ <li><code>custom</code> render no paginator, the paginator will be provieded explicitly as tags</li>
+ <li><code>list</code> render a list of pages</li>
+ <li><code>row</code> render the row, it can be modified by click</li>
+ <li><code>page</code> render the page, it can be modiefied by click</li>
+ <li><code>useShowAttributes</code> the classic paginator for backward compatibility
+ (deprected, will be removed in further releases)
+ </li>
+ </ul>
+
+ <tc:badge markup="warning">Todo: Check if 2 or more of the same controls will work on same page!</tc:badge>
+
+ <tc:sheet id="s1" value="#{sheetController.solarList}" var="object" rows="5"
+ paginator="custom">
+ <!--
+ <f:facet name="before">
+ <tc:paginatorPanel>
+ <tc:paginatorRow />
+ <tc:paginatorList arrows="hide"/>
+ <tc:paginatorPage />
+ </tc:paginatorPanel>
+ </f:facet>
+ -->
+ <f:facet name="after">
+ <tc:paginatorPanel>
+ <tc:paginatorRow/>
+ <tc:paginatorList arrows="hide"/>
+ <tc:paginatorPage/>
+ </tc:paginatorPanel>
+ </f:facet>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ <tc:column label="Orbit">
+ <tc:out value="#{object.orbit}"/>
+ </tc:column>
+ <tc:column label="Period (Days)">
+ <tc:out value="#{object.period}"/>
+ </tc:column>
+ <tc:column label="Discoverer">
+ <tc:out value="#{object.discoverer}"/>
+ </tc:column>
+ <tc:column label="Year">
+ <tc:out value="#{object.discoverYear}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+</ui:composition>
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
new file mode 100644
index 0000000000..1ae72af8d4
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/40-paginator/Paginator.xhtml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<ui:composition template="/main.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tc="http://myfaces.apache.org/tobago/component"
+ xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+ xmlns:f="http://xmlns.jcp.org/jsf/core">
+
+ <tc:section label="List: default (5 of 88 entries)">
+ <tc:sheet id="l1" value="#{sheetController.solarList}" var="object" rows="5" paginator="list">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="List: default (5 of 3 entries)">
+ <tc:sheet id="l2" value="#{sheetController.smallSolarList}" var="object" rows="5" paginator="list">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Page">
+ <tc:sheet id="p1" value="#{sheetController.solarList}" var="object" rows="5" paginator="page">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Page">
+ <tc:sheet id="r1" value="#{sheetController.solarList}" var="object" rows="5" paginator="row">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="List: default (2 of 3 entries)">
+ <tc:sheet id="c1" value="#{sheetController.solarList}" var="object" rows="5" paginator="custom">
+ <f:facet name="after">
+ <f:facet name="after">
+ <tc:paginatorPanel>
+ <tc:paginatorList alwaysVisible="true"/>
+ </tc:paginatorPanel>
+ </f:facet>
+ </f:facet>
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+
+</ui:composition>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/41-paginator/Paginator_Backward_Compatibility.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/41-paginator/Paginator_Backward_Compatibility.xhtml
new file mode 100644
index 0000000000..aaa54895cb
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/3000-sheet/41-paginator/Paginator_Backward_Compatibility.xhtml
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<ui:composition template="/main.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tc="http://myfaces.apache.org/tobago/component"
+ xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
+
+ <tc:section label="Use show-Attributes: default">
+ <tc:sheet id="s1" value="#{sheetController.solarList}" var="object" rows="2">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: row | space | space">
+ <tc:sheet id="s2" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="left" showDirectLinks="none" showPageRange="none">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: space | row | space">
+ <tc:sheet id="s3" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="center" showDirectLinks="none" showPageRange="none">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: space | space | row">
+ <tc:sheet id="s4" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="right" showDirectLinks="none" showPageRange="none">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: list | space | space">
+ <tc:sheet id="s5" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="left" showPageRange="none">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: space | list | space">
+ <tc:sheet id="s6" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="center" showPageRange="none">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: space | space | list">
+ <tc:sheet id="s7" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="right" showPageRange="none">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: page | space | space">
+ <tc:sheet id="s8" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="none" showPageRange="left">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: space | page | space">
+ <tc:sheet id="s9" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="none" showPageRange="center">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: space | space | page">
+ <tc:sheet id="s10" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="none" showPageRange="right">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: list | page | row">
+ <tc:sheet id="s11" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="right" showDirectLinks="left" showPageRange="center">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+
+ <tc:section label="Use show-Attributes: showPagingAlways=false (default), 3 entries (rows=5)">
+ <tc:sheet id="s12" value="#{sheetController.smallSolarList}" var="object" rows="5">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: showPagingAlways=true, 3 entries (rows=5)">
+ <tc:sheet id="s13" value="#{sheetController.smallSolarList}" var="object" rows="5"
+ showPagingAlways="true">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: showDirectLinksArrows">
+ <tc:sheet id="s14" value="#{sheetController.smallSolarList}" var="object" rows="2"
+ showDirectLinksArrows="true">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: directLinkCount=4">
+ <tc:sheet id="s15" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="center" showPageRange="none" directLinkCount="3">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+ <tc:section label="Use show-Attributes: showPageRangeArrows = false">
+ <tc:sheet id="s16" value="#{sheetController.solarList}" var="object" rows="2"
+ showRowRange="none" showDirectLinks="none" showPageRange="center"
+ showPageRangeArrows="false">
+ <tc:column label="Id">
+ <tc:out value="#{object.id}"/>
+ </tc:column>
+ <tc:column label="Name">
+ <tc:out value="#{object.name}"/>
+ </tc:column>
+ </tc:sheet>
+ </tc:section>
+
+</ui:composition>
diff --git a/tobago-theme/src/main/scss/_tobago.scss b/tobago-theme/src/main/scss/_tobago.scss
index f3030f25e8..9a7c780da4 100644
--- a/tobago-theme/src/main/scss/_tobago.scss
+++ b/tobago-theme/src/main/scss/_tobago.scss
@@ -1104,6 +1104,8 @@ tobago-overlay {
}
}
+/* page ----------------------------------------------------------- */
+
tobago-page {
display: block;
padding-top: $tobago-page-padding-top;
@@ -1173,6 +1175,75 @@ tobago-page {
}
}
+/* paginator-panel ------------------------------------------------------------- */
+
+tobago-paginator-panel {
+}
+
+/* paginator-list ------------------------------------------------------------- */
+
+tobago-paginator-list {
+}
+
+/* paginator-number ------------------------------------------------------------- */
+
+tobago-paginator-page {
+}
+
+/* paginator-row ------------------------------------------------------------- */
+
+tobago-paginator-row {
+
+}
+
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+
+ .page-link {
+ cursor: pointer;
+
+ input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+ }
+ }
+}
+
+/* paginator-list ------------------------------------------------------------- */
+
+tobago-paginator-list {
+}
+
+/* paginator-number ------------------------------------------------------------- */
+
+tobago-paginator-page {
+}
+
+/* paginator-row ------------------------------------------------------------- */
+
+tobago-paginator-row {
+
+}
+
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+
+ .page-link {
+ cursor: pointer;
+
+ input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+ }
+ }
+}
+
/* panel ------------------------------------------------------------- */
// todo: remove
@@ -1678,6 +1749,8 @@ tobago-sheet {
display: flex;
flex-wrap: wrap;
+ // XXX TOBAGO-2243 might to be removed, because it's now directly in the new components
+
.pagination {
margin-top: 1rem;
margin-bottom: 0;
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
index 88055521a9..524b7327cd 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
@@ -12938,6 +12938,7 @@ tobago-overlay.modal-backdrop:not(.show) {
display: none;
}
+/* page ----------------------------------------------------------- */
tobago-page {
display: block;
padding-top: 1rem;
@@ -13039,6 +13040,41 @@ tobago-page .tobago-page-toastStore .toast .tobago-auto-spacing {
overflow-y: auto;
}
+/* paginator-panel ------------------------------------------------------------- */
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
/* panel ------------------------------------------------------------- */
tobago-panel {
display: block;
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
index 43faf703a2..9aa728bd8f 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_bo [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_bo [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
index f1557cc728..efd21ed645 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#ff00be;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000000;--bs-white:#ffffff;--bs-gray:#777777;--bs-gray-dark:#323232;--bs-gray-100:#f8f9fa;--bs-gray-200:#d0d0d0;--bs-gray-300:#dee2e6;--bs-gray-400:#a0a0a0;--bs-gray-500:#adb5bd;--bs-gray-600:#777777;--bs-gray-700:#495057;--bs-gray-800:#323232;--bs [...]
+@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#ff00be;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000000;--bs-white:#ffffff;--bs-gray:#777777;--bs-gray-dark:#323232;--bs-gray-100:#f8f9fa;--bs-gray-200:#d0d0d0;--bs-gray-300:#dee2e6;--bs-gray-400:#a0a0a0;--bs-gray-500:#adb5bd;--bs-gray-600:#777777;--bs-gray-700:#495057;--bs-gray-800:#323232;--bs [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
index 6fca70db98..9a5a9e2b7a 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-charlotteville/src/main/css/tobago.css"],"names":[],"mappings":"iBAsCA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,QACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAA [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-charlotteville/src/main/css/tobago.css"],"names":[],"mappings":"iBAsCA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,QACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAA [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
index f7e2c833b8..8f981263d6 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
@@ -12965,6 +12965,7 @@ tobago-overlay.modal-backdrop:not(.show) {
display: none;
}
+/* page ----------------------------------------------------------- */
tobago-page {
display: block;
padding-top: 1rem;
@@ -13066,6 +13067,41 @@ tobago-page .tobago-page-toastStore .toast .tobago-auto-spacing {
overflow-y: auto;
}
+/* paginator-panel ------------------------------------------------------------- */
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
/* panel ------------------------------------------------------------- */
tobago-panel {
display: block;
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
index c45cd3586f..b37b499aad 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_bo [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_bo [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
index bf5cf119ee..4f0f515e2b 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";@font-face{font-family:Amaranth;font-style:normal;font-weight:400;src:url("../fonts/Amaranth-Regular.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:normal;font-weight:700;src:url("../fonts/Amaranth-Bold.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;src:url("../fonts/Amaranth-Italic.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;font-weight:700;src:url("../fonts/Amaranth-BoldItalic.otf") format( [...]
+@charset "UTF-8";@font-face{font-family:Amaranth;font-style:normal;font-weight:400;src:url("../fonts/Amaranth-Regular.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:normal;font-weight:700;src:url("../fonts/Amaranth-Bold.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;src:url("../fonts/Amaranth-Italic.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;font-weight:700;src:url("../fonts/Amaranth-BoldItalic.otf") format( [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
index 4e4ed910c8..93f070f06c 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-roxborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAiCA,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,qCAAqC,mBAE5C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,kCAAkC,mBAEzC,WACE,YAAa,SACb,WAAY,OACZ,IAAK,oCAAoC,mBAE3C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,wCAAwC,mBAE/C,mBACE,YAAa,QAAQ,CAAE,KAAK,CAAE,MAQhC,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,KACZ,UAAW,QACX,eAA [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-roxborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAiCA,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,qCAAqC,mBAE5C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,kCAAkC,mBAEzC,WACE,YAAa,SACb,WAAY,OACZ,IAAK,oCAAoC,mBAE3C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,wCAAwC,mBAE/C,mBACE,YAAa,QAAQ,CAAE,KAAK,CAAE,MAQhC,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,KACZ,UAAW,QACX,eAA [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
index 677f86b98d..a9d40406db 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
@@ -12959,6 +12959,7 @@ tobago-overlay.modal-backdrop:not(.show) {
display: none;
}
+/* page ----------------------------------------------------------- */
tobago-page {
display: block;
padding-top: 1rem;
@@ -13061,6 +13062,41 @@ tobago-page .tobago-page-toastStore .toast .tobago-auto-spacing {
overflow-y: auto;
}
+/* paginator-panel ------------------------------------------------------------- */
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
/* panel ------------------------------------------------------------- */
tobago-panel {
display: block;
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
index 6e26a042e5..d9a443df13 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_bo [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_bo [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
index 969b2c5203..52976a8807 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray- [...]
+@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray- [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
index e9cf069f74..f724626589 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-scarborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAwCA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,I [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-scarborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAwCA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,I [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
index 3293f2faee..dbf7f90aa7 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
@@ -12656,6 +12656,7 @@ tobago-overlay.modal-backdrop:not(.show) {
display: none;
}
+/* page ----------------------------------------------------------- */
tobago-page {
display: block;
padding-top: 1rem;
@@ -12757,6 +12758,41 @@ tobago-page .tobago-page-toastStore .toast .tobago-auto-spacing {
overflow-y: auto;
}
+/* paginator-panel ------------------------------------------------------------- */
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
/* panel ------------------------------------------------------------- */
tobago-panel {
display: block;
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
index 8a01a1b339..b34dc46645 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/_type.scss [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/_type.scss [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
index d314aae30b..f188099971 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:rgb(58, 37, 100);--bs-pink:#d63384;--bs-red:rgb(211, 0, 64);--bs-orange:#d90;--bs-yellow:#ffc107;--bs-green:rgb(29, 163, 50);--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:rgb(120, 140, 148);--bs-gray-dark:#323232;--bs-gray-100:#f7f7f7;--bs-gray-200:#e3e4e5;--bs-gray-300:#d7d7d7;--bs-gray-400:#ced4da;--bs-gray-500:#acacac;--bs-gray-600:rgb(120, 140, 148);--bs-gray [...]
+@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:rgb(58, 37, 100);--bs-pink:#d63384;--bs-red:rgb(211, 0, 64);--bs-orange:#d90;--bs-yellow:#ffc107;--bs-green:rgb(29, 163, 50);--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:rgb(120, 140, 148);--bs-gray-dark:#323232;--bs-gray-100:#f7f7f7;--bs-gray-200:#e3e4e5;--bs-gray-300:#d7d7d7;--bs-gray-400:#ced4da;--bs-gray-500:#acacac;--bs-gray-600:rgb(120, 140, 148);--bs-gray [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
index e85d395d97..5f6639ec22 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-speyside/src/main/css/tobago.css"],"names":[],"mappings":"iBAsCA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,iBACb,UAAW,QACX,SAAU,gBACV,YAAa,KACb,YAAa,QACb,WAAY,iBACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,mBACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,mBACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,gBACd,eAAgB,QAChB,aAAc,iBACd,UAAW,QACX,aAAc,QACd,YAAa,gBACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,mBAAoB,GAAG,CAAE,GAAG,C [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-speyside/src/main/css/tobago.css"],"names":[],"mappings":"iBAsCA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,iBACb,UAAW,QACX,SAAU,gBACV,YAAa,KACb,YAAa,QACb,WAAY,iBACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,mBACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,mBACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,gBACd,eAAgB,QAChB,aAAc,iBACd,UAAW,QACX,aAAc,QACd,YAAa,gBACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,mBAAoB,GAAG,CAAE,GAAG,C [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
index 3085e598c2..ea3f71de89 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
@@ -12922,6 +12922,7 @@ tobago-overlay.modal-backdrop:not(.show) {
display: none;
}
+/* page ----------------------------------------------------------- */
tobago-page {
display: block;
padding-top: 1rem;
@@ -13023,6 +13024,41 @@ tobago-page .tobago-page-toastStore .toast .tobago-auto-spacing {
overflow-y: auto;
}
+/* paginator-panel ------------------------------------------------------------- */
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
+/* paginator-list ------------------------------------------------------------- */
+/* paginator-number ------------------------------------------------------------- */
+/* paginator-row ------------------------------------------------------------- */
+tobago-paginator-list, tobago-paginator-page, tobago-paginator-row {
+ margin-top: 1rem;
+ margin-bottom: 0;
+}
+tobago-paginator-list .page-link, tobago-paginator-page .page-link, tobago-paginator-row .page-link {
+ cursor: pointer;
+}
+tobago-paginator-list .page-link input, tobago-paginator-page .page-link input, tobago-paginator-row .page-link input {
+ text-align: center;
+ display: none;
+ margin: -4px 0;
+ width: 3em;
+}
+
/* panel ------------------------------------------------------------- */
tobago-panel {
display: block;
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
index ebe6e77f57..75d6249d95 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../. [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/mixins/_color-mode.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../. [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
index 1cf224b2ef..2700ec5171 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray- [...]
+@charset "UTF-8";:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray- [...]
/*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
index 126edf5143..cbfa879c62 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-standard/src/main/css/tobago.css"],"names":[],"mappings":"iBAsBA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9 [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-standard/src/main/css/tobago.css"],"names":[],"mappings":"iBAsBA,MACA,sBACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9 [...]
\ No newline at end of file
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 522f121924..8690afd9af 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
@@ -1,19 +1,19 @@
-!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";var e,t;!function(e){e.ACTIVE="active",e.AUTOCOMPLETE="autocomplete",e.AUTOCOMPLETE_INPUT="autocomplete-input",e.BOTTOM_0="bottom-0",e.COLLAPSE="collapse",e.COLLAPSING="collapsing",e.D_NONE="d-none",e.DISABLED="disabled",e.DROPDOWN="dropdown",e.DROPDOWN_ITEM="dropdown-item",e.DROPDOWN_MENU="dropdown-menu",e.DROPDOWN_MENU_END="dropdown-menu-end",e.END_0="end-0",e.FADE="fade",e.FIXED_BOTTOM="fixed-bo [...]
+!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";var e,t;!function(e){e.ACTIVE="active",e.AUTOCOMPLETE="autocomplete",e.AUTOCOMPLETE_INPUT="autocomplete-input",e.BOTTOM_0="bottom-0",e.COLLAPSE="collapse",e.COLLAPSING="collapsing",e.D_NONE="d-none",e.DISABLED="disabled",e.DROPDOWN="dropdown",e.DROPDOWN_ITEM="dropdown-item",e.DROPDOWN_MENU="dropdown-menu",e.DROPDOWN_MENU_END="dropdown-menu-end",e.END_0="end-0",e.FADE="fade",e.FIXED_BOTTOM="fixed-bo [...]
/*!
* Bootstrap v5.3.3 (https://getbootstrap.com/)
* 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 ar=globalThis,lr=ar.trustedTypes,cr=lr?lr.createPolicy("lit-html",{createHTML:e=>e}):void 0,dr="$lit$",ur=`lit$${Math.random().toFixed(9).slice(2)}$`,hr="?"+ur,pr=`<${hr}>`,gr=document,fr=()=>gr.createComment(""),mr=e=>null===e||"object"!=typeof e&&"function"!=typeof e,br=Array.isArray,vr="[ \t\n\f\r]",_r=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,yr=/-->/g,Er=/>/g,wr=RegExp(`>|${vr}(?:([^\\s"'>=/]+)(${vr}*=${vr}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),Ar=/'/g,Sr [...]
+ */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 [...]
<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 d10718ebc6..f588c80f09 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 baa58f2673..3607fa9419 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,8 @@ import "./tobago-in";
import "./tobago-messages";
import "./tobago-overlay";
import "./tobago-page";
+import "./tobago-paginator-page";
+import "./tobago-paginator-row";
import "./tobago-panel";
import "./tobago-popover";
import "./tobago-popup";
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts
index 1ddeeee09c..24fcb5fe80 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-page.ts
@@ -52,15 +52,15 @@ export class Page extends HTMLElement {
window.addEventListener("unload", this.beforeUnload.bind(this));
- this.addEventListener("keypress", (event: KeyboardEvent): boolean => {
+ window.addEventListener("keydown", (event: KeyboardEvent): boolean => {
if (event.key === Key.ENTER) {
const target = event.target as HTMLElement;
if (target.tagName === "A" || target.tagName === "BUTTON") {
- return;
+ return true;
}
if (target.tagName === "TEXTAREA") {
if (!event.metaKey && !event.ctrlKey) {
- return;
+ return true;
}
}
const name = target.getAttribute("name");
@@ -69,11 +69,11 @@ export class Page extends HTMLElement {
const command = document.querySelector(`[data-tobago-default='${id}']`);
if (command) {
command.dispatchEvent(new MouseEvent("click"));
- break;
+ return false;
}
id = PageStatic.getNamingContainerId(id);
}
- return false;
+ document.querySelector("[data-tobago-default]");
}
});
}
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-page.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-page.ts
new file mode 100644
index 0000000000..1371a85b68
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-page.ts
@@ -0,0 +1,31 @@
+/*
+ * 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";
+
+export class TobagoPaginatorPage extends TobagoPaginator {
+
+ constructor() {
+ super();
+ }
+}
+
+document.addEventListener("tobago.init", function (event: Event): void {
+ if (window.customElements.get("tobago-paginator-page") == null) {
+ window.customElements.define("tobago-paginator-page", TobagoPaginatorPage);
+ }
+});
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-row.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-row.ts
new file mode 100644
index 0000000000..c146aa9d66
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator-row.ts
@@ -0,0 +1,31 @@
+/*
+ * 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";
+
+export class TobagoPaginatorRow extends TobagoPaginator {
+
+ constructor() {
+ super();
+ }
+}
+
+document.addEventListener("tobago.init", function (event: Event): void {
+ if (window.customElements.get("tobago-paginator-row") == null) {
+ window.customElements.define("tobago-paginator-row", TobagoPaginatorRow);
+ }
+});
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
new file mode 100644
index 0000000000..893a1a1a89
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-paginator.ts
@@ -0,0 +1,102 @@
+/*
+ * 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 {Key} from "./tobago-key";
+
+export class TobagoPaginator extends HTMLElement {
+
+ constructor() {
+ super();
+ }
+
+ get text(): HTMLElement {
+ return this.querySelector("span.page-link");
+ }
+
+ get output(): HTMLElement {
+ return this.querySelector(".page-link span");
+ }
+
+ get input(): HTMLInputElement {
+ return this.querySelector(".page-link input");
+ }
+
+ get sheet(): HTMLElement {
+ const sheet: HTMLElement = this.closest("tobago-sheet");
+ if (sheet != null) {
+ return sheet;
+ } else {
+ window.alert("todo: implement find, wenn this is not a child");
+ return document.querySelector("tobago-sheet");
+ }
+ }
+
+ connectedCallback(): void {
+ console.warn("register -------------- click on paging", this.tagName);
+ this.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));
+ }
+
+ 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();
+ input.select();
+ }
+
+ 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();
+ faces.ajax.request(
+ input.id,
+ null,
+ {
+ params: {
+ "javax.faces.behavior.event": "reload"
+ },
+ execute: this.sheet.id,
+ render: this.sheet.id
+ });
+ } else {
+ console.info("no update needed");
+ input.value = output.innerHTML;
+ input.style.display = "none";
+ output.style.display = "initial";
+ }
+ }
+}
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts
index 6db052a668..79236759bf 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts
@@ -240,13 +240,17 @@ export class Sheet extends HTMLElement {
// init paging by pages ---------------------------------------------------------------------------------------- //
+/*
for (const pagingText of this.querySelectorAll(".tobago-paging")) {
+ console.warn("register ************** click on paging");
pagingText.addEventListener("click", this.clickOnPaging.bind(this));
const pagingInput = pagingText.querySelector("input");
+ console.warn("register ************** blur on paging");
pagingInput.addEventListener("blur", this.blurPaging.bind(this));
+ console.warn("register ************** keydown on paging");
pagingInput.addEventListener("keydown", function (event: KeyboardEvent): void {
if (event.key === Key.ENTER) {
event.stopPropagation();
@@ -255,6 +259,7 @@ export class Sheet extends HTMLElement {
}
});
}
+*/
}
// attribute getter + setter ---------------------------------------------------------- //
@@ -888,9 +893,11 @@ Type: ${data.type}`);
}
}
+/*
clickOnPaging(event: MouseEvent): void {
const element = event.currentTarget as HTMLElement;
+ console.warn("execute ************** click on paging");
const output: HTMLElement = element.querySelector("span");
output.style.display = "none";
@@ -899,8 +906,11 @@ Type: ${data.type}`);
input.focus();
input.select();
}
+*/
+/*
blurPaging(event: FocusEvent): void {
+ console.warn("execute ************** blur on paging");
const input = event.currentTarget as HTMLInputElement;
const output: HTMLElement = input.parentElement.querySelector("span");
const number = Number.parseInt(input.value); // sanitizing
@@ -924,6 +934,7 @@ Type: ${data.type}`);
output.style.display = "initial";
}
}
+*/
syncScrolling(): void {
// sync scrolling of body to header
diff --git a/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg b/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
index 9426af5b30..00b5266f3e 100644
--- a/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
+++ b/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
@@ -439,6 +439,14 @@ GridSpanProperty(property) ::= <<
<NormalProperty(property)>
>>
+PaginatorModeProperty(property) ::= <<
+<NormalProperty(property)>
+>>
+
+ArrowsProperty(property) ::= <<
+<NormalProperty(property)>
+>>
+
DoubleProperty(property) ::= <<
<NormalProperty(property)>
>>