I'm working on a JSP tag. Here is the old line that starts looping through items in a model:
<c:forEach var="toc" items="${requestScope[formKey].model.sharingTocs}">
But the code has been refactored so the model path (model.sharingTocs above) is now dynamic rather than fixed. It is now passed into the tag via a JSP #attribute:
<%#attribute name="path" required="true"%>
So ${path} now evaluates to "model.sharingTocs".
How can items now be assigned?
Well. Good question.
This is a solution: writing a custom jstl tag to Evaluate a property expression of a bean:
<mytag:eval bean="${requestScope['formKey']}" propertyExpression = "${path}" var="items" />
And ForEach:
<c:forEach var="toc" items="${items}">
</c:forEach>
Sample code of mytag:eval JSTL tag ( Classic model )
public class EvalTag extends TagSupport
{
private Object bean;
private String propertyExpression; //Ex: 'model.sharingTocs'
private String var;
//............
#Override
public int doEndTag() throws JspException {
try {
// Use reflection to eval propertyExpression ('model.sharingTocs') on the given bean
Object propObject = SomeLibs.eval ( this.bean, this.propertyExpression);
this.pageContext.getRequest().setAttribute(this.var, propObject);
// You can add propObject into Other scopes too.
} catch (Exception ex) {
throw new JspTagException(ex.getMessage(), ex);
}
return EVAL_PAGE;
}
//............
// SETTERS here
}
A lib you can use to eval propertyExpression of a bean is Apache bean utils.
http://commons.apache.org/proper/commons-beanutils/apidocs/org/apache/commons/beanutils/package-summary.html#standard.nested
If you are using spring you can utilise the spring tag library, it also assumes you are inside a form:form tag.
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# attribute name="path" required="false" %>
<spring:bind path="${path}">
<c:forEach var="item" items="${status.value}">
${item}
</c:forEach>
</spring:bind>
It's been quite a while since I asked this question but (with new knowledge gained since) I think this ought to work:
<c:set var="itemsPath" value="requestScope[formKey].${path}"/>
<c:forEach var="toc" items="${itemsPath}">
i.e. set up an intermediary JSTL variable with the full path to the items and evaluate that one instead.
Related
I tried to extend a JSF application by including xhtml files from a directory which is not in the context root:
Point of inclusion:
<form>
<ui:repeat value="#{calcBean.resolveIncludes()}" var="curInc">
<ui:include src="#{curInc}" />
</ui:repeat>
</h:form>
CalcBean delivers:
public List<String> resolveIncludes()
{
final List<String> ret = new ArrayList<>();
ret.add("D:/extensionDir/inc1.xhtml");
ret.add("D:/extensionDir/inc2.xhtml");
return ret;
}
The content of the xhtml files is not included because the path must be relative the origin xhtml according documentation. Is there a way to achieve this? The aim is to extend a JSF application by adding a set of files to a defined extension directory without redeploy.
Ok it works. But unfortunately the path is validated before the ResourceHandler is invoked. To identify the resource as "external dynamic" I had to prefix it for instance with "extension_". In the origin example:
public List<String> resolveIncludes()
{
final List<String> ret = new ArrayList<>();
ret.add("/extension_inc1.xhtml");
ret.add("/extension_inc2.xhtml");
return ret;
}
And I had to use c:forEach instead of ui:repeat:
<c:forEach items="#{calcBean.resolveIncludes()}" var="curInc">
<ui:include src="#{curInc}" />
</c:forEach>
So I have a page with layout:
<form:form id='form1'>
<form:hidden path="order" />
<form:form id='form2'>
<form:hidden path="order" />
Constructor:
public ModelAndView showListView(Model model,
#ModelAttribute("form1") FormSearch form1,
#ModelAttribute("form2") FormSearch form2){
When I press button on form1 to receive 'order' value, I see that browser sends values correctly form1:order is newValue and form2:order is oldValue. But in constructor I receive form1:order newValue and form2:order newValue. So I think Spring is searching for first param value for both forms, which is incorrect.
What should I do to fix that?
Answer from different thread fixed the issue:
#InitBinder("form2")
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("*");
}
Have you tried:
<form:form id='form1' modelAttribute="form1">
<form:form id='form2' modelAttribute="form2">
Below code for bytes to kb conversion code its for Static return type.So how can i get a value in many jsp without creation bean.
public static double bytesToKB(int bytes){
return (double)bytes/1024;
}
how about this?
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<spring:eval expression="T(com.abc.xyz.YourClassName).bytesToKB(2560)" var="result"></spring:eval>
Spring Eval result: <c:out value="${result }"/>
I'am new to Spring MVC, following the "Spring in Action" book, creating my own project from scratch. I get the following exception when trying to reach 'reward.jsp':
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'reward' available as request attribute
Contents of my classes:
reward.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
<html>
<head>
<title>Rewards</title>
</head>
<body>
<h1>Rewards module</h1>
<h2>Add reward</h2>
<sf:form action="add" method="post" modelAttribute="reward">
Reward name:<sf:input path="name" />
Point value:<sf:input path="pointValue" />
<input type="submit" value="Add">
</sf:form>
<br />
<h2>Reward list</h2>
<table>
<c:forEach var="reward" items="${rewardList}">
<tr>
<td>${reward.name}</td>
<td>${reward.pointValue}</td>
<td>delete</td>
</tr>
</c:forEach>
</table>
It works just fine when I delete form inputs.
RewardController.java
#Controller
public class RewardController {
#Autowired
private RewardService rewardService;
#RequestMapping("/reward")
public String listRewards(Map<String, Object> model) {
model.put("rewardList", rewardService.listReward());
return "reward";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addReward(#ModelAttribute("reward") Reward reward,
BindingResult result) {
rewardService.addReward(reward);
return "redirect:/reward";
}
#RequestMapping("/delete/{rewardId}")
public String deleteContact(#PathVariable("rewardId") long rewardId) {
rewardService.removeReward(rewardId);
return "redirect:/reward";
}
}
Change your listRewards method, so that it add the form backing object to the model map model.put("reward", new Reward()).
#RequestMapping("/reward")
public String listRewards(Map<String, Object> model) {
model.put("rewardList", rewardService.listReward());
model.put("reward", new Reward())
return "reward";
}
I'm new on seam and richfaces. I want to hide/show a4joutputpanel by rendered="" "true/false" parameter by giving Managed Bean.But ı'm taking this exception:
com.sun.facelets.tag.TagAttributeException: /testscreen.xhtml
action="#{testBean.renderActive(true)}" Not a Valid Method Expression: #{testBean.renderActive(true)}
Can anyone help me about that?
Here's my xhtml and managedbean codes:
<a4j:commandButton action="#{testBean.renderActive(true)}" reRender="MyPanel" value="Start" />
<a4j:outputPanel id="MyPanel">
<s:div rendered="#{testBean.renderProperty}">
........
</s:div>
</a4j:outputPanel>
ManagedBean
public void renderActive(Boolean rendeBoolean){
this.renderProperty=rendeBoolean; }
private Boolean renderProperty;
public Boolean getRenderProperty() {
return renderProperty;
}
public void setRenderProperty(Boolean renderProperty) {
this.renderProperty = renderProperty;
}
#{testBean.renderActive(true)} is actually not a valid method expression in plain JSF EL because method expressions cannot have parameters.
It's valid with EL extension provided by jboss-el.jar, though.
Check if this jar is present in the application classpath, that is in the EAR or in WEB-INF/lib if you don't package the application as war. (see § 30.3.1 Packaging in the reference documentation).