blob: a2a5402a060f21fac6a94d89bd8209538a9db5c0 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* 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
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.apache.ofbiz.widget.renderer.macro;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilCodec;
import org.apache.ofbiz.base.util.UtilFormatOut;
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.ModelForm;
import org.apache.ofbiz.widget.model.ModelFormField;
import org.apache.ofbiz.widget.model.ModelFormField.ContainerField;
import org.apache.ofbiz.widget.model.ModelFormField.DisplayField;
import org.apache.ofbiz.widget.model.ModelScreenWidget.Label;
import org.apache.ofbiz.widget.model.ModelTheme;
import org.apache.ofbiz.widget.renderer.Paginator;
import org.apache.ofbiz.widget.renderer.VisualTheme;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtlMacroCall;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtl;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtlMacroCall.RenderableFtlMacroCallBuilder;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtlSequence;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtlString;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtlNoop;
import org.apache.ofbiz.widget.renderer.macro.renderable.RenderableFtlString.RenderableFtlStringBuilder;
import org.jsoup.nodes.Element;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.StringWriter;
import java.net.URI;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/**
* Creates RenderableFtl objects used to render the various elements of a form.
*/
public final class RenderableFtlFormElementsBuilder {
private static final String MODULE = RenderableFtlFormElementsBuilder.class.getName();
private final UtilCodec.SimpleEncoder internalEncoder = UtilCodec.getEncoder("string");
private final VisualTheme visualTheme;
private final RequestHandler requestHandler;
private final HttpServletRequest request;
private final HttpServletResponse response;
public RenderableFtlFormElementsBuilder(final VisualTheme visualTheme, final RequestHandler requestHandler,
final HttpServletRequest request, final HttpServletResponse response) {
this.visualTheme = visualTheme;
this.requestHandler = requestHandler;
this.request = request;
this.response = response;
}
public RenderableFtl tooltip(final Map<String, Object> context, final ModelFormField modelFormField) {
final String tooltip = modelFormField.getTooltip(context);
return RenderableFtlMacroCall.builder()
.name("renderTooltip")
.stringParameter("tooltip", tooltip)
.stringParameter("tooltipStyle", modelFormField.getTitleStyle())
.build();
}
public RenderableFtl asterisks(final Map<String, Object> context, final ModelFormField modelFormField) {
String requiredField = "false";
String requiredStyle = "";
if (modelFormField.getRequiredField()) {
requiredField = "true";
requiredStyle = modelFormField.getRequiredFieldStyle();
}
return RenderableFtlMacroCall.builder()
.name("renderAsterisks")
.stringParameter("requiredField", requiredField)
.stringParameter("requiredStyle", requiredStyle)
.build();
}
public RenderableFtl label(final Map<String, Object> context, final Label label) {
final String labelText = label.getText(context);
if (UtilValidate.isEmpty(labelText)) {
// nothing to render
return RenderableFtlNoop.INSTANCE;
}
return RenderableFtlMacroCall.builder()
.name("renderLabel")
.stringParameter("text", labelText)
.build();
}
public RenderableFtl displayField(final Map<String, Object> context, final DisplayField displayField,
final boolean javaScriptEnabled) {
ModelFormField modelFormField = displayField.getModelFormField();
String idName = modelFormField.getCurrentContainerId(context);
String description = displayField.getDescription(context);
String type = displayField.getType();
String imageLocation = displayField.getImageLocation(context);
Integer size = Integer.valueOf("0");
String title = "";
if (UtilValidate.isNotEmpty(displayField.getSize())) {
try {
size = Integer.parseInt(displayField.getSize());
} catch (NumberFormatException nfe) {
Debug.logError(nfe, "Error reading size of a field fieldName="
+ displayField.getModelFormField().getFieldName() + " FormName= "
+ displayField.getModelFormField().getModelForm().getName(), MODULE);
}
}
ModelFormField.InPlaceEditor inPlaceEditor = displayField.getInPlaceEditor();
boolean ajaxEnabled = inPlaceEditor != null && javaScriptEnabled;
if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) {
title = description;
description = description.substring(0, size - 8) + "..." + description.substring(description.length() - 5);
}
final RenderableFtlMacroCallBuilder builder = RenderableFtlMacroCall.builder()
.name("renderDisplayField")
.stringParameter("type", type)
.stringParameter("imageLocation", imageLocation)
.stringParameter("idName", idName)
.stringParameter("description", description)
.stringParameter("title", title)
.stringParameter("class", modelFormField.getWidgetStyle())
.stringParameter("alert", modelFormField.shouldBeRed(context) ? "true" : "false");
StringWriter sr = new StringWriter();
sr.append("<@renderDisplayField ");
if (ajaxEnabled) {
String url = inPlaceEditor.getUrl(context);
StringBuffer extraParameterBuffer = new StringBuffer();
String extraParameter;
Map<String, Object> fieldMap = inPlaceEditor.getFieldMap(context);
Set<Map.Entry<String, Object>> fieldSet = fieldMap.entrySet();
Iterator<Map.Entry<String, Object>> fieldIterator = fieldSet.iterator();
int count = 0;
extraParameterBuffer.append("{");
while (fieldIterator.hasNext()) {
count++;
Map.Entry<String, Object> field = fieldIterator.next();
extraParameterBuffer.append(field.getKey() + ":'" + (String) field.getValue() + "'");
if (count < fieldSet.size()) {
extraParameterBuffer.append(',');
}
}
extraParameterBuffer.append("}");
extraParameter = extraParameterBuffer.toString();
builder.stringParameter("inPlaceEditorUrl", url);
StringWriter inPlaceEditorParams = new StringWriter();
inPlaceEditorParams.append("{name: '");
if (UtilValidate.isNotEmpty(inPlaceEditor.getParamName())) {
inPlaceEditorParams.append(inPlaceEditor.getParamName());
} else {
inPlaceEditorParams.append(modelFormField.getFieldName());
}
inPlaceEditorParams.append("'");
inPlaceEditorParams.append(", method: 'POST'");
inPlaceEditorParams.append(", submitdata: " + extraParameter);
inPlaceEditorParams.append(", type: 'textarea'");
inPlaceEditorParams.append(", select: 'true'");
inPlaceEditorParams.append(", onreset: function(){jQuery('#cc_" + idName
+ "').css('background-color', 'transparent');}");
if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelText())) {
inPlaceEditorParams.append(", cancel: '" + inPlaceEditor.getCancelText() + "'");
} else {
inPlaceEditorParams.append(", cancel: 'Cancel'");
}
if (UtilValidate.isNotEmpty(inPlaceEditor.getClickToEditText())) {
inPlaceEditorParams.append(", tooltip: '" + inPlaceEditor.getClickToEditText() + "'");
}
if (UtilValidate.isNotEmpty(inPlaceEditor.getFormClassName())) {
inPlaceEditorParams.append(", cssclass: '" + inPlaceEditor.getFormClassName() + "'");
} else {
inPlaceEditorParams.append(", cssclass: 'inplaceeditor-form'");
}
if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingText())) {
inPlaceEditorParams.append(", indicator: '" + inPlaceEditor.getLoadingText() + "'");
}
if (UtilValidate.isNotEmpty(inPlaceEditor.getOkControl())) {
inPlaceEditorParams.append(", submit: ");
if (!"false".equals(inPlaceEditor.getOkControl())) {
inPlaceEditorParams.append("'");
}
inPlaceEditorParams.append(inPlaceEditor.getOkControl());
if (!"false".equals(inPlaceEditor.getOkControl())) {
inPlaceEditorParams.append("'");
}
} else {
inPlaceEditorParams.append(", submit: 'OK'");
}
if (UtilValidate.isNotEmpty(inPlaceEditor.getRows())) {
inPlaceEditorParams.append(", rows: '" + inPlaceEditor.getRows() + "'");
}
if (UtilValidate.isNotEmpty(inPlaceEditor.getCols())) {
inPlaceEditorParams.append(", cols: '" + inPlaceEditor.getCols() + "'");
}
inPlaceEditorParams.append("}");
builder.stringParameter("inPlaceEditorParams", inPlaceEditorParams.toString());
}
return builder.build();
}
public RenderableFtl textField(final Map<String, Object> context, final ModelFormField.TextField textField,
final boolean javaScriptEnabled) {
ModelFormField modelFormField = textField.getModelFormField();
String name = modelFormField.getParameterName(context);
String className = "";
String alert = "false";
String mask = "";
String placeholder = textField.getPlaceholder(context);
if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
className = modelFormField.getWidgetStyle();
if (modelFormField.shouldBeRed(context)) {
alert = "true";
}
}
String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
String textSize = Integer.toString(textField.getSize());
String maxlength = "";
if (textField.getMaxlength() != null) {
maxlength = Integer.toString(textField.getMaxlength());
}
String event = modelFormField.getEvent();
String action = modelFormField.getAction(context);
String id = modelFormField.getCurrentContainerId(context);
String clientAutocomplete = "false";
//check for required field style on single forms
if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
String requiredStyle = modelFormField.getRequiredFieldStyle();
if (UtilValidate.isEmpty(requiredStyle)) {
requiredStyle = "required";
}
if (UtilValidate.isEmpty(className)) {
className = requiredStyle;
} else {
className = requiredStyle + " " + className;
}
}
List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
boolean ajaxEnabled = updateAreas != null && javaScriptEnabled;
if (textField.getClientAutocompleteField() || ajaxEnabled) {
clientAutocomplete = "true";
}
if (UtilValidate.isNotEmpty(textField.getMask())) {
mask = textField.getMask();
}
String ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
boolean disabled = modelFormField.getDisabled();
boolean readonly = textField.getReadonly();
String tabindex = modelFormField.getTabindex();
return RenderableFtlMacroCall.builder()
.name("renderTextField")
.stringParameter("name", name)
.stringParameter("className", className)
.stringParameter("alert", alert)
.stringParameter("value", value)
.stringParameter("textSize", textSize)
.stringParameter("maxlength", maxlength)
.stringParameter("id", id)
.stringParameter("event", event != null ? event : "")
.stringParameter("action", action != null ? action : "")
.booleanParameter("disabled", disabled)
.booleanParameter("readonly", readonly)
.stringParameter("clientAutocomplete", clientAutocomplete)
.stringParameter("ajaxUrl", ajaxUrl)
.booleanParameter("ajaxEnabled", ajaxEnabled)
.stringParameter("mask", mask)
.stringParameter("placeholder", placeholder)
.stringParameter("tabindex", tabindex)
.stringParameter("delegatorName", ((HttpSession) context.get("session"))
.getAttribute("delegatorName").toString())
.build();
}
public RenderableFtl makeHyperlinkString(final ModelFormField.SubHyperlink subHyperlink,
final Map<String, Object> context) {
if (subHyperlink == null || !subHyperlink.shouldUse(context)) {
return RenderableFtlNoop.INSTANCE;
}
if (UtilValidate.isNotEmpty(subHyperlink.getWidth())) {
request.setAttribute("width", subHyperlink.getWidth());
}
if (UtilValidate.isNotEmpty(subHyperlink.getHeight())) {
request.setAttribute("height", subHyperlink.getHeight());
}
return makeHyperlinkByType(subHyperlink.getLinkType(), subHyperlink.getStyle(context),
subHyperlink.getUrlMode(), subHyperlink.getTarget(context),
subHyperlink.getParameterMap(context, subHyperlink.getModelFormField().getEntityName(),
subHyperlink.getModelFormField().getServiceName()),
subHyperlink.getDescription(context), subHyperlink.getTargetWindow(context), "",
subHyperlink.getModelFormField(), request, response, context);
}
public RenderableFtl makeHyperlinkByType(String linkType, String linkStyle, String targetType, String target,
Map<String, String> parameterMap, String description, String targetWindow,
String confirmation, ModelFormField modelFormField,
HttpServletRequest request, HttpServletResponse response,
Map<String, Object> context) {
String realLinkType = WidgetWorker.determineAutoLinkType(linkType, target, targetType, request);
String encodedDescription = encode(description, modelFormField, context);
// get the parameterized pagination index and size fields
int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
ModelForm modelForm = modelFormField.getModelForm();
ModelTheme modelTheme = visualTheme.getModelTheme();
String viewIndexField = modelForm.getMultiPaginateIndexField(context);
String viewSizeField = modelForm.getMultiPaginateSizeField(context);
int viewIndex = Paginator.getViewIndex(modelForm, context);
int viewSize = Paginator.getViewSize(modelForm, context);
if (("viewIndex" + "_" + paginatorNumber).equals(viewIndexField)) {
viewIndexField = "VIEW_INDEX" + "_" + paginatorNumber;
}
if (("viewSize" + "_" + paginatorNumber).equals(viewSizeField)) {
viewSizeField = "VIEW_SIZE" + "_" + paginatorNumber;
}
if ("hidden-form".equals(realLinkType)) {
parameterMap.put(viewIndexField, Integer.toString(viewIndex));
parameterMap.put(viewSizeField, Integer.toString(viewSize));
final RenderableFtlStringBuilder renderableFtlStringBuilder = RenderableFtlString.builder();
final StringBuilder htmlStringBuilder = renderableFtlStringBuilder.getStringBuilder();
if ("multi".equals(modelForm.getType())) {
final Element anchorElement = WidgetWorker.makeHiddenFormLinkAnchorElement(linkStyle,
encodedDescription, confirmation, modelFormField, request, context);
htmlStringBuilder.append(anchorElement.outerHtml());
// this is a bit trickier, since we can't do a nested form we'll have to put the link to submit the
// form in place, but put the actual form def elsewhere, ie after the big form is closed
final RenderableFtlString postFormRenderableFtlString = RenderableFtlString.withStringBuilder(sb -> {
final Element hiddenFormElement = WidgetWorker.makeHiddenFormLinkFormElement(target, targetType,
targetWindow, parameterMap, modelFormField, request, response, context);
sb.append(hiddenFormElement.outerHtml());
});
appendToPostFormRenderableFtl(postFormRenderableFtlString, context);
} else {
final Element hiddenFormElement = WidgetWorker.makeHiddenFormLinkFormElement(target, targetType,
targetWindow, parameterMap, modelFormField, request, response, context);
htmlStringBuilder.append(hiddenFormElement.outerHtml());
final Element anchorElement = WidgetWorker.makeHiddenFormLinkAnchorElement(linkStyle,
encodedDescription, confirmation, modelFormField, request, context);
htmlStringBuilder.append(anchorElement.outerHtml());
}
return renderableFtlStringBuilder.build();
} else {
if ("layered-modal".equals(realLinkType)) {
String uniqueItemName = "Modal_".concat(UUID.randomUUID().toString().replace("-", "_"));
String width = (String) request.getAttribute("width");
if (UtilValidate.isEmpty(width)) {
width = String.valueOf(modelTheme.getLinkDefaultLayeredModalWidth());
request.setAttribute("width", width);
}
String height = (String) request.getAttribute("height");
if (UtilValidate.isEmpty(height)) {
height = String.valueOf(modelTheme.getLinkDefaultLayeredModalHeight());
request.setAttribute("height", height);
}
request.setAttribute("uniqueItemName", uniqueItemName);
RenderableFtl renderableFtl = hyperlinkMacroCall(linkStyle, targetType, target, parameterMap,
encodedDescription, confirmation, modelFormField, request, response, context, targetWindow);
request.removeAttribute("uniqueItemName");
request.removeAttribute("height");
request.removeAttribute("width");
return renderableFtl;
} else {
return hyperlinkMacroCall(linkStyle, targetType, target, parameterMap, encodedDescription, confirmation,
modelFormField, request, response, context, targetWindow);
}
}
}
public RenderableFtl hyperlinkMacroCall(String linkStyle, String targetType, String target,
Map<String, String> parameterMap, String description, String confirmation,
ModelFormField modelFormField,
HttpServletRequest request, HttpServletResponse response,
Map<String, Object> context, String targetWindow) {
if (description != null || UtilValidate.isNotEmpty(request.getAttribute("image"))) {
StringBuilder linkUrl = new StringBuilder();
final URI linkUri = WidgetWorker.buildHyperlinkUri(target, targetType,
UtilValidate.isEmpty(request.getAttribute("uniqueItemName")) ? parameterMap : null,
null, false, false, true, request, response);
linkUrl.append(linkUri.toString());
String event = "";
String action = "";
String imgSrc = "";
String alt = "";
String id = "";
String uniqueItemName = "";
String width = "";
String height = "";
String imgTitle = "";
String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
if (UtilValidate.isNotEmpty(modelFormField.getEvent())
&& UtilValidate.isNotEmpty(modelFormField.getAction(context))) {
event = modelFormField.getEvent();
action = modelFormField.getAction(context);
}
if (UtilValidate.isNotEmpty(request.getAttribute("image"))) {
imgSrc = request.getAttribute("image").toString();
}
if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) {
alt = request.getAttribute("alternate").toString();
}
if (UtilValidate.isNotEmpty(request.getAttribute("imageTitle"))) {
imgTitle = request.getAttribute("imageTitle").toString();
}
Integer size = Integer.valueOf("0");
if (UtilValidate.isNotEmpty(request.getAttribute("descriptionSize"))) {
size = Integer.valueOf(request.getAttribute("descriptionSize").toString());
}
if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) {
imgTitle = description;
description = description.substring(0, size - 8) + "..."
+ description.substring(description.length() - 5);
}
if (UtilValidate.isEmpty(imgTitle)) {
imgTitle = modelFormField.getTitle(context);
}
if (UtilValidate.isNotEmpty(request.getAttribute("id"))) {
id = request.getAttribute("id").toString();
}
if (UtilValidate.isNotEmpty(request.getAttribute("uniqueItemName"))) {
uniqueItemName = request.getAttribute("uniqueItemName").toString();
width = request.getAttribute("width").toString();
height = request.getAttribute("height").toString();
}
return RenderableFtlMacroCall.builder()
.name("makeHyperlinkString")
.stringParameter("linkStyle", linkStyle == null ? "" : linkStyle)
.stringParameter("hiddenFormName", hiddenFormName)
.stringParameter("event", event)
.stringParameter("action", action)
.stringParameter("imgSrc", imgSrc)
.stringParameter("title", imgTitle)
.stringParameter("alternate", alt)
.mapParameter("targetParameters", parameterMap)
.stringParameter("linkUrl", linkUrl.toString())
.stringParameter("targetWindow", targetWindow)
.stringParameter("description", description)
.stringParameter("confirmation", confirmation)
.stringParameter("uniqueItemName", uniqueItemName)
.stringParameter("height", height)
.stringParameter("width", width)
.stringParameter("id", id)
.build();
} else {
return RenderableFtlNoop.INSTANCE;
}
}
public RenderableFtlMacroCall containerMacroCall(final Map<String, Object> context,
final ContainerField containerField) {
final String id = containerField.getModelFormField().getCurrentContainerId(context);
String className = UtilFormatOut.checkNull(containerField.getModelFormField().getWidgetStyle());
return RenderableFtlMacroCall.builder()
.name("renderContainerField")
.stringParameter("id", id)
.stringParameter("className", className)
.build();
}
private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
if (UtilValidate.isEmpty(value)) {
return value;
}
UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
if (modelFormField.getEncodeOutput() && encoder != null) {
value = encoder.encode(value);
} else {
value = internalEncoder.encode(value);
}
return value;
}
/**
* 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
* @param context
* @return Parameter string or empty string if no UpdateArea objects were found
*/
private String createAjaxParamsFromUpdateAreas(final List<ModelForm.UpdateArea> updateAreas,
final String extraParams,
final Map<String, Object> context) {
//FIXME copy from HtmlFormRenderer.java
if (updateAreas == null) {
return "";
}
String ajaxUrl = "";
boolean firstLoop = true;
for (ModelForm.UpdateArea updateArea : updateAreas) {
if (firstLoop) {
firstLoop = false;
} else {
ajaxUrl += ",";
}
Map<String, Object> ctx = UtilGenerics.cast(context);
Map<String, String> parameters = updateArea.getParameterMap(ctx);
String targetUrl = updateArea.getAreaTarget(context);
String ajaxParams;
StringBuffer ajaxParamsBuffer = new StringBuffer();
ajaxParamsBuffer.append(getAjaxParamsFromTarget(targetUrl));
//add first parameters from updateArea parameters
if (UtilValidate.isNotEmpty(parameters)) {
for (Map.Entry<String, String> entry : parameters.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
//test if ajax parameters are not already into extraParams, if so do not add it
if (UtilValidate.isNotEmpty(extraParams) && extraParams.contains(value)) {
continue;
}
if (ajaxParamsBuffer.length() > 0 && ajaxParamsBuffer.indexOf(key) < 0) {
ajaxParamsBuffer.append("&");
}
if (ajaxParamsBuffer.indexOf(key) < 0) {
ajaxParamsBuffer.append(key).append("=").append(value);
}
}
}
//then add parameters from request. Those parameters could end with an anchor so we must set ajax parameters first
if (UtilValidate.isNotEmpty(extraParams)) {
if (ajaxParamsBuffer.length() > 0 && !extraParams.startsWith("&")) {
ajaxParamsBuffer.append("&");
}
ajaxParamsBuffer.append(extraParams);
}
ajaxParams = ajaxParamsBuffer.toString();
ajaxUrl += updateArea.getAreaId() + ",";
ajaxUrl += requestHandler.makeLink(request, response, UtilHttp.removeQueryStringFromTarget(targetUrl));
ajaxUrl += "," + ajaxParams;
}
Locale locale = UtilMisc.ensureLocale(context.get("locale"));
return FlexibleStringExpander.expandString(ajaxUrl, context, locale);
}
private void appendToPostFormRenderableFtl(final RenderableFtl renderableFtl, final Map<String, Object> context) {
// If there is already a Post Form RenderableFtl, wrap it in a sequence with the given RenderableFtl
// appended. This ensures we don't overwrite any other elements to be rendered after the main form.
final RenderableFtl current = getPostMultiFormRenderableFtl(context);
if (current == null) {
setPostMultiFormRenderableFtl(renderableFtl, context);
} else {
final RenderableFtlSequence wrapper = RenderableFtlSequence.builder()
.renderableFtl(current)
.renderableFtl(renderableFtl)
.build();
setPostMultiFormRenderableFtl(wrapper, context);
}
final Map<String, Object> wholeFormContext = UtilGenerics.cast(context.get("wholeFormContext"));
}
private RenderableFtl getPostMultiFormRenderableFtl(final Map<String, Object> context) {
final Map<String, Object> wholeFormContext = getWholeFormContext(context);
return (RenderableFtl) wholeFormContext.get("postMultiFormRenderableFtl");
}
private void setPostMultiFormRenderableFtl(final RenderableFtl postMultiFormRenderableFtl,
final Map<String, Object> context) {
final Map<String, Object> wholeFormContext = getWholeFormContext(context);
wholeFormContext.put("postMultiFormRenderableFtl", postMultiFormRenderableFtl);
}
private Map<String, Object> getWholeFormContext(final Map<String, Object> context) {
final Map<String, Object> wholeFormContext = UtilGenerics.cast(context.get("wholeFormContext"));
if (wholeFormContext == null) {
throw new RuntimeException("Cannot access whole form context");
}
return wholeFormContext;
}
/**
* Extracts parameters from a target URL string, prepares them for an Ajax
* JavaScript call. This method is currently set to return a parameter string
* suitable for the Prototype.js library.
*
* @param target Target URL string
* @return Parameter string
*/
private static String getAjaxParamsFromTarget(String target) {
String targetParams = UtilHttp.getQueryStringFromTarget(target);
targetParams = targetParams.replace("?", "");
targetParams = targetParams.replace("&amp;", "&");
return targetParams;
}
}