Stefan Hausmann
Stefan Hausmann

Reputation: 55

Xpages Repeat Control / Documents from View - best practice

What I wanted to achieve in a recent application was to use my own pagination - so I need to know how many documents are in a (categorized) view to calculate the pages needed.

<xp:repeat id="repeat1" rows="30"
                value="#{javascript:viewScope.counterArray}"
                indexVar="counter" var="row" disableTheme="true"
                removeRepeat="true">
                <li>
                    <xp:link escape="true"
                        text="#{javascript:(counter + 1) + ' (' + row.toString() + ')'}" id="link3"
                        disableTheme="true">
                        <xp:eventHandler event="onclick"
                            submit="true">
                            <xp:this.action>
                                <xp:executeScript>
                                    <xp:this.script><![CDATA[#{javascript:viewScope.put("repeatFirstIndex", row);}]]></xp:this.script>
                                </xp:executeScript>
                            </xp:this.action>
                        </xp:eventHandler>
                    </xp:link>
                </li>
            </xp:repeat>

Becaue of this known problem I have to do a workaround, querying the number of documents via a repeat control.

<xp:repeat id="blindRepeat" rows="0" value="#{viewStories}"></xp:repeat>

I use this sample code to get the right number of iterations for the repeat control.

<xp:this.beforePageLoad><![CDATA[#{javascript:
var counterArray = []; 
var numberOfStories = getComponent("blindRepeat").getRowCount();
var numberOfPagesNecessary = Math.ceil(numberOfStories / sessionScope.get("ListPagerPerPage"));
for (var i = 0; i < (numberOfPagesNecessary - 1); i++) {
    counterArray[i] = i*sessionScope.get("ListPagerPerPage"); 
    viewScope.lastPage = i*sessionScope.get("ListPagerPerPage");
} 
viewScope.counterArray = counterArray;}]]></xp:this.beforePageLoad>

But right here is where I run into a Catch 22: I can only use a repeat control, because I cannot get the richt number of documents from the view directly, like Knut Herrmann (1) does, but the repeat control is not available , so I cannot use it like Per Henrik Lausten (2) proposes.

A colleague proposed filling the Array in a Script block that is nested behind the blind Repeat Control (so it should be drawn) but before the pagination repeat control (so viewScope should hold the right numbers), but this solution seems rather flaky to me.

So I am inquiring if there is a 'best practise' for this kind of situation - I'd like to solve this properly and not in a way that depends on the timely execution of some javascript

Upvotes: 0

Views: 642

Answers (1)

shillem
shillem

Reputation: 1260

Considered the reason you gave in the comment to your question I suggest you to implement your own custom renderer for the pager.

In the faces-config.xml declare as follows:

<render-kit>
    <renderer>
        <component-family>com.ibm.xsp.Pager
        </component-family>
        <renderer-type>com.ibm.xsp.XPager
        </renderer-type>
        <renderer-class>com.irc.xsp.renderer.UIPagerRenderer
        </renderer-class>
    </renderer>
</render-kit>

Where com.irc.xsp.renderer.UIPagerRenderer is the rendering class. Obviously you can name it whatever you want. Just use the same name in both places.

The renderer could look something like this:

package com.irc.xsp.renderer;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.FacesExceptionEx;
import com.ibm.xsp.component.UIPager;
import com.ibm.xsp.component.UIPagerControl;
import com.ibm.xsp.component.xp.XspPager;
import com.ibm.xsp.component.xp.XspPagerControl;
import com.ibm.xsp.context.FacesContextEx;
import com.ibm.xsp.event.PagerEvent;
import com.ibm.xsp.extsn.ResourceHandler;
import com.ibm.xsp.renderkit.html_extended.XPagerRenderer;
import com.ibm.xsp.util.AjaxUtilEx;
import com.ibm.xsp.util.FacesUtil;
import com.ibm.xsp.util.JavaScriptUtil;
import com.ibm.xsp.util.TypedUtil;

public class UIPagerRenderer extends XPagerRenderer {

    public static final String VAR_PAGE = "page"; //$NON-NLS-1$

    private enum Property {
        LIST_ITEM_CLASS, PAGER_LINK_CLASS, ACTIVE_CLASS("active"), DISABLED_CLASS("disabled");

        String className;

        Property() {
        }

        Property(String s) {
            this.className = s;
        }

        String getClassName() {
            return className;
        }

    }

    @Override
    public void decode(FacesContext context, UIComponent component) {
        super.decode(context, component);

        // check that this component cause the submit
        if (decodeCausedSubmit(context, component)) {
            PagerEvent pagerEvent = new PagerEvent(component);

            String hiddenValue = FacesUtil.getHiddenFieldValue(context);
            if (StringUtil.isNotEmpty(hiddenValue)) {
                int pos = hiddenValue.lastIndexOf('_');
                if (pos > -1) {
                    hiddenValue = hiddenValue.substring(pos + 1);
                    if (isFirst(hiddenValue)) {
                        pagerEvent.setAction(PagerEvent.ACTION_FIRST);
                    } else if (isLast(hiddenValue)) {
                        pagerEvent.setAction(PagerEvent.ACTION_LAST);
                    } else if (isNext(hiddenValue)) {
                        pagerEvent.setAction(PagerEvent.ACTION_NEXT);
                    } else if (isPrevious(hiddenValue)) {
                        pagerEvent.setAction(PagerEvent.ACTION_PREVIOUS);
                    } else {
                        try {
                            int value = Integer.parseInt(hiddenValue);
                            pagerEvent.setAction(PagerEvent.ACTION_GOTOPAGE);
                            pagerEvent.setPage(value);
                        } catch (NumberFormatException nfe) {
                            return; // just don't queue the event
                        }
                    }
                } else {
                    return;
                }
            }
            ((UIPager) component).queueEvent(pagerEvent);
        }
    }

    private boolean decodeCausedSubmit(FacesContext context, UIComponent component) {
        String currentClientId = component.getClientId(context);
        String hiddenValue = FacesUtil.getHiddenFieldValue(context);

        if (currentClientId != null && hiddenValue != null) {
            return StringUtil.indexOfIgnoreCase(hiddenValue, currentClientId) > -1;
        }
        return false;
    }

    @Override
    public boolean getRendersChildren() {
        return true;
    }

    @Override
    public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
        if (context == null || component == null) {
            throw new IOException();
        }

        List<?> controls = component.getChildren();

        if (controls.isEmpty()) {
            return;
        }

        XspPager pager = (XspPager) component;
        UIPager.PagerState pagerState = ((UIPager) component).createPagerState();

        if (pagerState == null) {
            throw new FacesExceptionEx(ResourceHandler.getString("PagerRenderer.Pagerisnotassociatedwithanydataco"));
        }

        encodePagerContent(context, context.getResponseWriter(), pager, pagerState, controls, false);
    }

    protected void encodePagerContent(FacesContext context, ResponseWriter writer, XspPager pager,
            UIPager.PagerState pagerState, List<?> controls, boolean rtl) throws IOException {
        // Compute the pages that should be displayed
        int pageCount = pagerState.getPageCount();
        int startCount = getStartCount(pagerState, pageCount);
        int endCount = getEndCount(pagerState, pageCount, startCount);

        String pagerId = pager.getClientId(context);

        String pagerRole = pager.getRole();
        String pagerTitle = pager.getTitle();
        String pagerOuterClass = pager.getOuterStyleClass();
        String pagerAriaLabel = pager.getAriaLabel();
        boolean closeOuterTag = false;

        if (isAnyAssigned(pagerRole, pagerTitle, pagerOuterClass, pagerAriaLabel)) {
            writer.startElement("div", null); // $NON-NLS-1$

            writeNonNullAttributeOnly(writer, "role", pagerRole);
            writeNonNullAttributeOnly(writer, "title", pagerTitle);
            writeNonNullAttributeOnly(writer, "class", pagerOuterClass);
            writeNonNullAttributeOnly(writer, "aria-label", pagerAriaLabel);

            closeOuterTag = true;
        }

        writer.startElement("ul", null);

        writeNonNullAttributeOnly(writer, "class", pager.getStyleClass());
        writeNonNullAttributeOnly(writer, "id", pagerId);

        Iterator<?> it = controls.iterator();

        while (it.hasNext()) {
            Object obj = it.next();

            if (obj instanceof XspPagerControl) {
                XspPagerControl control = (XspPagerControl) obj;
                String type = control.getType();

                if (StringUtil.isNotEmpty(type)) {
                    if (isFirst(type) || isNext(type) || isPrevious(type)
                            || (isLast(type) && pager.isAlwaysCalculateLast())) {
                        encodeAction(context, writer, pager, pagerState, pagerId, control, type, startCount, endCount,
                                rtl);

                        continue;
                    } else if (isLast(type) && !pager.isAlwaysCalculateLast()) {
                        if (!pagerState.hasMoreRows()) {
                            encodeAction(context, writer, pager, pagerState, pagerId, control, type, startCount,
                                    endCount, rtl);
                        } else {
                            writer.startElement("li", null);
                            writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS
                                    .getClassName(), Property.DISABLED_CLASS.getClassName()));

                            writer.startElement("a", null);
                            writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName());
                            writer.writeText(getMayBeMorePages(), null);
                            writer.endElement("a");

                            writer.endElement("li");
                        }

                        continue;
                    } else if (type.equalsIgnoreCase(UIPagerControl.TYPE_GROUP)) {
                        encodeGroup(context, writer, pager, pagerState, pagerId, control, startCount, endCount);

                        continue;
                    } else if (type.equalsIgnoreCase(UIPagerControl.TYPE_STATUS)) {
                        encodeStatus(context, writer, pager, pagerState, control, startCount, endCount);

                        continue;
                    } else if (isSeparator(type)) {
                        encodeSeparator(context, writer, control, type);

                        continue;
                    } else if (type.equalsIgnoreCase(UIPagerControl.TYPE_GOTO)) {
                        encodeGoto();

                        continue;
                    }
                }

                // "Unknown control type {0}"
                String msg = com.ibm.xsp.extsn.ResourceHandler.getString("PagerRenderer.Unknowncontroltype0"); //$NON-NLS-1$
                msg = StringUtil.format(msg, type);
                throw new FacesExceptionEx(msg);
            }
        }

        writer.endElement("ul");

        if (closeOuterTag) {
            writer.endElement("div");
        }
    }

    protected void encodeAction(FacesContext context, ResponseWriter writer, XspPager pager,
            UIPager.PagerState pagerState, String pagerId, XspPagerControl control, String type, int startCount,
            int endCount, boolean rtl) throws IOException {
        String controlId = pagerId + "__" + type;
        String defaultText = "";
        String ariaLabel = "";
        boolean renderLink = true;

        //TODO need to handle BIDI here for the unicode symbols
        if (isFirst(type)) {
            renderLink = pagerState.getCurrentPage() > startCount;
            // "\u00AB" FirstSymbol
            defaultText = "\u00AB"; //$NON-NLS-1$
            // "First page"
            ariaLabel = ResourceHandler.getString("PagerRenderer.First"); //$NON-NLS-1$
        } else if (isPrevious(type)) {
            renderLink = pagerState.getCurrentPage() > startCount;
            // "\u2039" PreviousSymbol
            defaultText = "\u2039"; //$NON-NLS-1$
            // "Previous page"
            ariaLabel = ResourceHandler.getString("PagerRenderer.Previous"); //$NON-NLS-1$
        } else if (isNext(type)) {
            renderLink = pagerState.getCurrentPage() < endCount - 1;
            // "\u203A" NextSymbol
            defaultText = "\u203A"; //$NON-NLS-1$;
            // "Next page"
            ariaLabel = ResourceHandler.getString("PagerRenderer.Next"); //$NON-NLS-1$
        } else if (isLast(type)) {
            renderLink = pagerState.getCurrentPage() < endCount - 1;
            // "\u00BB" LastSymbol
            defaultText = "\u00BB"; //$NON-NLS-1$
            // "Last page"
            ariaLabel = ResourceHandler.getString("PagerRenderer.Last"); //$NON-NLS-1$
        }

        writer.startElement("li", null);
        String listItemClass = Property.LIST_ITEM_CLASS.getClassName();

        if (!renderLink) {
            //If current page is the first, disable first/previous pagers
            //and if current page is the last, disable last/next pagers
            listItemClass = com.irc.util.StringUtil.concat(listItemClass, Property.DISABLED_CLASS.getClassName());
        }

        writeNonNullAttributeOnly(writer, "class", listItemClass);

        // Generate the image link
        String val = (String) control.getValue();

        if (StringUtil.isEmpty(val)) {
            val = defaultText;
        }

        // Generate the text link
        if (StringUtil.isNotEmpty(val)) {
            writer.startElement("a", null); // $NON-NLS-1$

            if (renderLink) {
                writer.writeAttribute("aria-disabled", "false", null); // $NON-NLS-1$ $NON-NLS-2$
                writer.writeAttribute("href", "#", null); // $NON-NLS-1$ $NON-NLS-2$
            } else {
                //add a11y attributes
                writer.writeAttribute("aria-disabled", "true", null); // $NON-NLS-1$ $NON-NLS-2$
            }

            writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName());

            writer.writeAttribute("id", controlId + "__lnk", null); // $NON-NLS-1$ $NON-NLS-2$
            writer.writeAttribute("role", "button", null); // $NON-NLS-1$ $NON-NLS-2$
            writer.writeAttribute("aria-label", ariaLabel, null); // $NON-NLS-1$
            writer.writeText(val, null);
            writer.endElement("a"); // $NON-NLS-1$

            if (renderLink) {
                setupSubmitOnClick(context, pager, pagerState, controlId, controlId + "__lnk"); // $NON-NLS-1$
            }
        }

        writer.endElement("li"); // $NON-NLS-1$
    }

    protected void encodeGroup(FacesContext context, ResponseWriter writer, XspPager pager,
            UIPager.PagerState pagerState, String pagerId, XspPagerControl control, int startCount, int endCount)
            throws IOException {
        // Save the old page value
        Map<String, Object> requestMap = TypedUtil.getRequestMap(context.getExternalContext());
        Object oldPage = requestMap.get(VAR_PAGE);
        String controlId = pagerId + "__" + control.getType();//$NON-NLS-1$

        // Encode the pages
        for (int i = startCount; i < endCount; i++) {
            // Push the page number
            requestMap.put(VAR_PAGE, i + 1);
            boolean renderLink = (i != pagerState.getCurrentPage());

            writer.startElement("li", null); // $NON-NLS-1$
            String listItemClass = Property.LIST_ITEM_CLASS.getClassName();

            if (!renderLink) {
                listItemClass = com.irc.util.StringUtil.concat(listItemClass, Property.ACTIVE_CLASS.getClassName());
            }

            writeNonNullAttributeOnly(writer, "class", listItemClass);

            // Generate the image link
            String val = (String) control.getValue();

            if (StringUtil.isEmpty(val)) {
                val = Integer.toString(i + 1);
            }

            // Generate the text link
            if (StringUtil.isNotEmpty(val)) { // Generate the text link
                writer.startElement("a", control); //$NON-NLS-1$
                writer.writeAttribute("id", controlId + "__lnk__" + i, null); // $NON-NLS-1$ $NON-NLS-2$
                // "Page {0}"
                String ariaLabel = ResourceHandler.getString("PagerRenderer.Gotopage0"); //$NON-NLS-1$
                ariaLabel = StringUtil.format(ariaLabel, val);
                writer.writeAttribute("aria-label", ariaLabel, null); // $NON-NLS-1$
                writer.writeAttribute("role", "button", null); // $NON-NLS-1$ $NON-NLS-2$

                writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName());

                if (renderLink) { //make sure the a is tab-able                 
                    writer.writeAttribute("tabindex", "0", null); // $NON-NLS-1$ $NON-NLS-2$
                    writer.writeAttribute("aria-pressed", "false", null); // $NON-NLS-1$ $NON-NLS-2$
                } else {
                    writer.writeAttribute("aria-pressed", "true", null); // $NON-NLS-1$ $NON-NLS-2$
                }

                writer.writeText(val, null);
                writer.endElement("a"); // $NON-NLS-1$

                if (renderLink) {
                    setupSubmitOnClick(context, pager, pagerState, controlId + "__lnk__" + i, controlId + "__lnk__" + i); // $NON-NLS-1$ $NON-NLS-2$
                }
            }

            writer.endElement("li"); // $NON-NLS-1$
        }

        // Encode after the pages
        if (!pager.isAlwaysCalculateLast()) {
            if (endCount < pagerState.getLastPage() || pagerState.hasMoreRows()) {
                writer.startElement("li", null); // $NON-NLS-1$
                writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS.getClassName(),
                        Property.DISABLED_CLASS.getClassName()));

                writer.startElement("a", control); //$NON-NLS-1$
                writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName());
                writer.writeText(getMayBeMorePages(), null);
                writer.endElement("a"); // $NON-NLS-1$
                writer.endElement("li"); // $NON-NLS-1$
            }
        }

        // Restore the old page value
        if (oldPage != null) {
            requestMap.put(VAR_PAGE, oldPage);
        } else {
            requestMap.remove(VAR_PAGE);
        }

    }

    protected void setupSubmitOnClick(FacesContext context, XspPager component, UIPager.PagerState st, String clientId,
            String sourceId) {
        boolean immediate = false;

        UIComponent subTree = ((FacesContextEx) context).getSubTreeComponent();

        boolean partialExec = component.isPartialExecute();
        String execId = null;
        if (partialExec) {
            execId = component.getClientId(context);
            immediate = true;
        } else {
            if (subTree != null) {
                partialExec = true;
                execId = subTree.getClientId(context);
                immediate = true;
            }
        }

        boolean partialRefresh = component.isPartialRefresh();
        String refreshId = null;
        if (partialRefresh) {
            UIComponent refreshComponent = component.findSharedDataPagerParent();
            if (null == refreshComponent) {
                refreshComponent = (UIComponent) st.getDataIterator();
            }
            refreshId = AjaxUtilEx.getRefreshId(context, refreshComponent);
        } else {
            if (subTree != null) {
                partialRefresh = true;
                refreshId = subTree.getClientId(context);
            }
        }

        // call some JavaScript in xspClient.js
        final String event = "onclick"; // $NON-NLS-1$
        // Note, the onClick event is also triggered if the user tabs to the
        // image\link and presses enter (Not just when clicked with a
        // mouse).

        // When the source is clicked, put its id in the hidden field and
        // submit the form.
        StringBuilder buff = new StringBuilder();
        if (partialRefresh) {
            JavaScriptUtil.appendAttachPartialRefreshEvent(buff, clientId, sourceId, execId, event,
            /* clientSideScriptName */null, immediate ? JavaScriptUtil.VALIDATION_NONE
                    : JavaScriptUtil.VALIDATION_FULL,
            /* refreshId */refreshId,
            /* onstart */getOnStart(component),
            /* oncomplete */getOnComplete(component),
            /* onerror */getOnError(component));
        } else {
            JavaScriptUtil.appendAttachEvent(buff, clientId, sourceId, execId, event,
            /* clientSideScriptName */null,
            /* submit */true, immediate ? JavaScriptUtil.VALIDATION_NONE : JavaScriptUtil.VALIDATION_FULL);
        }
        String script = buff.toString();

        // Add the script block we just generated.
        JavaScriptUtil.addScriptOnLoad(script);
    }

    protected String getOnStart(XspPager component) {
        return (String) component.getAttributes().get("onStart"); // $NON-NLS-1$
    }

    protected String getOnComplete(XspPager component) {
        return (String) component.getAttributes().get("onComplete"); // $NON-NLS-1$
    }

    protected String getOnError(XspPager component) {
        return (String) component.getAttributes().get("onError"); // $NON-NLS-1$
    }

    protected void encodeStatus(FacesContext context, ResponseWriter writer, XspPager pager,
            UIPager.PagerState pagerState, XspPagerControl control, int startCount, int endCount) throws IOException {
        writer.startElement("li", null); // $NON-NLS-1$
        writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS.getClassName(),
                Property.DISABLED_CLASS.getClassName()));

        String val = (String) control.getValue();

        if (StringUtil.isEmpty(val)) {
            val = "{0}"; // $NON-NLS-1$
        }

        if (pagerState.getLastPage() > 0) {
            writer.startElement("a", null); // $NON-NLS-1$
            writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName());
            writer.writeAttribute("role", "button", null); // $NON-NLS-2$ $NON-NLS-1$
            val = StringUtil.format(val, pagerState.getCurrentPage() + 1, pagerState.getLastPage(), startCount,
                    endCount);
            writer.writeText(val, null);
            writer.endElement("a"); // $NON-NLS-1$
        }

        writer.endElement("li"); // $NON-NLS-1$
    }

    protected void encodeSeparator(FacesContext context, ResponseWriter writer, XspPagerControl control, String type)
            throws IOException {
        String val = (String) control.getValue();

        writer.startElement("li", null); // $NON-NLS-1$

        if (StringUtil.isEmpty(val)) {
            String defaultSeparator = "|"; // $NON-NLS-1$

            if (type.equalsIgnoreCase(UIPagerControl.TYPE_SEPARATORPAGE)) {
                // "Page"
                defaultSeparator = com.ibm.xsp.extsn.ResourceHandler.getString("PagerRenderer.Page"); //$NON-NLS-1$
            }

            val = defaultSeparator;
        }

        writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS.getClassName(),
                Property.DISABLED_CLASS.getClassName()));

        // Generate the text link
        if (StringUtil.isNotEmpty(val)) {
            writer.startElement("a", null); // $NON-NLS-1$
            writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName());
            writer.writeText(val, null);
            writer.endElement("a"); // $NON-NLS-1$
        }

        writer.endElement("li"); // $NON-NLS-1$
    }

    protected void encodeGoto() {
        // Do not exists in core XPages yet..
    }

    protected int getStartCount(UIPager.PagerState st, int pageCount) {
        int start = (st.getFirst() / st.getRows()) - pageCount / 2;
        start = Math.min(Math.max(0, st.getLastPage() - pageCount), Math.max(0, start));
        return start;
    }

    protected int getEndCount(UIPager.PagerState st, int pageCount, int start) {
        int sizeOfPageRange = Math.min(start + pageCount, st.getLastPage()) - start;
        int end = start + sizeOfPageRange;
        return end;
    }

    protected boolean isFirst(String type) {
        return (type.equalsIgnoreCase(UIPagerControl.TYPE_FIRST)
                || type.equalsIgnoreCase(UIPagerControl.TYPE_FIRSTARROW) || type
                .equalsIgnoreCase(UIPagerControl.TYPE_FIRSTIMAGE));
    }

    protected boolean isNext(String type) {
        return (type.equalsIgnoreCase(UIPagerControl.TYPE_NEXT) || type.equalsIgnoreCase(UIPagerControl.TYPE_NEXTARROW) || type
                .equalsIgnoreCase(UIPagerControl.TYPE_NEXTIMAGE));
    }

    protected boolean isLast(String type) {
        return (type.equalsIgnoreCase(UIPagerControl.TYPE_LAST) || type.equalsIgnoreCase(UIPagerControl.TYPE_LASTARROW) || type
                .equalsIgnoreCase(UIPagerControl.TYPE_LASTIMAGE));
    }

    protected boolean isPrevious(String type) {
        return (type.equalsIgnoreCase(UIPagerControl.TYPE_PREVIOUS)
                || type.equalsIgnoreCase(UIPagerControl.TYPE_PREVIOUSARROW) || type
                .equalsIgnoreCase(UIPagerControl.TYPE_PREVIOUSIMAGE));
    }

    protected boolean isSeparator(String type) {
        return (type.equalsIgnoreCase(UIPagerControl.TYPE_SEPARATOR) || type
                .equalsIgnoreCase(UIPagerControl.TYPE_SEPARATORPAGE));
    }

    protected String getMayBeMorePages() {
        return "..."; // $NON-NLS-1$
    }

    private void writeNonNullAttributeOnly(ResponseWriter writer, String attributeName, String attributeValue)
            throws IOException {
        if (attributeValue != null && !attributeValue.isEmpty()) {
            writer.writeAttribute(attributeName, attributeValue, null);
        }
    }

    private boolean isAnyAssigned(String... objs) {
        for (String s : objs) {
            if (s != null && !s.isEmpty())
                return true;
        }

        return false;
    }

}

That is a class I've been using in my last project. Basically it's re-implemeting everything that the pager does in order to have control over the look and feel of the component - it's called renderer after all. You could try to tweak it here and there to see how the various things work out on the page. It's a learning process.

Upvotes: 3

Related Questions