svn commit: r560524 - in /ofbiz/trunk/framework: common/config/ images/webapp/images/ widget/dtd/ widget/src/org/ofbiz/widget/form/ widget/src/org/ofbiz/widget/html/

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r560524 - in /ofbiz/trunk/framework: common/config/ images/webapp/images/ widget/dtd/ widget/src/org/ofbiz/widget/form/ widget/src/org/ofbiz/widget/html/

jleroux@apache.org
Author: jleroux
Date: Sat Jul 28 02:21:09 2007
New Revision: 560524

URL: http://svn.apache.org/viewvc?view=rev&rev=560524
Log:
A patch from Jeremy Wickersheimer "Enhanced pager for Forms" (https://issues.apache.org/jira/browse/OFBIZ-1096)
I just added the CommonOf between lines numbers.
Tested with LookupPartyName on Firefox, IE7, and last Opera : works fine

Modified:
    ofbiz/trunk/framework/common/config/CommonUiLabels.properties
    ofbiz/trunk/framework/common/config/CommonUiLabels_fr.properties
    ofbiz/trunk/framework/images/webapp/images/maincss.css
    ofbiz/trunk/framework/widget/dtd/widget-form.xsd
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java

Modified: ofbiz/trunk/framework/common/config/CommonUiLabels.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/config/CommonUiLabels.properties?view=diff&rev=560524&r1=560523&r2=560524
==============================================================================
--- ofbiz/trunk/framework/common/config/CommonUiLabels.properties (original)
+++ ofbiz/trunk/framework/common/config/CommonUiLabels.properties Sat Jul 28 02:21:09 2007
@@ -344,6 +344,7 @@
 CommonReturnStatus=Return Status
 CommonReview=Review
 CommonRouting=Routing
+CommonRows=rows
 CommonRun=Run
 CommonSaturday=Saturday
 CommonSave=Save

Modified: ofbiz/trunk/framework/common/config/CommonUiLabels_fr.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/config/CommonUiLabels_fr.properties?view=diff&rev=560524&r1=560523&r2=560524
==============================================================================
--- ofbiz/trunk/framework/common/config/CommonUiLabels_fr.properties (original)
+++ ofbiz/trunk/framework/common/config/CommonUiLabels_fr.properties Sat Jul 28 02:21:09 2007
@@ -6,9 +6,9 @@
 # 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
@@ -312,6 +312,7 @@
 CommonReturnStatus=Statut du retour
 CommonReview=Revoir
 CommonRouting=Routage
+CommonRows=lignes
 CommonRun=D\u00E9marrer
 CommonSaturday=Samedi
 CommonSave=Enregistrer

Modified: ofbiz/trunk/framework/images/webapp/images/maincss.css
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/maincss.css?view=diff&rev=560524&r1=560523&r2=560524
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/maincss.css (original)
+++ ofbiz/trunk/framework/images/webapp/images/maincss.css Sat Jul 28 02:21:09 2007
@@ -1735,6 +1735,51 @@
 width: auto;
 }
 
+/* Pager */
+
+.nav-pager {
+height: 2em;
+padding-bottom: 0.7em;
+padding-top: 0.4em;
+}
+
+.nav-pager ul {
+display: inline; /* IE Fix */
+}
+
+.nav-pager ul li {
+background-color: #ffffff;
+float:left;
+font-weight: bold;
+line-height: 1.8em;
+margin: 0.2em;
+}
+
+.nav-pager ul li a {
+display: block;
+}
+
+.nav-pager ul .nav-first,
+.nav-pager ul .nav-previous,
+.nav-pager ul .nav-next,
+.nav-pager ul .nav-last {
+border: #999999 solid 0.1em;
+padding: 0 1em 0 1em;
+}
+
+.nav-pager ul .nav-first-disabled,
+.nav-pager ul .nav-previous-disabled,
+.nav-pager ul .nav-next-disabled,
+.nav-pager ul .nav-last-disabled {
+border: #999999 solid 0.1em;
+color: #333333;
+padding: 0 0.5em 0 0.5em;
+}
+
+.nav-pager select {
+margin: 0;
+}
+
 /* ================================= */
 /* ===== Visual Embellishments ===== */
 /* ================================= */

