Author: adrianc
Date: Fri May 31 17:07:00 2013
New Revision: 1488315
URL: http://svn.apache.org/r1488315
Log:
Fixed some bugs in the form widget column sorting code:
1. URL parameters were being mangled by clunky string manipulation code.
2. The sort column logic was piggy-backed on the pagination event. I created a
new choice for the form widget <on-event-update-area> element - "sort-column" -
so column sort events can update their own areas.
3. The parameter name for the sort column was hard-coded, so column sorting in
multiple lists on the same screen would not work. I added a new <form>
attribute - "sort-field-parameter-name" - so each list can be sorted separately.
Modified:
ofbiz/trunk/framework/widget/dtd/widget-form.xsd
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
Modified: ofbiz/trunk/framework/widget/dtd/widget-form.xsd
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/dtd/widget-form.xsd?rev=1488315&r1=1488314&r2=1488315&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/dtd/widget-form.xsd (original)
+++ ofbiz/trunk/framework/widget/dtd/widget-form.xsd Fri May 31 17:07:00 2013
@@ -115,6 +115,14 @@ under the License.
<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="sort-field-parameter-name">
+ <xs:annotation>
+ <xs:documentation>
+ The name of the request parameter that is used for
specifying the sorted column. This is required when you
+ have more than one list on a screen - each list must
use its own sort field parameter. Defaults to "sortField".
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
<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>
@@ -424,6 +432,7 @@ under the License.
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="paginate" />
+ <xs:enumeration value="sort-column" />
<xs:enumeration value="submit" />
</xs:restriction>
</xs:simpleType>
Modified:
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java?rev=1488315&r1=1488314&r2=1488315&view=diff
==============================================================================
---
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
(original)
+++
ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
Fri May 31 17:07:00 2013
@@ -353,7 +353,7 @@ public class MacroFormRenderer implement
if (UtilValidate.isNotEmpty(textField.getMask())) {
mask = textField.getMask();
}
- String ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, null,
context);
+ String ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "",
context);
boolean disabled = textField.disabled;
StringWriter sr = new StringWriter();
sr.append("<@renderTextField ");
@@ -1091,7 +1091,7 @@ public class MacroFormRenderer implement
boolean ajaxEnabled = (updateAreas != null ||
UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) &&
this.javaScriptEnabled;
String ajaxUrl = "";
if (ajaxEnabled) {
- ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, null,
context);
+ ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "",
context);
}
StringWriter sr = new StringWriter();
sr.append("<@renderSubmitField ");
@@ -2037,7 +2037,7 @@ public class MacroFormRenderer implement
this.appendContentUrl(imgSrc, "/images/fieldlookup.gif");
String ajaxUrl = "";
if (ajaxEnabled) {
- ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, null,
context);
+ ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "",
context);
}
String lookupPresentation = lookupField.getLookupPresentation();
if (UtilValidate.isEmpty(lookupPresentation)) {
@@ -2679,21 +2679,21 @@ public class MacroFormRenderer implement
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);
+ List<ModelForm.UpdateArea> updateAreas =
modelForm.getOnSortColumnUpdateAreas();
+ if (updateAreas == null) {
+ // For backward compatibility.
+ updateAreas = modelForm.getOnPaginateUpdateAreas();
+ }
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);
+ String paginateTarget = modelForm.getPaginateTarget(context);
+ if (paginateTarget.isEmpty() && updateAreas == null) {
+ Debug.logWarning("Cannot sort because the paginate target URL 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
@@ -2701,7 +2701,7 @@ public class MacroFormRenderer implement
if (UtilValidate.isEmpty(columnField)) {
columnField = modelFormField.getFieldName();
}
- // switch beetween asc/desc order
+ // switch between asc/desc order
String newSortField = columnField;
if (UtilValidate.isNotEmpty(oldSortField)) {
if (oldSortField.equals(columnField)) {
@@ -2712,36 +2712,31 @@ public class MacroFormRenderer implement
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 (UtilValidate.isNotEmpty(queryString)) {
- queryString = UtilHttp.encodeAmpersands(queryString);
- }
- if (prepLinkText == null) {
- prepLinkText = "";
- }
- if (prepLinkText.indexOf("?") < 0) {
- prepLinkText += "?";
- } else if (!prepLinkText.endsWith("?")) {
- prepLinkText += "&";
- }
- if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null"))
{
- prepLinkText += queryString + "&";
- }
- prepLinkText += "sortField" + "=" + newSortField;
- if (ajaxEnabled) {
- prepLinkText = prepLinkText.replace("?", "");
- prepLinkText = prepLinkText.replace("&", "&");
- }
- String linkUrl = "";
+ String queryString =
UtilHttp.getQueryStringFromTarget(paginateTarget).replace("?", "");
+ Map<String, Object> paramMap =
UtilHttp.getQueryStringOnlyParameterMap(queryString);
+ String qbeString = (String) context.get("_QBESTRING_");
+ if (qbeString != null) {
+ qbeString = qbeString.replaceAll("&", "&");
+
paramMap.putAll(UtilHttp.getQueryStringOnlyParameterMap(qbeString));
+ }
+ paramMap.put(modelForm.getSortFieldParameterName(), newSortField);
+ UtilHttp.canonicalizeParameterMap(paramMap);
+ String linkUrl = null;
if (ajaxEnabled) {
- linkUrl = createAjaxParamsFromUpdateAreas(updateAreas,
prepLinkText, context);
+ linkUrl = createAjaxParamsFromUpdateAreas(updateAreas, paramMap,
null, context);
} else {
- linkUrl = rh.makeLink(this.request, this.response, urlPath +
prepLinkText);
+ StringBuilder sb = new StringBuilder("?");
+ Iterator<Map.Entry<String, Object>> iter =
paramMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry<String, Object> entry = iter.next();
+ sb.append(entry.getKey()).append("=").append(entry.getValue());
+ if (iter.hasNext()) {
+ sb.append("&");
+ }
+ }
+ String newQueryString = sb.toString();
+ String urlPath =
UtilHttp.removeQueryStringFromTarget(paginateTarget);
+ linkUrl = rh.makeLink(this.request, this.response,
urlPath.concat(newQueryString));
}
StringWriter sr = new StringWriter();
sr.append("<@renderSortField ");
@@ -2755,7 +2750,47 @@ public class MacroFormRenderer implement
sr.append(Boolean.toString(ajaxEnabled));
sr.append(" />");
executeMacro(writer, sr.toString());
+ }
+ /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea
objects. See
+ * <code>selectall.js</code>.
+ * @param updateAreas
+ * @param extraParams Renderer-supplied additional target parameters
+ * @param context
+ * @return Parameter string or empty string if no UpdateArea objects were
found
+ */
+ private String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea>
updateAreas, Map<String, Object> extraParams, String anchor, Map<String, ?
extends Object> context) {
+ StringBuilder sb = new StringBuilder();
+ Iterator<ModelForm.UpdateArea> updateAreaIter = updateAreas.iterator();
+ while (updateAreaIter.hasNext()) {
+ ModelForm.UpdateArea updateArea = updateAreaIter.next();
+ sb.append(updateArea.getAreaId()).append(",");
+ String ajaxTarget = updateArea.getAreaTarget(context);
+ String urlPath = UtilHttp.removeQueryStringFromTarget(ajaxTarget);
+ sb.append(this.rh.makeLink(this.request,
this.response,urlPath)).append(",");
+ String queryString =
UtilHttp.getQueryStringFromTarget(ajaxTarget).replace("?", "");
+ Map<String, Object> parameters =
UtilHttp.getQueryStringOnlyParameterMap(queryString);
+ Map<String, Object> ctx = UtilGenerics.checkMap(context);
+ Map<String, Object> updateParams =
UtilGenerics.checkMap(updateArea.getParameterMap(ctx));
+ parameters.putAll(updateParams);
+ UtilHttp.canonicalizeParameterMap(parameters);
+ parameters.putAll(extraParams);
+ Iterator<Map.Entry<String, Object>> paramIter =
parameters.entrySet().iterator();
+ while (paramIter.hasNext()) {
+ Map.Entry<String, Object> entry = paramIter.next();
+ sb.append(entry.getKey()).append("=").append(entry.getValue());
+ if (paramIter.hasNext()) {
+ sb.append("&");
+ }
+ }
+ if (anchor != null) {
+ sb.append("#").append(anchor);
+ }
+ if (updateAreaIter.hasNext()) {
+ sb.append(",");
+ }
+ }
+ return sb.toString();
}
/** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea
objects. See
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=1488315&r1=1488314&r2=1488315&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 Fri
May 31 17:07:00 2013
@@ -198,11 +198,14 @@ public class ModelForm extends ModelWidg
protected FlexibleStringExpander rowCountExdr;
protected List<ModelFormField> multiSubmitFields = FastList.newInstance();
protected int rowCount = 0;
+ private String sortFieldParameterName = "sortField";
/** On Submit areas to be updated. */
protected List<UpdateArea> onSubmitUpdateAreas;
/** On Paginate areas to be updated. */
protected List<UpdateArea> onPaginateUpdateAreas;
+ /** On Sort Column areas to be updated. */
+ protected List<UpdateArea> onSortColumnUpdateAreas;
// ===== CONSTRUCTORS =====
/** Default Constructor */
@@ -305,6 +308,7 @@ public class ModelForm extends ModelWidg
this.defaultViewSize = parent.defaultViewSize;
this.onSubmitUpdateAreas = parent.onSubmitUpdateAreas;
this.onPaginateUpdateAreas = parent.onPaginateUpdateAreas;
+ this.onSortColumnUpdateAreas = parent.onSortColumnUpdateAreas;
this.altRowStyles = parent.altRowStyles;
this.useWhenFields = parent.useWhenFields;
@@ -324,6 +328,7 @@ public class ModelForm extends ModelWidg
this.fieldGroupMap = parent.fieldGroupMap;
this.fieldGroupList = parent.fieldGroupList;
this.lastOrderFields = parent.lastOrderFields;
+ this.sortFieldParameterName = parent.sortFieldParameterName;
}
}
@@ -462,7 +467,10 @@ public class ModelForm extends ModelWidg
if (this.paginate == null || formElement.hasAttribute("paginate")) {
this.paginate =
FlexibleStringExpander.getInstance(formElement.getAttribute("paginate"));
}
-
+ String sortFieldParameterName =
formElement.getAttribute("sort-field-parameter-name");
+ if (!sortFieldParameterName.isEmpty()) {
+ this.sortFieldParameterName = sortFieldParameterName;
+ }
this.skipStart = "true".equals(formElement.getAttribute("skip-start"));
this.skipEnd = "true".equals(formElement.getAttribute("skip-end"));
this.hideHeader =
"true".equals(formElement.getAttribute("hide-header"));
@@ -686,6 +694,8 @@ public class ModelForm extends ModelWidg
addOnPaginateUpdateArea(updateArea);
} else if ("submit".equals(updateArea.getEventType())) {
addOnSubmitUpdateArea(updateArea);
+ } else if ("sort-column".equals(updateArea.getEventType())) {
+ addOnSortColumnUpdateArea(updateArea);
}
}
@@ -718,6 +728,23 @@ public class ModelForm extends ModelWidg
}
}
+ protected void addOnSortColumnUpdateArea(UpdateArea updateArea) {
+ if (onSortColumnUpdateAreas == null) {
+ onSortColumnUpdateAreas = FastList.newInstance();
+ }
+ int index = onSortColumnUpdateAreas.indexOf(updateArea);
+ if (index != -1) {
+ if (UtilValidate.isNotEmpty(updateArea.areaTarget)) {
+ onSortColumnUpdateAreas.set(index, updateArea);
+ } else {
+ // blank target indicates a removing override
+ onSortColumnUpdateAreas.remove(index);
+ }
+ } else {
+ onSortColumnUpdateAreas.add(updateArea);
+ }
+ }
+
public void addAutoFieldsFromService(AutoFieldsService autoFieldsService) {
autoFieldsServices.add(autoFieldsService);
@@ -2335,6 +2362,10 @@ public class ModelForm extends ModelWidg
this.type = string;
}
+ public List<UpdateArea> getOnSortColumnUpdateAreas() {
+ return this.onSortColumnUpdateAreas;
+ }
+
public List<UpdateArea> getOnPaginateUpdateAreas() {
return this.onPaginateUpdateAreas;
}
@@ -2758,24 +2789,25 @@ public class ModelForm extends ModelWidg
}
public String getSortField(Map<String, Object> context) {
- String field = "sortField";
String value = null;
-
try {
- value = (String)context.get(field);
+ value = (String)context.get(this.sortFieldParameterName);
if (value == null) {
Map<String, String> parameters =
UtilGenerics.cast(context.get("parameters"));
if (parameters != null) {
- value = parameters.get(field);
+ value = parameters.get(this.sortFieldParameterName);
}
}
} catch (Exception e) {
Debug.logWarning(e, "Error getting sortField: " + e.toString(),
module);
}
-
return value;
}
+ public String getSortFieldParameterName() {
+ return this.sortFieldParameterName;
+ }
+
/* Returns the list of ModelForm.UpdateArea objects.
*/
public List<UpdateArea> getOnSubmitUpdateAreas() {