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.
Related
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!
I must print some component from html page. I used from Prime Faces, but I have some problem.
Internet Explorer 11 add some text to printed images ("Submit Query").
Problem occur in h:commandButton which have empty value.
How I may resolve this problem??
You can achieve by using css background-image with image in order to present a background image.
<h:commandButton value=" " style="background-image: url(your-image.png)" />
If you do not want to have the appearance of a button, you can nest <h:graphicImage> inside
<h:commandLink> and instead.
<h:commandLink ...>
<h:graphicImage value="your-image.png" />
</h:commandLink>
This is the code in the body of my .xhtml file. The bars were showing before (I don't remember changing anything significant) but now just the value is displayed.
<p:progressBar value="#{bean.value}" labelTemplate="{value}%" styleClass="animated"/>
<p:progressBar id="progress" interval="100" rendered="true" ajax="true" value="#{bean.value}" widgetVar="pbAjax" labelTemplate="{value}%" style="width:300px; font-size:12px"/>
The second bar is derived from this answer but the problem still remains the same.
<p:progressBar value="50" labelTemplate="{value}%" displayOnly="true"/>
This is the code from primefaces, which also does not show up as a bar but just as a value.
I would appreciate it you could clarify if I have some major misunderstanding of how the progressBar works.
Use Firebug or your browser's WebDevelopment Tools to check if the progressbar is properly rendered:
Check for Javascript Errors
Is the right CSS Style applied or are you overwriting primefaces css classes?
Are you using your own JQuery Version? It can come to conflicts between your JQuery and Primefaces' one.
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.
With richfaces, how can I get my h:outputLabel and rich:combobox components to display directly adjacent to each other on the same line?
Here are the two approaches I've tried.
#1 rich:Layout
I first tried using rich:layout & rich:layoutPanel, but the components appear on separate lines. Here's the code:
<rich:layout>
<rich:layoutPanel position="left" width="100%">
<h:outputLabel for="timeSpanUnitsCombo2" value="Time Span " />
<rich:comboBox id="timeSpanUnitsCombo2" value="#{bean.timeSpanUnitsLabel}" enableManualInput="false">
<f:selectItems value="#{bean.timeSpanUnitsList}" />
</rich:comboBox>
</rich:layoutPanel>
</rich:layout>
And here's the rendered output:
#2 h:panelGrid
Next I tried using a h:panelGrid, but again no success - the components are evenly spaced over the available area, instead of being directly adjacent and left-aligned as I intended. Here's the code:
<h:panelGrid columns="2">
<h:outputLabel for="timeSpanUnitsCombo3" value="Time Span " />
<rich:comboBox id="timeSpanUnitsCombo3" value="#{bean.timeSpanUnitsLabel}" enableManualInput="false">
<f:selectItems value="#{bean.timeSpanUnitsList}" />
</rich:comboBox>
</h:panelGrid>
And here's the rendered output:
Component layout with richfaces is proving to be thoroughly frustrating. I'll give second prize to anyone who has some good references on layout with richfaces. :)
This can be done by many ways. One of them is to use fragment
<s:fragment>
<h:outputText value="Time Span" />
<rich:comboBox id="timeSpanUnitsCombo2" value="#{bean.timeSpanUnitsLabel}" enableManualInput="false">
<f:selectItems value="#{bean.timeSpanUnitsList}" />
</rich:comboBox>
</s:fragment>
Or you can use a div instead of fragment. <div> your code...</div>
If you are using seam, you can wrap it in <s:decorate> and use <s:label>
From Seam in Action
....<s:label> and <s:message>. The benefit of using the Seam tags is
that they are automatically correlated with the adjacent input component, a feature
of <s:decorate>