Modified: ofbiz/trunk/framework/widget/dtd/widget-form.xsd
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-form.xsd?view=diff&rev=560524&r1=560523&r2=560524
==============================================================================
--- ofbiz/trunk/framework/widget/dtd/widget-form.xsd (original)
+++ ofbiz/trunk/framework/widget/dtd/widget-form.xsd Sat Jul 28 02:21:09 2007
@@ -122,17 +122,20 @@
         <xs:attribute type="xs:string" name="override-list-size">
             <xs:annotation><xs:documentation>The total number of rows in the original list (used for pagination). If not specified, the size of the list will be used. Accepts ${} notation.</xs:documentation></xs:annotation>
         </xs:attribute>
+        <xs:attribute type="xs:string" name="paginate-first-label">
+            <xs:annotation><xs:documentation>Text to display for the [First] button in a form with pagination. Defaults to "First". Accepts ${} notation.</xs:documentation></xs:annotation>
+        </xs:attribute>
         <xs:attribute type="xs:string" name="paginate-previous-label">
             <xs:annotation><xs:documentation>Text to display for the [Previous] button in a form with pagination. Defaults to "Previous". Accepts ${} notation.</xs:documentation></xs:annotation>
         </xs:attribute>
         <xs:attribute type="xs:string" name="paginate-next-label">
             <xs:annotation><xs:documentation>Text to display for the [Next] button in a form with pagination. Defaults to "Next". Accepts ${} notation.</xs:documentation></xs:annotation>
         </xs:attribute>
-        <xs:attribute type="xs:string" name="paginate-previous-style">
-            <xs:annotation><xs:documentation>CSS style to use for the [Previous] button in a form with pagination. Defaults to "buttontext".</xs:documentation></xs:annotation>
+        <xs:attribute type="xs:string" name="paginate-last-label">
+            <xs:annotation><xs:documentation>Text to display for the [Last] button in a form with pagination. Defaults to "Last". Accepts ${} notation.</xs:documentation></xs:annotation>
         </xs:attribute>
-        <xs:attribute type="xs:string" name="paginate-next-style">
-            <xs:annotation><xs:documentation>CSS style to use for the [Next] button in a form with pagination. Defaults to "buttontext".</xs:documentation></xs:annotation>
+        <xs:attribute type="xs:string" name="paginate-style">
+            <xs:annotation><xs:documentation>CSS style to use for the whole pager in a form with pagination. Defaults to "nav-pager".</xs:documentation></xs:annotation>
         </xs:attribute>
         <xs:attribute type="xs:string" name="item-index-separator" default="_o_"/>
         <xs:attribute type="xs:string" name="extends"/>

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java?view=diff&rev=560524&r1=560523&r2=560524
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java Sat Jul 28 02:21:09 2007
@@ -92,11 +92,12 @@
     protected FlexibleStringExpander paginateIndexField;
     protected FlexibleStringExpander paginateSizeField;
     protected FlexibleStringExpander overrideListSize;
+    protected FlexibleStringExpander paginateFirstLabel;
     protected FlexibleStringExpander paginatePreviousLabel;
     protected FlexibleStringExpander paginateNextLabel;
+    protected FlexibleStringExpander paginateLastLabel;
     protected String paginateTargetAnchor;
-    protected String paginatePreviousStyle;
-    protected String paginateNextStyle;
+    protected String paginateStyle;
     protected boolean separateColumns = false;
     protected boolean paginate = true;
     protected boolean useRowSubmit = false;
@@ -156,10 +157,15 @@
     protected int defaultViewSize = DEFAULT_PAGE_SIZE;
     public static String DEFAULT_PAG_INDEX_FIELD = "viewIndex";
     public static String DEFAULT_PAG_SIZE_FIELD = "viewSize";
+    public static String DEFAULT_PAG_FIRST_LABEL = "First";
     public static String DEFAULT_PAG_PREV_LABEL = "Previous";
     public static String DEFAULT_PAG_NEXT_LABEL = "Next";
