Hi Bilgin, Bruno,

I did a complete code review and tested on FF3 & IE7. It works well, good work, 
bravo !

I just found this without surrounding {} but it's how it's done there anyway apart some blocks. Bad, but easier to read, so I let all like that ;o)
+        if (overrideFormField.sortField != null)
+            this.sortField = overrideFormField.sortField;

In HtmlFormRenderer.java
   I changed coulumnField to columnField (typo).
   Replaced a tab in targetType="plain"; (does not come from this patch)

Some formatting in widget-form.xsd, just because it's easier to read

BTW I get a (not related to this patch) strange Ajax behaviour on FF3, Opera 9.02, Chrome and Safari (all on Windows) not IE7 : when I create a new Ajax Example these Browsers propose to download a json file which contains
{"javax.servlet.request.cipher_suite":"TLS_DHE_RSA_WITH_AES_128_CBC_SHA","targetRequestUri":"/createExampleAjax","javax.servlet.request.key_size":128,"exampleId":"10010","thisRequestUri":"createExampleAjax","multiPartMap":{},"_CONTROL_PATH_":"/example/control","_CONTEXT_ROOT_":"D:\\workspace\\ofbizRun\\framework\\example\\webapp\\example\\","javax.servlet.request.ssl_session":"48ec8be7be79ec074f8e4892ecc833538bcab9e0a77be14299958fc8c52b6b68","_SERVER_ROOT_URL_":"https://localhost:18443"}

Any ideas about that (it's OFBiz OOTB r702746) ?

Jacques

Author: bibryam
Date: Mon Oct  6 12:29:40 2008
New Revision: 702236

URL: http://svn.apache.org/viewvc?rev=702236&view=rev
Log:
Applied the patch from JIRA Issue # List-Multi form column sorting". Thanks to 
Bruno Busco for helping and patience.
As this is my first commit to framework, I'd really appreciate if you could 
review this commit.

Modified:
   ofbiz/trunk/framework/example/widget/example/ExampleForms.xml
   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/form/ModelFormField.java
   ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java

Modified: ofbiz/trunk/framework/example/widget/example/ExampleForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/widget/example/ExampleForms.xml?rev=702236&r1=702235&r2=702236&view=diff
==============================================================================
--- ofbiz/trunk/framework/example/widget/example/ExampleForms.xml (original)
+++ ofbiz/trunk/framework/example/widget/example/ExampleForms.xml Mon Oct  6 
12:29:40 2008
@@ -49,15 +49,16 @@
            <service service-name="performFind" result-map-name="result" 
result-map-list-name="listIt">
                <field-map field-name="inputFields" env-name="exampleCtx"/>
                <field-map field-name="entityName" value="Example"/>
+                <field-map field-name="orderBy" 
env-name="parameters.sortField"/>
            </service>
        </actions>
        <field name="exampleId" title="${uiLabelMap.ExampleExampleId}" 
widget-style="buttontext">
            <hyperlink also-hidden="false" description="${exampleId}" 
target="EditExample?exampleId=${exampleId}"/>
        </field>
-        <field name="exampleName" 
title="${uiLabelMap.CommonName}"><display/></field>
+        <field name="exampleName" title="${uiLabelMap.CommonName}" 
sort-field="true"><display/></field>
        <field name="exampleTypeId" title="${uiLabelMap.CommonType}"><display-entity 
entity-name="ExampleType"/></field>
        <field name="statusId" title="${uiLabelMap.CommonStatus}"><display-entity 
entity-name="StatusItem"/></field>
-        <field name="description" 
title="${uiLabelMap.CommonDescription}"><display/></field>
+        <field name="description" title="${uiLabelMap.CommonDescription}" 
sort-field="true"><display/></field>
    </form>

    <!-- Typically, this extended form wouldn't be necessary. The parent form 
(ListExamples) would

Modified: ofbiz/trunk/framework/images/webapp/images/maincss.css
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/maincss.css?rev=702236&r1=702235&r2=702236&view=diff
==============================================================================
--- ofbiz/trunk/framework/images/webapp/images/maincss.css (original)
+++ ofbiz/trunk/framework/images/webapp/images/maincss.css Mon Oct  6 12:29:40 
2008
@@ -1501,6 +1501,23 @@
text-align: left;
}

