Convert from Name of Bean and Name of Property to the property in JSP - spring-mvc

I have a been called “FooOneBean” and that has a number of properties, one of which is “fooOnePropA’ which is a list of Foo objects.
In a Java Controller, this bean is set in the request as follows:
request.setAttibute(“FooOneBean”, FooOneBean.instance());
Normally, this can be used in a JSP to display the dropdown as follows:
<tiles:importAttribute name="elementName" />
<c:set var=”dropdown” value=”${FooOneBean.fooOnePropA}” /> <!—Name of the bean and property hard-coded here -- >
<form:select path="${elementName}" id="${elementName}">
<form:options items="${dropdown}" itemLabel="displayName" itemValue="code" />
</form:select>
However, what we have is a very generic JSP that should be able to display the dropdown based on the String name of the bean and property set in the JSP. The name of the bean or property can change based on how the JSP is invoked. So,
<tiles:importAttribute name="elementName" />
<tiles:importAttribute name="resourceBean" />
<tiles:importAttribute name="resourceList" />
<%--
<c:out value="${resourceBean}" /> <!—Displays “FooOneBean” -->
<c:out value="${resourceList}" /> <!—Displays “fooOnePropA” -->
--%>
<c:set var="beanName" value="${resourceBean}" />
<c:set var="propName" value="${resourceList}" />
<c:set var="dropdown" value="${beanName.propName }" />
<form:select path="${elementName}" id="${elementName}">
<form:options items="${dropdown}" itemLabel="displayName" itemValue="code" />
</form:select>
This will fail with the message: '${beanName.propName}' Property 'propName' not found on type java.lang.String
On the otherhand if dropdown is set as:
<c:set var="dropdown" value="${beanName}.${propName}" />
It fails with the error: Type [java.lang.String] is not valid for option items
How can this be accomplished in JSP? I am able to do this using Scriptlets that I want to avoid.

Thanks for the comments from JB Nizet. This can be done as:
<tiles:importAttribute name="elementName" />
<tiles:importAttribute name="resourceBean" />
<tiles:importAttribute name="resourceList" />
<c:set var="dropdown" value="${requestScope[resourceBean][resourceList]}”/>
<form:select path="${elementName}" id="${elementName}">
<form:options items="${dropdown}" itemLabel="displayName" itemValue="code" />
</form:select>

Related

Sending an item from a drop-down list in url parameter Spring MVC

Good evening,
I need to recover the element selected in a drop-down list and put it in a parameter to recover it at the level of the controller
I got the selected item with javascript and put it in an input to get it as a parameter but it doesn't work
<script type="text/javascript">
function GetSelectedText() {
var e = document.getElementById("listRoles");
var result = e.options[e.selectedIndex].text;
document.getElementById("r1").innerHTML = result;
}
</script>
<body>
<form:select path="roles" multiple="false" onChange="GetSelectedText();">
<option value="${author.role}" selected>${author.role}</option>
<c:forEach items="${roles}" var="r">
<c:if test="${r!=author.role}">
<option value="${r}">${r}</option>
</c:if>
</c:forEach>
</form:select>
<input type="text" id="r1" name="role" />
<c:url value="/modifierRole" var="url">
<c:param name="id" value="${author.id}" />
<c:param name="role" value="${param.role}" />
</c:url>
modify
</body>

Why Do I get Entity & in url formed with spring:url

I am working with Spring MVC and I need to create a url with two parameters:
<spring:url value="/test" var="myUrl" >
<spring:param name="param1" value="1" />
<spring:param name="param2" value="2" />
</spring:url>
I get this: myUrl = /test?param1=1&amp ;param2=2 (note that this url have a entity &amp ; inside)
and when I put this url in a href=${myUrl} this don't work like I want.
Though, If I use c:url and c:param I get that I want :
<c:url value="/test" var="myUrl">
<c:param name="param1" value="1" />
<c:param name="param2" value="2" />
</c:url>
myUrl = /test?param1=1&param2=2
What is the problem with "spring:param" ? Do I need to configure some parameter in my Spring mvc configuration?
Thanks.

Button action called upon second click