-    public static String DEFAULT_PAG_PREV_STYLE = "buttontext";
-    public static String DEFAULT_PAG_NEXT_STYLE = "buttontext";
+    public static String DEFAULT_PAG_LAST_LABEL = "Last";
+    public static String DEFAULT_PAG_STYLE = "nav-pager";
+    public static String DEFAULT_PAG_FIRST_STYLE = "nav-first";
+    public static String DEFAULT_PAG_PREV_STYLE = "nav-previous";
+    public static String DEFAULT_PAG_NEXT_STYLE = "nav-next";
+    public static String DEFAULT_PAG_LAST_STYLE = "nav-last";
     
     protected List actions;
     protected List rowActions;
@@ -373,17 +379,20 @@
         if (this.overrideListSize == null || formElement.hasAttribute("override-list-size")) {
             this.overrideListSize = new FlexibleStringExpander(formElement.getAttribute("override-list-size"));
         }
+        if (this.paginateFirstLabel == null || formElement.hasAttribute("paginate-first-label")) {
+            this.paginateFirstLabel = new FlexibleStringExpander(formElement.getAttribute("paginate-first-label"));
+        }
         if (this.paginatePreviousLabel == null || formElement.hasAttribute("paginate-previous-label")) {
             this.paginatePreviousLabel = new FlexibleStringExpander(formElement.getAttribute("paginate-previous-label"));
         }
         if (this.paginateNextLabel == null || formElement.hasAttribute("paginate-next-label")) {
             this.paginateNextLabel = new FlexibleStringExpander(formElement.getAttribute("paginate-next-label"));
         }
-        if (this.paginatePreviousStyle == null || formElement.hasAttribute("paginate-previous-style")) {
-            setPaginatePreviousStyle(formElement.getAttribute("paginate-previous-style"));
+        if (this.paginateLastLabel == null || formElement.hasAttribute("paginate-last-label")) {
+            this.paginateLastLabel = new FlexibleStringExpander(formElement.getAttribute("paginate-last-label"));
         }
-        if (this.paginateNextStyle == null || formElement.hasAttribute("paginate-next-style")) {
-            setPaginateNextStyle(formElement.getAttribute("paginate-next-style"));
+        if (this.paginateStyle == null || formElement.hasAttribute("paginate-style")) {
+            setPaginateStyle(formElement.getAttribute("paginate-style"));
         }
         
         this.paginate = "true".equals(formElement.getAttribute("paginate"));
@@ -950,6 +959,9 @@
     public void renderListFormString(StringBuffer buffer, Map context, FormStringRenderer formStringRenderer, int positions) {
         // render list/tabular type forms
 
+        // prepare the items iterator and compute the pagination parameters
+        this.preparePager(context);
+
         // render formatting wrapper open
         formStringRenderer.renderFormatListWrapperOpen(buffer, context, this);
 
@@ -1179,7 +1191,73 @@
             return null;
         }
     }
-    
+
+    public void preparePager(Map context) {
+        this.rowCount = 0;
+        String lookupName = this.getListName();
+        if (UtilValidate.isEmpty(lookupName)) {
+            Debug.logError("No value for list or iterator name found.", module);
+            return;
+        }
+        Object obj = context.get(lookupName);
+        if (obj == null) {
+            Debug.logInfo("No object for list or iterator name:" + lookupName + " found.", module);
+            return;
+        }
+        // if list is empty, do not render rows
+        Iterator iter = null;
+        List items = null;
+        if (obj instanceof Iterator) {
+            iter = (Iterator) obj;  
+            setPaginate(true);
+        } else if (obj instanceof List) {
+            items = (List) obj;
+            iter = items.listIterator();
+            setPaginate(true);
+        }
+
+        // set low and high index
+        getListLimits(context, obj);
+
+        int listSize = ((Integer) context.get("listSize")).intValue();
+        int lowIndex = ((Integer) context.get("lowIndex")).intValue();
+        int highIndex = ((Integer) context.get("highIndex")).intValue();
+        Debug.logInfo("preparePager: low - high = " + lowIndex + " - " + highIndex, module);
+
+        // we're passed a subset of the list, so use (0, viewSize) range
+        if (isOverridenListSize()) {
+            lowIndex = 0;
+            highIndex = ((Integer) context.get("viewSize")).intValue();
+        }
+
+        if (iter == null) return;
+
+        // count item rows
+        int itemIndex = -1;
+        Object item = null;
+        while ((item = this.safeNext(iter)) != null && (itemIndex < highIndex)) {
+            itemIndex++;
+        }
+
+        Debug.logInfo("preparePager: Found rows = " + itemIndex, module);
+
+        // reduce the highIndex if number of items falls short
+        if ((itemIndex + 1) < highIndex) {
+            highIndex = itemIndex + 1;
+            // if list size is overridden, use full listSize
+            context.put("highIndex", new Integer(isOverridenListSize() ? listSize : highIndex));
+        }
+        context.put("actualPageSize", new Integer(highIndex - lowIndex));
+
+        if (iter instanceof EntityListIterator) {
+            try {
+                ((EntityListIterator) iter).first();
+            } catch(GenericEntityException e) {
+                Debug.logError(e, "Error rewinding list form render EntityListIterator: " + e.toString(), module);
+            }
+        }
+    }
+
     public void renderItemRows(StringBuffer buffer, Map context, FormStringRenderer formStringRenderer, boolean formPerItem, int numOfColumns) {
         this.rowCount = 0;
         String lookupName = this.getListName();
@@ -2101,6 +2179,14 @@
         return viewSize;
     }
 
+    public String getPaginateFirstLabel(Map context) {
+        String field = this.paginateFirstLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_FIRST_LABEL;
+        }
+        return field;
+    }
+
     public String getPaginatePreviousLabel(Map context) {
         String field = this.paginatePreviousLabel.expandString(context);
         if (UtilValidate.isEmpty(field)) {
@@ -2117,12 +2203,32 @@
         return field;
     }
 
+    public String getPaginateLastLabel(Map context) {
+        String field = this.paginateLastLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_LAST_LABEL;
+        }
+        return field;
+    }
+
+    public String getPaginateStyle() {
+        return this.paginateStyle;
+    }
+
+    public String getPaginateFirstStyle() {
+        return DEFAULT_PAG_FIRST_STYLE;
+    }
+
     public String getPaginatePreviousStyle() {
-        return this.paginatePreviousStyle;
+        return DEFAULT_PAG_PREV_STYLE;
     }
 
     public String getPaginateNextStyle() {
-        return this.paginateNextStyle;
+        return DEFAULT_PAG_NEXT_STYLE;
+    }
+
+    public String getPaginateLastStyle() {
+        return DEFAULT_PAG_LAST_STYLE;
     }
 
     public String getTargetWindow(Map context) {
@@ -2191,12 +2297,8 @@
         this.paginateSizeField = new FlexibleStringExpander(string);
     }
 
