JSF not null condition [duplicate] - jsf

This question already has answers here:
Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work
(1 answer)
JSTL c:if doesn't work inside a JSF h:dataTable
(1 answer)
JSTL in JSF2 Facelets... makes sense?
(3 answers)
Closed 5 years ago.
Using JSF & EL, I'm basically trying to check if a variable is null (or not).
Here is a code snippet:
<p:dataGrid value="#{bean.graphiques}"
var="graphique"
rows="1" columns="3">
<c:if test="#{not empty graphique}">
<p:chart type="line" model="#{graphique}"/>
</c:if>
<c:if test="#{empty graphique}">
<p:outputLabel>
Add a new chart.
</p:outputLabel>
</c:if>
</p:dataGrid>
First check, #{not empty graphique} is always false, even if graphique is not null. I tried with #{graphique ne null} and #{graphique != null}, but it's false, too.
When I remove the c:if statement, the chart is displayed. Thus, graphique is not null.
I looked for a solution on a lot of websites - including SO - but didn't manage to find a solution.
Do you know what's going on and how to solve my problem?
Thanks!

Did you try...
<p:chart type="line" model="#{graphique}" rendered="#{graphique != null}"/>
Sometimes I had issues with primefaces tags in <c:if>

Related

p:selectBooleanCheckBox does not work inside a p:dialog [duplicate]

This question already has answers here:
Can you nest html forms?
(21 answers)
How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?
(2 answers)
Closed 6 years ago.
I'm using PrimeFaces 5.3 with the following code:
<p:dialog id="dlg1" appendTo="#(body)" header="Confirm Dialog" widgetVar="dlg1" modal="true">
<h:form id="dialogform">
<h:outputText id="confirmlabel" value="Are you Sure you want to #{reportRunnerNamedBean.currentCommand} ?" />
<br/>
<center>
Check to send only missed emails:<p:selectBooleanCheckbox id="sendOnlyMissedBox" value="#{reportRunnerNamedBean.sendMissedOnly}"></p:selectBooleanCheckbox><br/>
<p:commandButton id="yesButton" value="Yes" action="#{reportRunnerNamedBean.runCurrentCommand()}" onstart="startWait();PF('waitDialog').show();" oncomplete="PF('waitDialog').hide();stopWait();" onclick="PF('dlg1').hide();" process="#form"/>
<p:commandButton id="noButton" process="#this" value="No" onclick="PF('dlg1').hide();"/>
</center>
</h:form>
</p:dialog>
No matter what, the backing bean value for the sendMissedOnly is set to false. I have confirmed this by attaching a debugger. I have even tried adding ajax to the box, it is still false every time, no matter if it is checked or not. Does p:selectBooleanCheckbox just not work in a dialog?
I figured this out. It was because the dialog was in an form. It seems that when a dialog is in a form , and you have a form within the dialog itself, the component will not be processed. It seems JSF/primefaces does not like multiple layers of forms or dialogs defined within forms. If you are having a similar issue, makes sure your dialog is defined outside any form. Moving a dialog can cause paths to components to change. the easiest way to resolve that is to use the primefaces handy p:component tag like this update=":#{p:component('compoment_name')}" > that will make it find it no matter where in the tree the component occurs.

p:commandButton can't to update p:panel [duplicate]

This question already has an answer here:
How to update panel from datatable [duplicate]
(1 answer)
Closed 7 years ago.
I'm using PF 5.3, with JSF 2.2
I have a p:commandButton which exists in one of p:column of a p:dataTable. I have a panel outside the dataTable and I want it to be updated once the commandButton is clicked, but this didn't work.
xhtml sample:
<h:form id="register_edit_student" enctype="multipart/form-data" >
<p:dataTable var="students" value="#{generalPresentation.students}">
<p:column headerText="Edit">
<p:commandButton update="updateStudent" value="Edit" action="#{teacherPresentation.assignEditableStudent(students)}" />
</p:column>
</p:dataTable>
<p:panel id="updateStudent">
</p:panel>
</h:form>
My requirement is to update the "updateStudent" p:panel.
Once I ask the p:commandButton to update the panel (update="updateStudent") the page design crashed and all controls disappeared.
I was reading in the internet the commandButton of a column in a dataTable cannot update anything outside the dataTable, so the question, is there a solution or work around?
Thanks
You have three options to solve this:
add prependId="false" to your form,
Prepend the form id in your reference: update=":register_edit_student:updateStudent" or
move your panel outside of the form element.
Note: The first option should be used rarely and is known to cause issues with plain JSF.

Recursion with include and h:datatable [duplicate]