+/* ===== Sort field style ===== */
+.basic-table .header-row-2 th .sort-order-asc,
+.basic-table .header-row-2 td .sort-order-asc{
+background: url(/images/arrow-gr-up.png) no-repeat right;
+padding-right: 20px;
+}
+.basic-table .header-row-2 th .sort-order-desc,
+.basic-table .header-row-2 td .sort-order-desc{
+background: url(/images/arrow-gr-dw.png) no-repeat right;
+padding-right: 20px;
+}
+.basic-table .header-row-2 th .sort-order,
+.basic-table .header-row-2 td .sort-order{
+background: url(/images/arrow-gr.png) no-repeat right;
+padding-right: 20px;
+}
+
/* ===== Table decorator - Hover bar ===== */

.hover-bar tr:hover {

Modified: ofbiz/trunk/framework/widget/dtd/widget-form.xsd
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-form.xsd?rev=702236&r1=702235&r2=702236&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/dtd/widget-form.xsd (original)
+++ ofbiz/trunk/framework/widget/dtd/widget-form.xsd Mon Oct  6 12:29:40 2008
@@ -101,6 +101,15 @@
        <xs:attribute type="xs:string" name="default-widget-style"/>
        <xs:attribute type="xs:string" name="default-tooltip-style"/>
        <xs:attribute type="xs:string" name="default-required-field-style"/>
+        <xs:attribute type="xs:string" name="default-sort-field-style">
+ <xs:annotation><xs:documentation>CSS style to used for form sort fields. Defaults to "sort-order".</xs:documentation></xs:annotation>
+        </xs:attribute>
+        <xs:attribute type="xs:string" name="default-sort-field-asc-style">
+ <xs:annotation><xs:documentation>CSS style to used for form sort fields. Defaults to "sort-order-asc".</xs:documentation></xs:annotation>
+        </xs:attribute>
+        <xs:attribute type="xs:string" name="default-sort-field-desc-style">
+ <xs:annotation><xs:documentation>CSS style to used for form sort fields. Defaults to "sort-order-desc".</xs:documentation></xs:annotation>
+        </xs:attribute>
        <xs:attribute name="paginate" default="true">
            <xs:simpleType>
                <xs:restriction base="xs:token">
@@ -446,6 +455,23 @@
        <xs:attribute type="xs:string" name="required-field-style">
<xs:annotation><xs:documentation>The name of a style (like a CSS class) to apply to the title of this field if required. Will default to form's default-required-field-style. If field is required, but required-field-style is empty, an '*' will be placed to the right of text, textarea and password fields.</xs:documentation></xs:annotation>
        </xs:attribute>
+        <xs:attribute name="sort-field" default="false">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="true"/>
+                    <xs:enumeration value="false"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute type="xs:string" name="sort-field-style">
+ <xs:annotation><xs:documentation>The name of a style (like a CSS class) to apply to the sort field link. Will default to form's default-sort-field-style.</xs:documentation></xs:annotation>
+        </xs:attribute>
+        <xs:attribute type="xs:string" name="sort-field-asc-style">
+ <xs:annotation><xs:documentation>The name of a style (like a CSS class) to apply to the sort field link ordered ascending. Will default to form's default-sort-field-asc-style.</xs:documentation></xs:annotation>
+        </xs:attribute>
+        <xs:attribute type="xs:string" name="sort-field-desc-style">
+ <xs:annotation><xs:documentation>The name of a style (like a CSS class) to apply to the sort field link ordered descending. Will default to form's default-sort-field-desc-style.</xs:documentation></xs:annotation>
+        </xs:attribute>
    </xs:attributeGroup>

  <!-- ================== FIELD TYPES ==================== -->

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?rev=702236&r1=702235&r2=702236&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java 
(original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java Mon 
Oct  6 12:29:40 2008
@@ -115,6 +115,9 @@
    protected boolean useRowSubmit = false;
    protected FlexibleStringExpander targetWindowExdr;
    protected String defaultRequiredFieldStyle;
+    protected String defaultSortFieldStyle;
+    protected String defaultSortFieldAscStyle;
+    protected String defaultSortFieldDescStyle;
    protected String oddRowStyle;
    protected String evenRowStyle;
    protected String defaultTableStyle;
@@ -176,6 +179,11 @@
    public static String DEFAULT_PAG_NEXT_STYLE = "nav-next";
    public static String DEFAULT_PAG_LAST_STYLE = "nav-last";

+    /** Sort field default styles. */
+    public static String DEFAULT_SORT_FIELD_STYLE = "sort-order";
+    public static String DEFAULT_SORT_FIELD_ASC_STYLE = "sort-order-asc";
+    public static String DEFAULT_SORT_FIELD_DESC_STYLE = "sort-order-desc";
+
    protected List<ModelFormAction> actions;
    protected List<ModelFormAction> rowActions;
    protected FlexibleStringExpander rowCountExdr;
@@ -387,6 +395,15 @@
        if (this.defaultRequiredFieldStyle == null || 
formElement.hasAttribute("default-required-field-style")) {
            this.defaultRequiredFieldStyle = 
formElement.getAttribute("default-required-field-style");
        }
+        if (this.defaultSortFieldStyle == null || 
formElement.hasAttribute("default-sort-field-style")) {
+            this.defaultSortFieldStyle = 
formElement.getAttribute("default-sort-field-style");
+        }
+        if (this.defaultSortFieldAscStyle == null || 
formElement.hasAttribute("default-sort-field-asc-style")) {
+            this.defaultSortFieldAscStyle = 
formElement.getAttribute("default-sort-field-asc-style");
+        }
+        if (this.defaultSortFieldDescStyle == null || 
formElement.hasAttribute("default-sort-field-desc-style")) {
+            this.defaultSortFieldDescStyle = 
formElement.getAttribute("default-sort-field-desc-style");
+        }

        // pagination settings
        if (this.paginateTarget == null || 
formElement.hasAttribute("paginate-target")) {
@@ -1794,6 +1811,18 @@
    public String getDefaultRequiredFieldStyle() {
        return this.defaultRequiredFieldStyle;
    }
+
+    public String getDefaultSortFieldStyle() {
+        return (UtilValidate.isEmpty(this.defaultSortFieldStyle) ? 
DEFAULT_SORT_FIELD_STYLE : this.defaultSortFieldStyle);
+    }
+
+    public String getDefaultSortFieldAscStyle() {
+ return (UtilValidate.isEmpty(this.defaultSortFieldAscStyle) ? DEFAULT_SORT_FIELD_ASC_STYLE : this.defaultSortFieldAscStyle);
+    }
+
+    public String getDefaultSortFieldDescStyle() {
+ return (UtilValidate.isEmpty(this.defaultSortFieldDescStyle) ? DEFAULT_SORT_FIELD_DESC_STYLE : this.defaultSortFieldDescStyle);
+    }


    /**
@@ -2589,6 +2618,25 @@
        return inbetweenList;
    }

+    public String getSortField(Map<String, Object> context) {
+        String field = "sortField";
+        String value = null;
+
+        try {
+            value = (String)context.get(field);
+            if (value == null) {
+                Map parameters = (Map) context.get("parameters");
+                if (parameters != null) {
+                    value = (String)parameters.get(field);
+                }
+            }
+        } catch (Exception e) {
+            Debug.logWarning(e, "Error getting sortField: " + e.toString(), 
module);
+        }
+
+        return value;
+    }
+
    /* Returns the list of ModelForm.UpdateArea objects.
     */
    public List<UpdateArea> getOnSubmitUpdateAreas() {

Modified: 
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java?rev=702236&r1=702235&r2=702236&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java 
(original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java 
Mon Oct  6 12:29:40 2008
@@ -92,6 +92,9 @@
    protected String widgetStyle;
    protected String tooltipStyle;
    protected String requiredFieldStyle;
+    protected String sortFieldStyle;
+    protected String sortFieldAscStyle;
+    protected String sortFieldDescStyle;
    protected Integer position = null;
    protected String redWhen;
    protected String event;
@@ -102,6 +105,7 @@
    protected String idName;
    protected boolean separateColumn = false;
    protected Boolean requiredField = null;
+    protected Boolean sortField = null;
    protected String headerLink;
    protected String headerLinkStyle;

@@ -135,6 +139,9 @@
        this.widgetStyle = fieldElement.getAttribute("widget-style");
        this.tooltipStyle = fieldElement.getAttribute("tooltip-style");
        this.requiredFieldStyle = 
fieldElement.getAttribute("required-field-style");
+        this.sortFieldStyle = fieldElement.getAttribute("sort-field-style");
+        this.sortFieldAscStyle = 
fieldElement.getAttribute("sort-field-asc-style");
+        this.sortFieldDescStyle = 
fieldElement.getAttribute("sort-field-desc-style");
        this.redWhen = fieldElement.getAttribute("red-when");
        this.event = fieldElement.getAttribute("event");
        this.setAction(fieldElement.hasAttribute("action")? 
fieldElement.getAttribute("action"): null);
@@ -144,6 +151,7 @@
        if (sepColumns != null && sepColumns.equalsIgnoreCase("true"))
            separateColumn = true;
this.requiredField = fieldElement.hasAttribute("required-field") ? "true".equals(fieldElement.getAttribute("required-field")) : null;
+        this.sortField = fieldElement.hasAttribute("sort-field") ? 
"true".equals(fieldElement.getAttribute("sort-field")) : null;
        this.headerLink = fieldElement.getAttribute("header-link");
        this.headerLinkStyle = fieldElement.getAttribute("header-link-style");

@@ -271,7 +279,8 @@
            this.tooltip = overrideFormField.tooltip;
        if (overrideFormField.requiredField != null)
            this.requiredField = overrideFormField.requiredField;
-
+        if (overrideFormField.sortField != null)
+            this.sortField = overrideFormField.sortField;
        if (UtilValidate.isNotEmpty(overrideFormField.titleAreaStyle))
            this.titleAreaStyle = overrideFormField.titleAreaStyle;
        if (UtilValidate.isNotEmpty(overrideFormField.widgetAreaStyle))
@@ -1070,6 +1079,27 @@
            return this.modelForm.getDefaultRequiredFieldStyle();
        }
    }
+
+    public String getSortFieldStyle() {
+        if (UtilValidate.isNotEmpty(this.sortFieldStyle)) {
+            return this.sortFieldStyle;
+        }
+        return this.modelForm.getDefaultSortFieldStyle();
+    }
+
+    public String getSortFieldStyleAsc() {
+        if (UtilValidate.isNotEmpty(this.sortFieldAscStyle)) {
+            return this.sortFieldAscStyle;
+        }
+        return this.modelForm.getDefaultSortFieldAscStyle();
+    }
+
+    public String getSortFieldStyleDesc() {
+        if (UtilValidate.isNotEmpty(this.sortFieldDescStyle)) {
+            return this.sortFieldDescStyle;
+        }
+        return this.modelForm.getDefaultSortFieldDescStyle();
+    }

    /**
     * @return
@@ -1378,6 +1408,20 @@
    }

    /**
+     * @return
+     */
+    public boolean isSortField() {
+        return this.sortField != null ? this.sortField.booleanValue() : false;
+    }
+
+    /**
+     * @param boolean
+     */
+    public void setSortField(boolean sort) {
+        this.sortField = Boolean.valueOf(sort);
+    }
+
+    /**
     * @param ModelForm
     */
    public void setModelForm(ModelForm modelForm) {

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?rev=702236&r1=702235&r2=702236&view=diff
==============================================================================
--- 
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java 
(original)
+++ 
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java 
Mon Oct  6 12:29:40 2008
@@ -2416,6 +2416,85 @@
        appendWhitespace(writer);
    }

+ public void renderSortField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
+        boolean ajaxEnabled = false;
+        ModelForm modelForm = modelFormField.getModelForm();
+        List<ModelForm.UpdateArea> updateAreas = 
modelForm.getOnPaginateUpdateAreas();
+        String targetService = modelForm.getPaginateTarget(context);
+        if (this.javaScriptEnabled) {
+            if (UtilValidate.isNotEmpty(updateAreas)) {
+                ajaxEnabled = true;
+            }
+        }
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
+            Debug.logWarning("Cannot sort because TargetService is empty for the 
form: " + modelForm.getName(), module);
+            return;
+        }
+
+        String str = (String) context.get("_QBESTRING_");
+        String oldSortField = modelForm.getSortField(context);
+        String sortFieldStyle = modelFormField.getSortFieldStyle();
+
+        // if the entry-name is defined use this instead of field name
+        String coulumnField = modelFormField.getEntryName();
+        if (UtilValidate.isEmpty(coulumnField)) {
+            coulumnField = modelFormField.getFieldName();
+        }
+
+        // switch beetween asc/desc order
+        String newSortField = coulumnField;
+        if (UtilValidate.isNotEmpty(oldSortField)) {
+            if (oldSortField.equals(coulumnField)) {
+                newSortField = "-" + coulumnField;
+                sortFieldStyle = modelFormField.getSortFieldStyleDesc();
+            } else if (oldSortField.equals("-" + coulumnField)) {
+                newSortField = coulumnField;
+                sortFieldStyle = modelFormField.getSortFieldStyleAsc();
+            }
+        }
+
+        //  strip sortField param from the query string
+        HashSet<String> paramName = new HashSet<String>();
+        paramName.add("sortField");
+        String queryString = UtilHttp.stripNamedParamsFromQueryString(str, 
paramName);
+        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
+        String prepLinkText = UtilHttp.getQueryStringFromTarget(targetService);
+        if (prepLinkText == null) {
+            prepLinkText = "";
+        }
+        if (prepLinkText.indexOf("?") < 0) {
+            prepLinkText += "?";
+        } else if (!prepLinkText.endsWith("?")) {
+            prepLinkText += "&amp;";
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) 
{
+            prepLinkText += queryString + "&amp;";
+        }
+        prepLinkText += "sortField" + "=" + newSortField;
+        if (ajaxEnabled) {
+            prepLinkText = prepLinkText.replace("?", "");
+            prepLinkText = prepLinkText.replace("&amp;", "&");
+        }
+
+        writer.append("<a");
+        if (UtilValidate.isNotEmpty(sortFieldStyle)) {
+            writer.append(" class=\"");
+            writer.append(sortFieldStyle);
+            writer.append("\"");
+        }
+
+        writer.append(" href=\"");
+        if (ajaxEnabled) {
+ writer.append("javascript:ajaxUpdateAreas('" + createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText, context) + "')");
+        } else {
+            writer.append(rh.makeLink(this.request, this.response, urlPath + 
prepLinkText));
+        }
+        writer.append("\">" + titleText + "</a>");
+    }
+
    /* (non-Javadoc)
* @see org.ofbiz.widget.form.FormStringRenderer#renderFileField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.FileField)
     */
@@ -2679,6 +2758,8 @@
            targetType="plain";
            }
makeHyperlinkString(writer, modelFormField.getHeaderLinkStyle(), targetType, targetBuffer.toString(), titleText, null, null, null);
+        } else if (modelFormField.isSortField()) {
+            renderSortField (writer, context, modelFormField, titleText);
        } else if (modelFormField.isRowSubmit()) {
            if (UtilValidate.isNotEmpty(titleText)) writer.append(titleText + 
"<br/>");
            writer.append("<input type=\"checkbox\" name=\"selectAll\" value=\"Y\" 
onclick=\"javascript:toggleAll(this, '");



Reply via email to