I want to display name (current user) in a drop down list in JSF. Here name is a dynamic variable that gets populated though some pojo class. The present code that I have is
<f:selectItem itemLabel="#{accessManager.salesManager.displayName} #{' ('.concat(i.m['current user']).concat(') ')}" itemValue="#{accessManager.salesManager.oid}" />
accessManager.salesManager.displayName populates the name on the UI.
#{' ('.concat(i.m['current user']).concat(') ')}" here I am trying to hard code (current user).
But this is throwing exceptions.
Can any one help me in this? It sounds to be a very simple query but I am not used to EL.
Based on your example, the easiest way is to provide an extra function in your managed bean which evaluates if the current user is the current choice or not. Later on, you evaluate that function with a ternary operator, which will decide wether to display the bundled (translated) value or not.
#ViewScoped
public class ChoiceBean{
public List<SalesManager> getSalesManagers(){
return salesManagers;
}
//Checks if your current choice is the current manager(EL 2.2 required to pass the parameter)
public boolean checkIfCurrent(SalesManager manager){
if (manager.getName().equals("Bob")) return true;
return false;
}
}
<f:selectItem
itemLabel="#{manager.name} #{choiceBean.checkIfCurrent(manager) ? i.m['current user'] : ''}" itemValue="#{salesManager.oid}" />
See also:
Passing parameter to JSF action
Ternary operator in JSTL/EL
Another solution is to use a function doing this String concatenation for you. Either
you use the JSTL functions library with fn:join (see enter link description here) or
implement your own static method in EL, and use that one. The method itself would (surprisingly) look like
public static String concat(String string1, String string2) {
return string1.concat(string2);
}
and the call in JSF, nested like #{fn:concat('(',fn:concat(i.m['current user'],')'))}.
But, out of curiosity, why don't you want to add the brackets into the properties file, so the ressource-value holds (current user) instead of current user?
Hope it helps...
So the question is how do I concat '(' & ')' before and after #{i.m['current user'])}
Don't do it the hard way. Just put those parentheses outside the EL expression.
<f:selectItem itemLabel="#{accessManager.salesManager.displayName} (#{i.m['current user']})" itemValue="#{accessManager.salesManager.oid}" />
Related
The division of two integers is resulting in a floating point value.
Is there a way to get the result as an integer in the following situation?
<p:commandButton value="#{bean.intA / bean.intB}" ../>
The result should be shown as "1" not as "1.0".
EL doesn't support upcasting/formatting. An universal solution would be to create a custom EL function referring the below utility method:
public static String formatNumber(Number number, String pattern) {
if (number == null) {
return null;
}
DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(getLocale());
formatter.applyPattern(pattern);
return formatter.format(number);
}
You can then use it as below:
<p:commandButton value="#{util:formatNumber(bean.intA / bean.intB, '#')}" ... />
In case you happen to use JSF utility library OmniFaces, it's available as #{of:formatNumber()} whose source code is actually copied above.
First I want to tell :
I saw How to use JSF's h:selectBooleanCheckbox with h:dataTable to create one object per row?
and my problem is like same but not solved problem.
Following is my code :
*.xhtml
<rich:column>
<h:selectBooleanCheckbox id="resolveTxn" value="#{verifyTransactionBean.checked[verifyTxnList.id]}"/>
</rich:column>
.
.//Some code here
.
<h:commandButton value="Resolve" action="#{verifyTransactionBean.resolveToTxn}" styleClass="btn" />
and following is my code
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
public void resolveToTxn() {
List<ToVerifyTxnDTO> list = new ArrayList<ToVerifyTxnDTO>();
for (ToVerifyTxnDTO dTO : toVerifyTxnDTOList) {
if(checked.get(dTO.getId())){//I got null pointer exception here
Long id=dTO.getId();
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
}
}
}
What I want to do ?
I want to pass checked row id as parameter on following :
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
And after clicking the button Resolve some operation should be done and refresh dataTable and display same page. Operation is done but getting null pointer exception while displaying (Reddering) the same page
Thanks
The if () test on a Boolean will throw NullPointerException if the Boolean itself is actually null instead of true or false. In other words, the checked.get(dTO.getId()) has unexpectedly returned null for some reason.
That can have several causes:
The JSF implementation hasn't properly updated the checked map with the value from <h:selectBooleanCheckbox> for some reason.
The EL implementation was using Boolean instead of boolean for some reason.
The toVerifyTxnDTOList has incompatibly changed during the process which caused that the currently iterated dTO isn't the one which was been displayed in the table at the moment checkboxes were clicked (perhaps because the bean is request scoped instead of view scoped).
The toVerifyTxnDTOList contains more items than present in the checked map because you're using pagination and displaying only a subset at once.
In any case, to fix the NullPointerException, just add an additional nullcheck:
Boolean dtoChecked = checked.get(dTO.getId());
if (dtoChecked != null && dtoChecked) {
// ...
}
This however doesn't fix the underlying cause of your problem. My best guess would be that the toVerifyTxnDTOList contains more items than actually being displayed in the table. Thus, it's one of the last mentioned two causes mentioned in the list. The first mentioned two causes are theoretically possible, but in practice I haven't seen this before.
I'm trying to put an autocomplete that fetches suggestions as a list of Entry<String, Integer>
<p:autoComplete completeMethod="#{suggester.suggestTopics}"
var="x1" itemLabel="#{x1.key}" itemValue="#{x1.value.toString()}"
value="#{topicController.selected}" />
Manged bean code is as follows:
private int selected;
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected= selected;
}
But this fails saying the Integer class doesn't have method/property named key. If I remove the value attribute from autocomplete then it starts working properly. But when I put value attribute it starts expecting that the object inside var should be of the same type as that inside value attribute. I believe/expect it should be that the object inside itemValue should be of the same type as that inside value attribute.
I want to use POJOs for suggestions but pass just the entity Id to the value
Using :
Primefaces 3.1
JSF 2.1.6
I believe/expect it should be that the object inside itemValue should
be of the same type as that inside value attribute.
Yes this makes sense, and it is the same in the primefaces showcase:
<p:autoComplete value="#{autoCompleteBean.selectedPlayer1}"
id="basicPojo"
completeMethod="#{autoCompleteBean.completePlayer}"
var="p" itemLabel="#{p.name}" itemValue="#{p}"
converter="player" forceSelection="true"/>
As you see is var="p" and itemValue="#{p} where p is an instance of Player. And selectedPlayer1 is also an instance of Player.
I don't know if it works with a Map since the Primefaces example is called "Pojo support" and the suggestions should be a List of elements of the same type as in the value attribute.
I think you want to use the Simple auto complete , but instead you looked at the wrong example on the showcase of the Pojo Support
x1 refers to the int selected - while it expect to be referred to a POJO (with key and value properties.) , that's why you get the message
Integer class doesn't have method/property named key
Or simple use the Simple auto complete
As commented to Matt you dont need to rebuild Player(Pojo) from Db. You can set simply id property of Player(Pojo) and in action method may be utilize this id to fetch it from DB.
In your case in convertor you might do
Entry<String, Integer> e = new Entry<String, Integer>();
e.setId(value) // where value is passed in to convertor in method getAsObject.....
This value will be set to private Entry<String, Integer> selected
I have used Pojo autocomplete but not tried with generic classes.
Hope this helps.
I know the question is outdated but I've had the same problem.
The point is that you have to assign var to p (var="p"). I think it's terribly unobvious (documentation doesnot mention it has to be that way) 'cause I thought I can assign any var name I want.
I've a java.lang.Character bean property which I'd like to compare in EL as below:
#{q.isMultiple eq 'Y'}
It does not ever evaluate true.
How is this caused and how can I solve it?
In contrary to "plain Java", whether you single or double-quote your literals in EL, they represent both java.lang.String instances. Your method is returning a java.lang.Character instance, so this will never return true in an equals() call between both instances.
The solution is to change it to a String or boolean return type. The property name isMultiple strongly suggests a boolean. You only need to remove that is from the property name and keep it in the getter method.
private boolean multiple;
public boolean isMultiple() {
return multiple;
}
#{q.multiple}
An alternative is using an enum. This would only be applicable if you have more than two states (or perhaps three, a Boolean also includes null).
Can also do this by converting the Character to String by printing it as body of <c:set> as below:
<c:set var="isMultipleVal">#{q.isMultiple}</c:set>
And then comparing it instead:
#{isMultipleVal eq 'Y'}
If you're using EL 2.2, one workaround is:
#{q.isMultiple.toString() eq 'Y'}
You may need to look the property isMultiple in the Class of variable 'q'. Please verify your class having a getter method with signature as public char getIsMultiple(){}.
Also, are you sure ${q.isMultiple eq 'Y'} gives true?
I'm storing value expressions in a JSF component with the f:attribute tag, e.g.:
<h:inputText ...>
<f:attribute name="myId1" value="#{bean.prop1}" />
<f:attribute name="myId2" value="#{bean.prop2}" />
<f:attribute name="myId3" value="#{bean.prop3}" />
</h:inputText>
Is there a way to access all of those value expressions programmatically? (without knowlegde of the names myId1, myId2,...)
Section 9.4.2 of the JSF 2.1 specification says that those values are stored "in the component’s ValueExpression Map".
That's the only occurrence of the term "ValueExpression Map" in the complete spec.
How do I access that map?
In the UIcomponent's Method getValueExpression() of the Jboss/Mojarra implementation the map
getStateHelper().get(UIComponentBase.PropertyKeys.bindings)
is used to obtain a single value expression.
I guess that map is a super set of the "ValueExpression Map"?
Can I be sure that all implementations and all inherited (standard) components use that map to store ValueExpressions?
Thanks.
In theory you should be able to see them all by UIComponent#getAttributes():
Map<String, Object> attributes = component.getAttributes();
for (Map.Entry<String, Object> entry : attributes.entrySet()) {
System.out.printf("name=%s, value=%s%n", entry.getKey(), entry.getValue());
}
However, that doesn't work the way as you'd expect. It only returns static attributes. This does not seem to ever going to be fixed/implemented. See also JSF issue 636. I'd suggest to stick to attribtues with predefinied prefix and an incremental numerical suffix, like as you've presented in your example. That's also what I've always used to pass additional information from the component on to custom validators and converters. You can just collect them as follows:
Map<String, Object> attributes = component.getAttributes();
List<Object> values = new ArrayList<Object>();
for (int i = 1; i < Integer.MAX_VALUE; i++) {
Object value = attributes.get("myId" + i);
if (value == null) break;
values.add(value);
}
System.out.println(values);
An alternative to the answer given by BalusC might be to use nested facets or UIParameter components. Facets can be retrieved as a map using getFacets but you probably need to put an additional UIOutput inside each facet to access its value expression.
Nested UIParameters can be accessed by iterating over the components children and checking for instanceof UIParameter. UIParameters have name and value attributes and so could be easily converted to a map.
I have used parameters in a custom component, but I'm not sure how a standard UIInput like in your example reacts to these.
BalusC is right. UIComponent#getAttributes().get(name) gets values from both places - at first from attributes map and then if not found from "value expression map". To put some value you have to call UIComponent#setValueExpression(name, ValueExpression). If value is literal, it gets stored into the attribute map, otherwise into the "value expression map". Everything is ok then.