This question already has an answer here:
JSTL c:if doesn't work inside a JSF h:dataTable
(1 answer)
Closed 7 years ago.
I'm having some troubles trying to recursively include pages. The problem is that all the include actually take place but there is something going on with the h:dataTable that makes it so the second included datatable content isn't displayed.. I'm guessing the problem comes from the var post being concurrent with itself. It works without the datatable.
So from a page.xhtml I'm calling an include for post_view2.xhtml:
<ui:include src="/template/includes/post_view2.xhtml" >
<ui:param name="postList" value="#{watchThread.listeFirstPosts}"></ui:param>
<ui:param name="count" value="8"></ui:param>
</ui:include>
Count is set to 8.
This is post_view2.xhtml:
<ui:composition xmlns=....>
<h:dataTable var="post" value="#{postList}" styleClass="fullWidth">
<h:column>
#{post.posts.size()} <!-- gives a size higher than 0 -->
<h:outputText value="#{watchThread.sanitize(post.content)}"/>
<c:if test="${count gt 0}">
<ui:include src="/template/includes/post_view2.xhtml">
<ui:param name="postList" value="#{post.replies}"></ui:param>
<ui:param name="count" value="${count-1}"></ui:param>
</ui:include>
</c:if>
</h:column>
</h:dataTable>
</ui:composition>
Notice that at the first include the post var is equal to a list. On the second include I'm trying to make it equal to another list and I think that is what is causing the problem. I don't know why nor how to solve it.
On a side note I'm using jstl c:if but if there is another solution that is pure jsf, primefaces included I'd take it.
I found a bit of a workaround but I'll let the question as unanswered.
Instead of using DataTable I'm using jsp tag forEach and it works.
so instead of this:
<h:dataTable var="post" value="#{postList}">
I have :
<c:forEach var="post" items="#{postList}">
I don't know why this works and dataTable doesn't. If anyone knows please expand.

Conditionally render a <div> based on value of <h:outputText>

I am using jsf primefaces. I want to display an image depending on the value of a specific outputext. If the text value is 'Alarm *' then a div will appear whith a spesific image. If the value is 'Alarm **' then a div with an other image will appear, etc. I tried the code below but it does not work for me.
<h:outputText id="alarmCriticalityValue" value="#{msg[summary.criticality.key]}" />
<c:if test="#{alarmCriticalityValue=='Alarm *'}">
<div class="alarm1"></div>
</c:if>
How should i implement this idea?
You need to use binding attribute to put the UIComponent instance in the EL scope. The id attribute doesn't do that, on contrary to what you expected.
<h:outputText binding="#{alarmCriticality}" ... />
And then you need to use UIOutput#getValue() to obtain its value attribute.
<c:if test="#{alarmCriticality.value == 'Alarm *'}">
That said, you'd better use rendered attribute here, particularly if #{summary} represents the currently iterated item of a JSF iterating component like <ui:repeat> or <h:dataTable>.
<h:panelGroup layout="block" styleClass="alarm1"
rendered="#{alarmCriticality.value == 'Alarm *'}" />
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
How to conditionally render plain HTML elements like <div>s?
JSTL in JSF2 Facelets... makes sense?
Unrelated to the concrete problem. It's strange to see the conditional rendering depend on localized text. What if you change the locale and/or the localized text? This is very brittle. You'd better check the bundle key instead.
<h:outputText value="#{msg[summary.criticality.key]}" />
<h:panelGroup layout="block" styleClass="alarm1"
rendered="#{summary.criticality.key == 'some.alarm.key'}" />
This way you also don't need to bind the output text anymore.
Try
<c:if test="#{msg[summary.criticality.key].equals('Alarm *')}">
Or add a binding to the h:outputText and check against that.
Try this
<h:outputText id="alarmCriticalityValue" value="#{msg[summary.criticality.key]}" />
<h:panelGroup layout="block" styleClass="alarm1" rendered="#{alarmCriticality.value eq 'Alarm *'}" />

Use c:set inside ui:repeat does not work

I have a JSF 2 application with the following code:
<c:set var="number" value="0" scope="view" />
<ui:repeat value="${items}" var="item" varStatus="itemIndex">
<c:if test="${item.boolProperty == true}">
<c:set var="number" value="${number + 1}" scope="view" />
</c:if>
<h:outputText value="#{item.name}" />: <h:outputText value="#{number}" />
</ui:repeat>
I want to increase the number depending on the property of the item in the loop. However, the condition seems not to work, since the value of number always stays 0. If I remove the condition, the number is incremented only once, or it is always 0 before incrementing, therefore it outputs 1. Could it be possible the number var changes not to affect the number var that is outside the loop? I believe the scope attribute takes care of that.
JSTL tags and JSF components doesn't run in sync as you'd expect from the coding. JSTL tags runs during building of the JSF view, while JSF components runs during rendering of the JSF view. See for a detailed explanation also JSTL in JSF2 Facelets... makes sense?
What you want to achieve is unfortunately not possible with JSF components. The <ui:param> comes close, but it functions merely as an alias for a more complex EL expression, while the <c:set> actually sets something in the desired scope (the view scope which you've there is by the way wrong).
Your best bet is to change the model or wrap the model in another model so that you end up as
<ui:repeat value="${items}" var="item" varStatus="itemIndex">
<h:outputText value="#{item.name}" />: <h:outputText value="#{item.number}" />
</ui:repeat>

Resources