-    public void setPaginatePreviousStyle(String string) {
-        this.paginatePreviousStyle = (UtilValidate.isEmpty(string) ? DEFAULT_PAG_PREV_STYLE : string);
-    }
-
-    public void setPaginateNextStyle(String string) {
-        this.paginateNextStyle = (UtilValidate.isEmpty(string) ? DEFAULT_PAG_NEXT_STYLE : string);
+    public void setPaginateStyle(String string) {
+        this.paginateStyle = (UtilValidate.isEmpty(string) ? DEFAULT_PAG_STYLE : string);
     }
 
     public void setDefaultViewSize(int val) {

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java?view=diff&rev=560524&r1=560523&r2=560524
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java Sat Jul 28 02:21:09 2007
@@ -1129,18 +1129,29 @@
 
     public void renderFormatListWrapperOpen(StringBuffer buffer, Map context, ModelForm modelForm) {
 
+        String queryString = null;
+        if (UtilValidate.isNotEmpty((String)context.get("queryString"))) {
+            queryString = (String)context.get("queryString");
+        } else {
+            Map inputFields = (Map)context.get("requestParameters");
+            // strip out any multi form fields if the form is of type multi
+            if (modelForm.getType().equals("multi")) {
+                inputFields = UtilHttp.removeMultiFormParameters(inputFields);
+            }
+            queryString = UtilHttp.urlEncodeArgs(inputFields);
+        }
+        context.put("_QBESTRING_", queryString);
+
         buffer.append("<!-- begin form widget -->");
         this.appendWhitespace(buffer);
+        this.renderNextPrev(buffer, context, modelForm);
+        buffer.append(" <table cellspacing=\"0\" class=\"");
         if(UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
-            buffer.append(" <table");
-            buffer.append(" class=\"");
             buffer.append(modelForm.getDefaultTableStyle());
-            buffer.append("\" cellspacing=\"0\">");
         } else {
-            buffer.append(" <table cellspacing=\"0\" class=\"basic-table form-widget-table dark-grid\">");
-            // DEJ 20050101 removed the width=\"100%\", doesn't look very good with CSS float: left based side "columns"
+            buffer.append("basic-table form-widget-table dark-grid");
         }
-
+        buffer.append("\">");
         this.appendWhitespace(buffer);
     }
 
@@ -1148,18 +1159,6 @@
         buffer.append(" </table>");
 
         this.appendWhitespace(buffer);
-        String queryString = null;
-        if (UtilValidate.isNotEmpty((String)context.get("queryString"))) {
-            queryString = (String)context.get("queryString");
-        } else {
-            Map inputFields = (Map)context.get("requestParameters");
-            // strip out any multi form fields if the form is of type multi
-            if (modelForm.getType().equals("multi")) {
-                inputFields = UtilHttp.removeMultiFormParameters(inputFields);
-            }
-            queryString = UtilHttp.urlEncodeArgs(inputFields);
-        }
-        context.put("_QBESTRING_", queryString);
         this.renderNextPrev(buffer, context, modelForm);
         buffer.append("<!-- end form widget -->");
         this.appendWhitespace(buffer);
@@ -1923,7 +1922,7 @@
             targetService = "${targetService}";
         }
         if (UtilValidate.isEmpty(targetService)) {
-            Debug.logWarning("TargetService is empty.", module);  
+            Debug.logWarning("Cannot paginate because TargetService is empty for the form: " + modelForm.getName(), module);
             return;
         }
 
@@ -1934,14 +1933,26 @@
         int viewIndex = modelForm.getViewIndex(context);
         int viewSize = modelForm.getViewSize(context);
         int listSize = modelForm.getListSize(context);
-        
+
         int lowIndex = modelForm.getLowIndex(context);
         int highIndex = modelForm.getHighIndex(context);
         int actualPageSize = modelForm.getActualPageSize(context);
 
         // if this is all there seems to be (if listSize < 0, then size is unknown)
-        if (actualPageSize >= listSize && listSize >= 0) {
-            return;
+        if (actualPageSize >= listSize && listSize >= 0) return;
+
+        // needed ofr the "Page" and "rows" labels
+        Map uiLabelMap = (Map) context.get("uiLabelMap");
+        String pageLabel = "";
+        String rowsLabel = "";
+        String ofLabel = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            pageLabel = (String) uiLabelMap.get("CommonPage");
+            rowsLabel = (String) uiLabelMap.get("CommonRows");
+            ofLabel = (String) uiLabelMap.get("CommonOf");
+            ofLabel = ofLabel.toLowerCase();
         }
 
         // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
@@ -1965,45 +1976,105 @@
         String paginateAnchor = modelForm.getPaginateTargetAnchor();
         if (paginateAnchor != null) anchor = "#" + paginateAnchor;
 
-        buffer.append(" <table border=\"0\" cellpadding=\"2\">\n");
-        buffer.append("  <tr>\n");
-        buffer.append("    <td align=\"right\">\n");
-        buffer.append("      <b>\n");
-        if (viewIndex > 0) {
-            buffer.append(" <a href=\"");
-            String linkText = targetService;
-            if (linkText.indexOf("?") < 0)  linkText += "?";
-            else linkText += "&amp;";
-            if (queryString != null && !queryString.equals("null"))
-                linkText += queryString + "&amp;";
-            linkText += viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=" + (viewIndex - 1) + anchor + "\"";
-
-            // make the link
-            String tmp = rh.makeLink(request, response, linkText);
-            buffer.append(tmp);
-            buffer.append(" class=\"").append(modelForm.getPaginatePreviousStyle()).append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>\n");
+        // preparing the link text, so that later in the code we can reuse this and just add the viewIndex
+        String prepLinkText = "";
+        prepLinkText = targetService;
+        if (prepLinkText.indexOf("?") < 0) {
+            prepLinkText += "?";
+        } else if (!prepLinkText.endsWith("?")) {
+            prepLinkText += "&amp;";
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
+            prepLinkText += queryString + "&amp;";
+        }
+        prepLinkText += viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=";
+
+        buffer.append("<div class=\"").append(modelForm.getPaginateStyle()).append("\">");
+        buffer.append("<ul>");
+        String linkText;
 
+        // First button
+        buffer.append("<li class=\"").append(modelForm.getPaginateFirstStyle());
+        if (viewIndex > 0) {
+            buffer.append("\"><a href=\"");
+            linkText = prepLinkText + 0 + anchor + "\"";
+            // - make the link
+            buffer.append(rh.makeLink(this.request, this.response, linkText)).append("\">").append(modelForm.getPaginateFirstLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            buffer.append("-disabled\">").append(modelForm.getPaginateFirstLabel(context));
         }
+        buffer.append("</li>");
+        // Previous button
+        buffer.append("<li class=\"").append(modelForm.getPaginatePreviousStyle());
+        if (viewIndex > 0) {
+            buffer.append("\"><a href=\"");
+            linkText = prepLinkText + (viewIndex - 1) + anchor + "\"";
+            // - make the link
+            buffer.append(rh.makeLink(this.request, this.response, linkText)).append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            buffer.append("-disabled\">").append(modelForm.getPaginatePreviousLabel(context));
+        }
+        buffer.append("</li>");
+        // used for iterator and for the last page
+        int page = 0;
         if (listSize > 0) {
-            buffer.append("          <span class=\"tabletext\">" + (lowIndex + 1) + " - " + (lowIndex + actualPageSize ) + " of " + listSize + "</span> \n");
+
+            linkText = prepLinkText;
+            if(linkText.startsWith("/")) {
+                linkText = linkText.substring(1 , linkText.length());
+            }
+
+            buffer.append("<li>").append(pageLabel).append(" <select name=\"page\" size=\"1\" onchange=\"location.href = '" + linkText + "' + this.value;\" >");
+            //actual value
+            for(int i = 0; i < listSize ; ) {
+                if(  page == viewIndex ) {
+                    buffer.append("<option selected value=\"");
+                } else {
+                    buffer.append("<option value=\"");
+                }
+                buffer.append(page);
+                buffer.append("\">");
+                buffer.append( 1 + page);
+                buffer.append("</option>");
+                // increment page and calculate next index
+                page++;
+                i = page * viewSize;
+            }
+            buffer.append("</select></li>");
+
+            buffer.append("<li>");
+            buffer.append((lowIndex + 1) + " - " + (lowIndex + actualPageSize ) + " " + ofLabel + " " + listSize).append(" " + rowsLabel);
+            buffer.append("</li>");
         }
-        if (highIndex < listSize) {
-            buffer.append(" <a href=\"");
-            String linkText = "" + targetService;
-            if (linkText.indexOf("?") < 0)  linkText += "?";
-            else linkText += "&amp;";
-            linkText += queryString + "&amp;" + viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=" + (viewIndex + 1) + anchor + "\"";
-
-            // make the link
-            buffer.append(rh.makeLink(request, response, linkText));
-            buffer.append(" class=\"").append(modelForm.getPaginatePreviousStyle()).append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>\n");
 
+        // Next button
+        buffer.append("<li class=\"").append(modelForm.getPaginateNextStyle());
+        if (highIndex < listSize) {
+            buffer.append("\"><a href=\"");
+            linkText = prepLinkText + (viewIndex + 1) + anchor + "\"";
+            // - make the link
+            buffer.append(rh.makeLink(this.request, this.response, linkText)).append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            buffer.append("-disabled\">").append(modelForm.getPaginateNextLabel(context));
+        }
+        buffer.append("</li>");
+        // Last button
+        buffer.append("<li class=\"").append(modelForm.getPaginateLastStyle());
+        if (highIndex < listSize) {
+            buffer.append("\"><a href=\"");
+            linkText = prepLinkText + (page - 1) + anchor + "\"";
+            // - make the link
+            buffer.append(rh.makeLink(this.request, this.response, linkText)).append("\">").append(modelForm.getPaginateLastLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            buffer.append("-disabled\">").append(modelForm.getPaginateLastLabel(context));
         }
-        buffer.append("      </b>\n");
-        buffer.append("   </td>\n");
-        buffer.append("  </tr>\n");
-        buffer.append(" </table>\n");
+        buffer.append("</li>");
 
+        buffer.append("</ul>").append("</div>");
         this.appendWhitespace(buffer);
     }