This is an automated email from the ASF dual-hosted git repository.
nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push:
new b663660 Implemented: on-event-update-area on form inherit information
from parent form (OFBIZ-11811) (OFBIZ-11808)
b663660 is described below
commit b663660486074196385bdf08034547839dc1e11c
Author: Nicolas Malin <[email protected]>
AuthorDate: Fri May 21 17:40:46 2021 +0200
Implemented: on-event-update-area on form inherit information from parent
form
(OFBIZ-11811) (OFBIZ-11808)
When you write a form, if you want the dynamic interaction and style, you
need to implement everything on the form.
The developer must know the style used, different area and rules support by
the technology besides the really information/action that the form will do.
<form name="ListFacility" type="list" list-name="listIt"
paginate-target="FindFacility"
odd-row-style="alternate-row" header-row-style="header-row-2"
default-table-style="basic-table hover-bar">
<actions>...
<field name="facilityId">....
<on-event-update-area event-type="sort-column"
area-id="search-results" area-target="FacilitySearchResults"/>
<on-event-update-area event-type="paginate" area-id="search-results"
area-target="FacilitySearchResults"/>
</form>
We can put all information on the theme and all dynamic refresh (for area)
are related to the parent form and parent screen. Finally we will obtain :
<form name="ListFacility" extends="CommonDynamicList"
extends-resource="component://common/widget/CommonForms.xml"
paginate-target="FindFacility">
<actions>...
<field name="facilityId">....
</form>
<form name="CommonDynamicList" type="list"
odd-row-style="alternate-row" header-row-style="header-row-2"
default-table-style="basic-table hover-bar">
<on-event-update-area event-type="sort-column"/>
<on-event-update-area event-type="paginate"/>
</form>
The target and area to update has been automatically resolved from the
parent form and screen.
This commit improve the modelForm and the widget-form.xsd to do that.
Thanks to Gil Portenseigne his help
---
.../ofbiz/webapp/control/RequestHandler.java | 4 +-
framework/widget/dtd/widget-form.xsd | 20 ++++-
.../org/apache/ofbiz/widget/model/ModelForm.java | 2 +
.../widget/renderer/macro/MacroCommonRenderer.java | 90 +++++++++++-----------
.../widget/renderer/macro/MacroFormRenderer.java | 23 +++---
5 files changed, 81 insertions(+), 58 deletions(-)
diff --git
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
index 46ed743..9ebd1e4 100644
---
a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
+++
b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
@@ -1388,10 +1388,10 @@ public final class RequestHandler {
}
// now add the actual passed url, but if it doesn't start with a / add
one first
- if (!url.startsWith("/")) {
+ if (url != null && !url.startsWith("/")) {
newURL.append("/");
}
- newURL.append(url);
+ newURL.append(url == null ? "": url);
String encodedUrl;
if (encode) {
diff --git a/framework/widget/dtd/widget-form.xsd
b/framework/widget/dtd/widget-form.xsd
index c989030..93e5d56 100644
--- a/framework/widget/dtd/widget-form.xsd
+++ b/framework/widget/dtd/widget-form.xsd
@@ -597,8 +597,24 @@ under the License.
</xs:restriction>
</xs:simpleType>
</xs:attribute>
- <xs:attribute name="area-id" type="xs:string" use="required" />
- <xs:attribute name="area-target" type="xs:string" use="required" />
+ <xs:attribute name="area-id" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>
+ Mandatory in classic usage.
+ This has been made optional for template needs
(common-theme) and automatic area-id
+ definition, based on calling widget.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="area-target" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>
+ Mandatory in classic usage.
+ This has been made optional for template needs
(common-theme) and automatic area-id
+ definition, based on calling widget.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:complexType>
</xs:element>
diff --git
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
index 62d9d91..1869d2b 100644
---
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
+++
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
@@ -36,6 +36,7 @@ import org.apache.ofbiz.base.util.GroovyUtil;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilCodec;
import org.apache.ofbiz.base.util.UtilGenerics;
+import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
@@ -2278,6 +2279,7 @@ public abstract class ModelForm extends ModelWidget {
* elements used in form widgets.
*/
public static class UpdateArea {
+ public static final List<String> EVENT_TYPES_FOR_LIST_REFRESH =
UtilMisc.toList("paginate", "sort-column");
private final String eventType;
private final String areaId;
private final String areaTarget;
diff --git
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
index 8fb85f5..997317f 100644
---
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
+++
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
@@ -23,21 +23,19 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilMisc;
+import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
import org.apache.ofbiz.webapp.control.RequestHandler;
import org.apache.ofbiz.widget.WidgetWorker;
import org.apache.ofbiz.widget.model.CommonWidgetModels;
import org.apache.ofbiz.widget.model.ModelForm;
-/**
- * TODO : Migrate to {@link
org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtl}
- */
public class MacroCommonRenderer {
/**
@@ -50,38 +48,56 @@ public class MacroCommonRenderer {
* @return Parameter string or empty string if no UpdateArea objects were
found
*/
public static String
createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas,
Map<String, Object> extraParams,
- String anchor, Map<String,
? extends Object> context) {
+ ModelForm
parentModelForm, String anchor, Map<String, ? extends Object> context) {
HttpServletRequest request = (HttpServletRequest)
context.get("request");
HttpServletResponse response = (HttpServletResponse)
context.get("response");
+ Map<String, Object> ctx = UtilGenerics.cast(context);
RequestHandler rh = RequestHandler.from(request);
StringBuilder sb = new StringBuilder();
Iterator<ModelForm.UpdateArea> updateAreaIter = updateAreas.iterator();
while (updateAreaIter.hasNext()) {
ModelForm.UpdateArea updateArea = updateAreaIter.next();
- sb.append(updateArea.getAreaId()).append(",");
+
+ //For each update area we need to resolve three information below
+ String areaIdToUpdate;
+ String targetToCall;
+ String parametersToForward;
+
+ // 1. areaId to update, use the screen stack with the potential
area given by the update area element
+ areaIdToUpdate =
WidgetWorker.getScreenStack(ctx).resolveScreenAreaId(updateArea.getAreaId());
+
+ // 2. the target, if the updateArea haven't the information and we
are on event link to the pagination,
+ // will ask to the parent model the pagination target
String ajaxTarget = updateArea.getAreaTarget(context);
- String urlPath = UtilHttp.removeQueryStringFromTarget(ajaxTarget);
- sb.append(rh.makeLink(request, response, urlPath)).append(",");
+ if (UtilValidate.isEmpty(ajaxTarget)
+ && parentModelForm != null) {
+ if
(ModelForm.UpdateArea.EVENT_TYPES_FOR_LIST_REFRESH.contains(updateArea.getEventType()))
{
+ ajaxTarget = parentModelForm.getPaginateTarget(ctx);
+ } else {
+ ajaxTarget = parentModelForm.getTarget(ctx,
parentModelForm.getTargetType());
+ }
+ }
+ targetToCall = rh.makeLink(request, response,
UtilHttp.removeQueryStringFromTarget(ajaxTarget));
+
+ // 3. Build parameters to forward
String queryString =
UtilHttp.getQueryStringFromTarget(ajaxTarget).replace("?", "");
Map<String, Object> parameters =
UtilHttp.getQueryStringOnlyParameterMap(queryString);
- Map<String, Object> ctx = UtilGenerics.cast(context);
- Map<String, Object> updateParams =
UtilGenerics.cast(updateArea.getParameterMap(ctx));
- parameters.putAll(updateParams);
+
parameters.putAll(UtilGenerics.cast(updateArea.getParameterMap(ctx)));
UtilHttp.canonicalizeParameterMap(parameters);
- if (extraParams != null) {
- 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("&");
- }
+ parametersToForward = UtilHttp.urlEncodeArgs(parameters, false);
+ if (UtilValidate.isNotEmpty(parametersToForward)
+ && UtilValidate.isNotEmpty(extraParams)) {
+ parametersToForward += "&";
}
- if (anchor != null) {
+ parametersToForward += buildParamStringFromMap(extraParams);
+
+ // 4. build the final string
+ sb.append(areaIdToUpdate).append(",")
+ .append(targetToCall).append(",")
+ .append(parametersToForward);
+ if (UtilValidate.isNotEmpty(anchor)) {
sb.append("#").append(anchor);
}
if (updateAreaIter.hasNext()) {
@@ -92,28 +108,12 @@ public class MacroCommonRenderer {
return FlexibleStringExpander.expandString(sb.toString(), context,
locale);
}
- /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea
objects. See
- * <code>OfbizUtil.js</code>.
- * @param updateAreas
- * @param extraParams Renderer-supplied additional target parameters String
- * @param context
- * @return Parameter string or empty string if no UpdateArea objects were
found
- */
- public static String
createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, String
extraParams,
- Map<String, ? extends
Object> context) {
- Map<String, Object> extraParamsAsMap =
buildParamMapFromString(extraParams);
- return createAjaxParamsFromUpdateAreas(updateAreas, extraParamsAsMap,
null, context);
- }
-
- private static Map<String, Object> buildParamMapFromString(String
extraParams) {
- Map<String, Object> extraParamsAsMap = null;
- if (extraParams != null) {
- while (extraParams.startsWith("&")) {
- extraParams = extraParams.replaceFirst("&", "");
- }
- extraParamsAsMap =
UtilGenerics.cast(StringUtil.strToMap(extraParams, "&", false));
- }
- return extraParamsAsMap;
+ private static String buildParamStringFromMap(Map<String, Object>
extraParamsAsMap) {
+ if (extraParamsAsMap == null) return "";
+ final Map<String, Object> extraParamsAsMapConverted = extraParamsAsMap;
+ return extraParamsAsMap.keySet().stream()
+ .map(key -> key + "=" + extraParamsAsMapConverted.get(key))
+ .collect(Collectors.joining("&"));
}
/**
@@ -132,7 +132,7 @@ public class MacroCommonRenderer {
WidgetWorker.getScreenStack(context).resolveScreenAreaId(link.getTargetWindow(context)),
link.getTarget(context));
linkUrl =
createAjaxParamsFromUpdateAreas(UtilMisc.toList(resolveUpdateArea),
- UtilHttp.urlEncodeArgs(link.getParameterMap(context)),
context);
+ UtilGenerics.cast(link.getParameterMap(context)), null,
null, context);
break;
default:
final URI linkUri =
WidgetWorker.buildHyperlinkUri(link.getTarget(context), link.getUrlMode(),
diff --git
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
index 2e0e5af..d093526 100644
---
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
+++
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
@@ -1022,7 +1022,7 @@ public final class MacroFormRenderer implements
FormStringRenderer {
&& this.javaScriptEnabled;
String ajaxUrl = "";
if (ajaxEnabled) {
- ajaxUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, "", context);
+ ajaxUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
modelForm, "", context);
}
String tabindex = modelFormField.getTabindex();
StringWriter sr = new StringWriter();
@@ -2117,7 +2117,7 @@ public final class MacroFormRenderer implements
FormStringRenderer {
this.appendContentUrl(imgSrc, "/images/fieldlookup.gif");
String ajaxUrl = "";
if (ajaxEnabled) {
- ajaxUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, "", context);
+ ajaxUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
modelForm, "", context);
}
String lookupPresentation = lookupField.getLookupPresentation();
if (UtilValidate.isEmpty(lookupPresentation)) {
@@ -2341,7 +2341,7 @@ public final class MacroFormRenderer implements
FormStringRenderer {
String ajaxLastUrl = "";
if (viewIndex > 0) {
if (ajaxEnabled) {
- ajaxFirstUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText +
0 + anchor, context);
+ ajaxFirstUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
modelForm, prepLinkText + 0 + anchor, context);
} else {
linkText = prepLinkText + 0 + anchor;
firstUrl = rh.makeLink(this.request, this.response, urlPath +
linkText);
@@ -2349,7 +2349,8 @@ public final class MacroFormRenderer implements
FormStringRenderer {
}
if (viewIndex > 0) {
if (ajaxEnabled) {
- ajaxPreviousUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText +
(viewIndex - 1) + anchor, context);
+ ajaxPreviousUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
modelForm,
+ prepLinkText + (viewIndex - 1) + anchor, context);
} else {
linkText = prepLinkText + (viewIndex - 1) + anchor;
previousUrl = rh.makeLink(this.request, this.response, urlPath
+ linkText);
@@ -2358,7 +2359,8 @@ public final class MacroFormRenderer implements
FormStringRenderer {
// Page select dropdown
if (listSize > 0 && this.javaScriptEnabled) {
if (ajaxEnabled) {
- ajaxSelectUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText +
"' + this.value + '", context);
+ ajaxSelectUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
modelForm,
+ prepLinkText + "' + this.value + '", context);
} else {
linkText = prepLinkText;
if (linkText.startsWith("/")) {
@@ -2370,7 +2372,8 @@ public final class MacroFormRenderer implements
FormStringRenderer {
// Next button
if (highIndex < listSize) {
if (ajaxEnabled) {
- ajaxNextUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText +
(viewIndex + 1) + anchor, context);
+ ajaxNextUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
+ modelForm, prepLinkText + (viewIndex + 1) + anchor,
context);
} else {
linkText = prepLinkText + (viewIndex + 1) + anchor;
nextUrl = rh.makeLink(this.request, this.response, urlPath +
linkText);
@@ -2380,7 +2383,8 @@ public final class MacroFormRenderer implements
FormStringRenderer {
if (highIndex < listSize) {
int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
if (ajaxEnabled) {
- ajaxLastUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText +
lastIndex + anchor, context);
+ ajaxLastUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
+ modelForm, prepLinkText + lastIndex + anchor, context);
} else {
linkText = prepLinkText + lastIndex + anchor;
lastUrl = rh.makeLink(this.request, this.response, urlPath +
linkText);
@@ -2389,7 +2393,8 @@ public final class MacroFormRenderer implements
FormStringRenderer {
// Page size select dropdown
if (listSize > 0 && this.javaScriptEnabled) {
if (ajaxEnabled) {
- ajaxSelectSizeUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas,
prepLinkSizeText + anchor, context);
+ ajaxSelectSizeUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null,
+ modelForm, prepLinkSizeText + anchor, context);
} else {
linkText = prepLinkSizeText;
if (linkText.startsWith("/")) {
@@ -2833,7 +2838,7 @@ public final class MacroFormRenderer implements
FormStringRenderer {
UtilHttp.canonicalizeParameterMap(paramMap);
String linkUrl = null;
if (ajaxEnabled) {
- linkUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, paramMap,
null, context);
+ linkUrl =
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, paramMap,
modelForm, null, context);
} else {
StringBuilder sb = new StringBuilder("?");
Iterator<Map.Entry<String, Object>> iter =
paramMap.entrySet().iterator();