I have 2 command buttons and one select one menu. I need to call a bean method depending on the buttons selected and the currently selected item in the menu.
<h:form id="form1">
<h:outputLabel value="menu:" />
<h:commandButton value ="en" action="#{bean.exec}" >
<f:setPropertyActionListener target="#{bean.menu}" value='en' />
</h:commandButton>
<h:commandButton value ="fr" action="#{bean.exec}" >
<f:setPropertyActionListener target="#{bean.menu}" value='fr' />
</h:commandButton>
<h:outputLabel value="id:" />
<h:selectOneMenu value="#{bean.id}">
<f:selectItems value="#{bean.idlist}" />
<f:ajax listener="#{bean.exec}" render ="form1" />
</h:selectOneMenu>
</h:form>
However, although the first button updates my properties and calls the action method, the second button gives me the following message
WARNING: FacesMessage(s) have been enqueued, but may not have been displayed
and the view doesn't get updated on the fist click. However, immediately on the second click, the properties get updated and so does the view.
How is this caused and how can I solve it?
I did see the log, however I dont understand the error: this is what it shows: form1:j_idt124: Validation Error: Value is not valid What value and where?
It's easier to identify the value if you give all input components an ID and attach a <h:message> to them as follows:
<h:outputLabel for="id" value="id:" />
<h:selectOneMenu id="id" value="#{bean.id}">
<f:selectItems value="#{bean.idlist}" />
<f:ajax listener="#{bean.exec}" render ="form1" />
</h:selectOneMenu>
<h:message for="id" />
This way you will get form1:id as label instead of form1:j_idt124. Alternatively, you can also specify the label of the input component:
<h:selectOneMenu label="id" ... />
As to the "Value is not valid" error, you will get this error when the selected value does not match any one of the available values during processing the form submit. This can in turn happen when the property behind #{bean.idlist} has incompatibly changed during processing the form submit. This can in turn happen when the bean is request scoped. Putting the bean in the view scope should fix it.
See also:
Validation Error: Value is not valid

Is it possible to remove the "Upload MM Component" button from the SDL Tridion 2011 Ribbon

