JSF Selectitems Format Label Number - jsf

I've got a List of Numbers (range 500 - 5000, steps of 500).
I would like to add a decimal dot 1000 -> 1.000; 2500 -> 2.500 etc. but just for the labels not to be saved as a value.
I tried the following but it didnt work:
<h:selectOneMenu value="#{bean.selectedValue}">
<f:convertNumber type="currency" locale="de-DE" pattern="#,###" />
<f:selectItems itemValue="#{bean.selectItemslist}" var="item" itemLabel="#{item.label}" itemValue="#{item.value} />
</h:selectOneMenu>
But this didnt do anything :(
Tried several patterns and included integerOnly="true" but nothing seems to work :(
Thanks for your help!

The converter applies on the item value only, not on the item label. That explains why it "fails". In this particular case, your best bet is to create a custom EL function, so that you end up something like this:
<f:selectItems ... itemLabel="#{my:formatNumber(item.label, '#,###')}" />
The JSF utility library OmniFaces has several, see also OmniFaces functions/Numbers showcase.

Related

<h:selectOneMenu with conditional <f:selectItems shows options twice

I want to use a selectOneMenu to have a user choose a value. In some cases I want to disable one of the values shown in the menu. I tried using render on both the selectItems as well as selectOneMenu as well as added a ui:fragment around the Menu but I always get all the values from both lists shown. Any ideas how to prevent that?
Here my current last try that again resulted in twice the list and the item in question once enabled and once disabled in it:
<ui:fragment rendered="#{cc.attrs.showP==true}">
<h:selectOneMenu id="type" binding="#{cc.type}">
<f:selectItems value="#{typeDAO.findAll()}"/>
</h:selectOneMenu>
</ui:fragment>
<ui:fragment rendered="#{cc.attrs.showP==false}">
<h:selectOneMenu id="type" binding="#{cc.type}">
<f:selectItems value="#{typeDAO.findAll()}" var="item" itemDisabled="#{item=='P'}"/>
</h:selectOneMenu>
</ui:fragment>
Your concrete problem is caused because you're binding physically multiple components to the same variable.
<h:selectOneMenu ... binding="#{cc.type}" />
<h:selectOneMenu ... binding="#{cc.type}" />
If the getter behind binding returns non-null, then JSF will use it instead of creating a new one. Basically, the second tag will reuse the component created in the first tag and set/add all attributes/items to it.
Your particular case can be solved in at least two ways:
Use JSTL to build the JSF component tree conditionally instead of using JSF to render the HTML output conditionally. You shouldn't have physically multiple components in the JSF component tree sharing the same binding let alone the same id.
<c:if test="#{cc.attrs.showP}">
<h:selectOneMenu id="type" binding="#{cc.type}">
...
</h:selectOneMenu>
</c:if>
<c:if test="#{not cc.attrs.showP}">
<h:selectOneMenu id="type" binding="#{cc.type}">
...
</h:selectOneMenu>
</c:if>
Make your code DRY. I.e. get rid of all code duplication.
<h:selectOneMenu id="type" binding="#{cc.type}">
<f:selectItems value="#{typeDAO.findAll()}" var="item" itemDisabled="#{not cc.attrs.showP and item eq 'P'}" />
</h:selectOneMenu>
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
JSTL in JSF2 Facelets... makes sense?
Guess I found it - bit weird to answer my question though. I think it's because the possible values of the menu are created before the rendered attributes are evaluated and since I did bind both menus to the same variable/id I got all items of the two menus. Thus I now used different names and then in my composite component have some logic that checks which one is used and continues to use the right value. Works :-)
Bit weird to me is this thing that as a developer u have to know when the attribute list is built in comparison to when the rendering happens. I recently had a similar issue with foreach and repeat. Is there any way to know these things as part of some overarching concept that I can remember or is that really case by case?
Thanks guys!

Primefaces selectCheckboxMenu how to get the last checked item

I am using selectCheckboxMenu from primefaces, but i need to know which item was checked here is my code:
<p:selectCheckboxMenu
label=""
id="cboBiblioteca"
filter="true" filterMatchMode="contains"
required="false"
widgetVar="cboBiblioteca"
value="#{documentalBean.sbiblioteca}"
style="width:20px">
<p:ajax event="change" listener="#{documentalBean.checkBiblioteca()}"/>
<f:selectItems value="#{bibliotecaBean.bibliotecas}" var="biblioteca" itemLabel="#{biblioteca.NOMBRE_BIBLIOTECA.toLowerCase()}" itemValue="#{biblioteca.ID_BIBLIOTECA_MEDIADOR}"/>
</p:selectCheckboxMenu>
my "sbiblioteca" array is a String array, when i whatch it on the debugger i cant get the last checked, because they arent added to the last they are added according to their position in the list.
Store the 'last -1' list and compare with the 'last'... Simple... Just like you would in plain java... See differences between two arrays

Dynamically setting value of a h:selectOneMenu using c:forEach

I'm working on a project that requires me to display and be able to select and store tags to the product. Tags are provided in tree-like structure. I can't assume maximum depth of a tags tree.
I wanted to display tags split by levels, using c:forEach - p:selectManyCheckbox - f:selectItems, and handling selections using p:ajax components.
I use following types to store possible values and selections in Tree object:
HashMap<Long, ArrayList<Tag>> tree;
HashMap<Long, Object[]> selected;
Hashmap keys are equal to "tag level".
In order to display values I use following code for testing:
<p:panelGrid id="tagDisplay" columns="2">
<c:forEach begin="1" end="5" var="idx">
<p:outputLabel value="#{idx}"></p:outputLabel>
<p:selectManyCheckbox value="#{product.tags.selected[1]}">
<f:selectItems value="#{product.tags.tree[1]}" var="tag" itemLabel="#{tag.name}" itemValue="#{tag.id}" />
<p:ajax listener="#{product.selectorListener}" update="tagDisplay" />
</p:selectManyCheckbox>
</c:forEach>
</p:panelGrid>
Code seemed to work fine, though displayed five times.
Now I'm stuck trying to dynamically bind Hashmaps to selectors. As I replaced "1" with "idx", I got no results.
I tried to use ui-repeat with a dummy table, but then I lost panelgrid structure.
Any help will be appreciated!
My environment - Websphere 8.5, JSF 2.2, Primefaces 5.2
The <c:forEach begin end> is only for static iteration, not for dynamic iteration.
You'd better iterate over #{product.tags.tree} itself in <c:forEach items>. Each iteration over a Map will give Map.Entry back which in turn has getKey() and getValue() methods.
<p:panelGrid ...>
<c:forEach items="#{product.tags.tree}" var="entry" varStatus="loop">
<p:outputLabel value="#{loop.index}"></p:outputLabel>
<p:selectManyCheckbox value="#{product.tags.selected[entry.key]}">
<f:selectItems value="#{entry.value}" ... />
...
</p:selectManyCheckbox>
</c:forEach>
</p:panelGrid>
That said, must it really be a HashMap? Don't you rather want a fixed ordered LinkedHashMap?

Length of h:outputLabel changes after RichFaces AJAX call

I have been trying to incorporate RichFaces into one of our more complicated pages to make it run a bit more smoothly via AJAX. Everything is working fine and it has solved a few problems I was having using regular form posts so I'd really like to keep it. The only problem in my way is that after pressing an a4j:commandButton most of my h:outputLabels are shortened by 3 pixels (these pixels were to the left of the text, which is unusual since the left padding, margin and border width are all 0px). This causes lots of my controls to shift slightly and looks very unprofessional. It looks to me like the re-rendering has done a more accurate job than the initial render. Here are the relevant parts of my page:
<a4j:form id="mainForm">
...
<fieldset id="illustrationDetails">
<h:outputLabel for="product" value="Product" />
<h:selectOneMenu id="product" value="#{illustrationManager.illustration.product}" valueChangeListener="#{illustrationManager.illustration.setProduct}" onchange="submit()">
<f:selectItems value="#{illustrationManager.illustration.products}" />
</h:selectOneMenu>
<h:outputLabel for="paymentFrequency" value="Payment" />
<h:selectOneMenu id="paymentFrequency" value="#{illustrationManager.illustration.paymentFrequency}">
<f:selectItems value="#{illustrationManager.illustration.paymentFrequencies}" />
</h:selectOneMenu>
<h:outputLabel for="expenseGroup" value="Expense Group" />
<h:selectOneMenu id="expenseGroup" value="#{illustrationManager.illustration.expenseGroupId}">
<f:selectItems value="#{illustrationManager.illustration.expenseGroups}" />
</h:selectOneMenu>
</fieldset>
...
<a4j:commandButton id="calculateButton" value="Calculate" action="#{illustrationManager.calculatePremium()}" ajaxSingle="true" reRender="mainForm" />
...
</a4j:form>
In the fieldset above, all but the first label exhibit this problem. The first label is rendered what I would consider to be correctly (with no pixels to the left) by the initial render and as a result is not changed by the re-render.
Any suggestions would be welcome! Also, if you want more info like the css for the relevant controls let me know and I'll post it.
Well, this is a partial answer anyway. The 3 pixels to the left of the h:outputLabels was due to the fact that the Mojarra JSF implementation adds a \n character to the beginning of the label tag body it creates. I'm as baffled as the guy who submitted this bug about it as to why this is done. The \n is converted to a space when displayed and that's what my 3 pixels were.
I do not know why, but the re-render triggered by my RichFaces AJAX call removes these \n characters and so the space is no longer displayed.
As a workaround, I have explicitly put spaces at the front of all my labels so that a space is always displayed. I'm surprised this is not a common problem.

Formatting a double in JSF

I have a problem similar to the one found here : JSF selectItem label formatting.
What I want to do is to accept a double as a value for my and display it with two decimals. Can this be done in an easy way?
I've tried using but that seems to be applied on the value from the inputText that is sent to the server and not on the initial value in the input field.
My code so far:
<h:inputText id="december" value="#{budgetMB.december}" onchange="setDirty()" styleClass="StandardBlack">
<f:convertNumber maxFractionDigits="2" groupingUsed="false" />
</h:inputText>
EDIT: The above code actually works. I was fooled by JDeveloper that didn't update the jsp page even when I did a explicit rebuild of my project and restarted the embedded OC4J server. However, after a reboot of my computer everything was fine.
If I'm not misunderstanding your requirement, I was able to achieve formatting of the value in the input box during the rendering of the view with:
<h:inputText id="text1" value="#{...}">
<f:convertNumber pattern="#,###,##0.00"/>
</h:inputText>
I was using the Standard Faces Components in my vendor-branded Eclipse so I'm assuming the pattern attribute is part of standard JSF.
If what you are trying to do is make the value of the input text field change on screen (to correct user input), you should probably look into using one of the JSF ajax frameworks like Rich Faces.
A possible example would look like this:
<h:inputText id="december" value="#{budgetMB.december}" styleClass="StandardBlack">
<f:convertNumber maxFractionDigits="2" groupingUsed="false" />
<a4j:support event="onblur" reRender="december" />
</h:inputText>
I haven't tested this, but I think it may work.
It seems you're actually formatting a currency. There already exists a specific formatter to handle currencies that you can assign many options to:
<f:convertNumber type="currency" />
Some interesting attributes of this tag are: locale, currencyCode, integerOnly, currencySymbol and pattern.

Resources