How to use jstl el to call a dynamic nested property - java

if you wanna call the getter method from a specific bean using a dynamic key you use like that:
${bean[getterName]}
but if you wanna call double nested, or triple nested properties with a dynamic name how does it works, is it possible?
${bean.propertyA.propertyB} WORKS
${bean[propertyA.propertyB]} DOES NOT WORKS
<c:set var="dynamicKey" value="propertyA.propertyB" />
${bean[dynamicKey]} DOES NOT WORKS
UPDATE:
For now we're handling like that:
<c:forTokens items="${property}" delims="." var="item">
<c:set var="value" value="${value[item]}" />
</c:forTokens>

Dot notation vs brackets notation with nested properties:
${bean.propertyA.propertyB}
${bean[propertyA.propertyB]} ==> Not right, instead
${bean["propertyA"]["propertyB"]}
Your example with JSTL:
<c:set var="dynamicKey" value="${bean['propertyA']['propertyB']}" />
<c:out value="${dynamicKey}" />

After 2 years we are leaving like this since it does not seems to have a big impact on performance.
<c:forTokens items="${property}" delims="." var="item">
<c:set var="value" value="${value[item]}" />
</c:forTokens>

Related

Is there a way to populate a map in JSP?

For example
<jsp:useBean id="total" class="java.util.LinkedHashMap"/>
// need somehow do something like this: total.put('key', 'value');
But without using scriptlets (it's obvious but a little bit ugly)
You can use JSTL <c:set> for this.
<jsp:useBean id="total" class="java.util.LinkedHashMap"/>
<c:set target="${total}" property="key" value="value" />

JSF Map binding in Repeater

Here is what I am trying to do:
<ui:repeat value="#{foo}" var="keyprefix">
<p:inputText value="#{someBean.someMap[keyprefix + 'somesuffix']}" />
</ui:repeat>
I have tried using fn:join which doesn't work. I tried using .concat() but I am not on 2.2, I'm still using 2.1. Is there a simple way to do this I'm missing?
You can use <c:set> to prepare the dynamic map key by just inlining the EL expression in the string literal the usual way.
<c:set var="key" value="#{keyprefix}somesuffix" />
<p:inputText value="#{someBean.someMap[key]}" />

How can I loop through each character in a String using JSTL?

How can I loop through each character in a String using JSTL?
Tricky use of fn:substring() would do
<c:forEach var="i" begin="0" end="${fn:length(str)}" step="1">
<c:out value="${fn:substring(str, i, i + 1)}" />
</c:forEach>
Late to the party, but EL 2.2 allows for instance method calls (more on that here: https://stackoverflow.com/a/7122669/2047962). This means that you could shorten Jigar Joshi's answer by a few characters:
<c:forEach var="i" begin="0" end="${fn:length(str)}" step="1">
<c:out value="${str.charAt(i)}" />
</c:forEach>
I only suggest this because it is a little more obvious what your code is doing.
i think you can't do that with JSTL's forEach. You need to write your own tag or an EL function. Here is a sample code how you write your custom tags:
http://www.java2s.com/Tutorial/Java/0360__JSP/CustomTagSupport.htm

conditional check in c:if always fails

The c:if test always fails for me and it never gets inside the loop. I am using the following namespaces
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:c="http://java.sun.com/jstl/core"
The string ('array') to be split is "Tom and Jerry are GAP1 friends"
<s:decorate template="/layout/display-text.xhtml">
<c:set var="array" value="#{_mybean.value}"/>
<c:set var="space" value="#{fn:split(array, ' ')}"/>
<c:set var="len" value="#{fn:length(space)}"/>
<h:outputText value="total length = #{len}"/><br/>
<c:forEach begin="0" end="5" var="index">
<h:outputText value="index = #{index}, value = #{space[index]}"/><br/>
<c:set var="val" value="#{space[index]}"/>
<c:if test="#{fn:startsWith(val, 'GAP')}">
<h:outputText value="Found keyword parameter GAP" /><br/>
</c:if>
</c:forEach>
</s:decorate>
The JSTL core URI is invalid. As per the JSTL TLD it should be (note the extra /jsp):
xmlns:c="http://java.sun.com/jsp/jstl/core"
That said, mixing JSF with JSTL is never been a good idea. It won't always give results as you'd expect because they doesn't run in sync as you would expect from the coding. It's more that JSP/JSTL runs from top to bottom first and then hands over the produced result to JSF to process further from top to bottom again. That would cause some specific constructs to fail. Better use pure JSF components/attributes instead.
Instead of c:forEach, rather use Seam's a4j:repeat or Facelets' ui:repeat and instead of c:if make use of the rendered attribute of the JSF component which has to be toggled to show/hide. Instead of all that JSTL c:set, write appropriate code logic in managed bean constructor or action method or getter.
The JSTL functions (fn) taglib is however still highly valuable in JSF. You can keep using it.

array as hidden variable

can array be used as hidden variable on jsp.....like I have a form i.e a simple java
class,I want it to be as hidden variable can I do it..
Thanks in advance
HTTP request parameters can only be strings. So you either have to convert it to a single string (maybe a commaseparated string?), but you need to convert it back yourself, or you have to use multiple hidden input values (all with the same name), which is generally a much better solution. In plain JSP/Servlet you can get them back using HttpServletRequest#getParameterValues() and Struts is smart enough to see that.
<logic:iterate id="foo" name="bean" property="arrayOrList">
<html:hidden name="paramName" property="propertyName" indexed="true" />
</logic:iterate>
just write multiple hidden elements with the same name en different values. struts will see that it is supposed to be an array
agree with BalusC in addition to that
you can try following
adding [] at the end of the name , keeping name and property same and adding multiple values.
for example
<html:hidden name="name1[]" property="status" value="value1" />
<html:hidden name="name1[]" property="status" value="value2" />
<html:hidden name="name1[]" property="status" value="value3" />

Categories