This button causes a lot of problems for my client, as it always uses a predefined Schema. I can't find a way to remove this button with my Editor config. I have done this with other buttons, but these buttons are implemented in some sort of sub-group.
On my personal sandbox machine, I tried removing the commented out control in the extract of the ../WebUI/Editors/CME/Controls/Toolbars/Tabs/CreateRibbonPage.ascx file shown below:
<c:RibbonSplitButton runat="server" CommandName="NewComponent"
Title="<%$ Resources: Tridion.Web.UI.Strings, NewComponent %>"
Label="<%$ Resources: Tridion.Web.UI.Strings, NewComponent %>"
ID="NewComponentBtn1">
<c:RibbonContextMenuItem runat="server" ID="NewComponentCMI2"
Command="NewComponent"
Title="<%$ Resources: Tridion.Web.UI.Strings, NewComponent %>"
Label="<%$ Resources: Tridion.Web.UI.Strings, NewComponent %>" />
<c:RibbonContextMenuItem runat="server" ID="NewMultimediaComponentCMI2"
Command="NewMultimediaComponent"
Title="<%$ Resources: Tridion.Web.UI.Strings, NewMultimediaComponent %>"
Label="<%$ Resources: Tridion.Web.UI.Strings, NewMultimediaComponent %>" />
<!--
<c:RibbonUploadContextMenuItem runat="server"
ID="NewBasicMultimediaComponentCMI2" Command="NewBasicMultimediaComponent"
Title="<%$ Resources: Tridion.Web.UI.Strings, NewBasicMultimediaComponent %>"
Label="<%$ Resources: Tridion.Web.UI.Strings, NewBasicMultimediaComponent %>" />
-->
</c:RibbonSplitButton>
This seems to have the desired result, but I imagine that this will probably invalidate our support agreement if I did this in a customer environment. Is this possible to do in a supported way, or do I have to hack the UI files like this to achieve my goal?
One of the solutions is to create extension for the NewBasicMultimediaComponent command, which extends isAvailable and isEnabled methods and returns false for them. In this case "Upload MM Component" still will be present as an option for "New Component" button, but it will be disabled.
I've used css to hide the display of ribbon items before. Purely because I couldn't find the appropriate solution.
I'm adding this answer because I needed to do something similar with a complete ribbon toolbar.
I needed to remove the complete ribbon toolbar "Create" in order to add a simpler version of it and it seems you can do the removal part by creating a new extension and use this in your extensions config:
<?xml version="1.0"?>
<Configuration xmlns="http://www.sdltridion.com/2009/GUI/Configuration/Merge" xmlns:cfg="http://www.sdltridion.com/2009/GUI/Configuration" xmlns:ext="http://www.sdltridion.com/2009/GUI/extensions" xmlns:cmenu="http://www.sdltridion.com/2009/GUI/extensions/ContextMenu" xmlns:edt="http://www.sdltridion.com/2009/GUI/Configuration/Merge">
<resources>
<cfg:groups />
</resources>
<definitionfiles />
<extensions>
<ext:editorextensions>
<ext:editorextension target="CME">
<ext:editurls />
<ext:listdefinitions />
<ext:itemicons />
<ext:taskbars />
<ext:commands />
<ext:commandextensions />
<ext:contextmenus />
<ext:lists />
<ext:tabpages>
</ext:tabpages>
<ext:toolbars>
</ext:toolbars>
<ext:ribbontoolbars>
<ext:remove>
<ext:extension id="CreatePage">
<ext:apply>
<ext:view name="DashboardView">
<ext:control id="DashboardToolbar" />
</ext:view>
</ext:apply>
</ext:extension>
</ext:remove>
</ext:ribbontoolbars>
<ext:extendedareas />
</ext:editorextension>
</ext:editorextensions>
<ext:dataextenders />
</extensions>
<commands />
<contextmenus />
<localization />
<settings>
<dependencies />
<defaultpage />
<editurls />
<listdefinitions />
<theme>
<path>/Themes/</path>
</theme>
<customconfiguration />
</settings>
</Configuration>
To make this work for buttons you probably can do the same thing (haven't tested this), by providing the button id in the ext:extension id attribute.

Display sub-property in table tag (Spring Roo supplied tag library)

I am using Spring Roo. There is table:table and table:column tags.
How to display sub-property of colections elements in table?
In straightforward way it doesnt work:
<table:table data="${knowledgebase.concepts}" id="l_domain_Concept" path="/concepts" z="user-managed">
<table:column id="c_domain_Concept_translations" property="defaultTranslation.name" z="user-managed" />
</table:table>
Exception:
Caused by: javax.el.PropertyNotFoundException: Property 'defaultTranslation.name' not found on type domain.data.Concept
I modified table.tagx so it could be used with sub-properties and Spring converting capabilities.
<c:forTokens items="${columnProperties}" delims="," var="column" varStatus="num">
<c:set var="prop" value="${ item }" />
<c:forTokens items="${column}" delims="." var="subprop">
<c:set var="prop" value="${ prop[subprop]}" />
</c:forTokens>
<c:set var="columnMaxLength" value="${lengths[num.count - 1]}" scope="request"/>
<td>
<c:choose>
<c:when test="${not convert}">
<c:out value="${columnMaxLength lt 0 ? prop : fn:substring(prop, 0, columnMaxLength)}" />
</c:when>
<c:otherwise>
<spring:eval expression="prop" />
</c:otherwise>
</c:choose>
</td>
Edit PROJECT/src/main/webapp/WEB-INF/tags/form/fields/table.tagx. At line 78, you should see <c:set var="columnDatePattern" value="${patterns[num.count-1]}" />. Put under that line, the following piece of code:
<!-- Get the last descendant property -->
<c:set var="prop" value="${item}" />
<c:forTokens items="${column}" delims="." var="subprop">
<c:if test="${not empty prop}">
<c:set var="prop" value="${prop[subprop]}" />
</c:if>
</c:forTokens>
<!-- Now under tag c:choose below, please change from "item[column]" into "prop" -->
<!-- // End of Get the last descendant property. -->
Don't forget to change from "item[column]" into "prop". For example, the changed lines should be:
<c:choose>
<c:when test="${columnType eq 'date'}">
<spring:escapeBody>
<fmt:formatDate value="${prop}" pattern="${fn:escapeXml(columnDatePattern)}" var="colTxt" />
</spring:escapeBody>
</c:when>
<c:when test="${columnType eq 'calendar'}">
<spring:escapeBody>
<fmt:formatDate value="${prop.time}" pattern="${fn:escapeXml(columnDatePattern)}" var="colTxt"/>
</spring:escapeBody>
</c:when>
<c:otherwise>
<c:set var="colTxt">
<spring:eval expression="prop" htmlEscape="false" />
</c:set>
</c:otherwise>
</c:choose>
You can edit entity file Concepts.java :
#Transient
public String getDefaultTranslationName(){
return defaultTranslation.getName();
}
After , you edit to:
<table:column id="c_domain_Concept_translations" property="DefaultTranslationName" z="user-managed" />
Hope can help you !

Resources