Render an icon conditionally - jsf

In a Datatable of Primefaces I want to insert an icon in a certain column conditionally.
This column has two values: 1 or 0, if it is 1 use the check icon and if it is 0 use the close icon.
I've already tried with "rendered", with "style", with styleClass, and it does not work for me. Either the read values are output, or nothing is rendered (the column is empty).
Is there any way to do this?
I pass a portion of code:
<p:column headerText="Vota" width="30" filterBy="#{vot.estado}">
<h:outputText value="#{vot.estado}" style="float:right #{vot.estado == 1 ? 'ui-icon-check' : 'ui-icon-close'}"/>
</p:column>

You have the icon info in the style attribute while it should be in the styleClass attribute and you need the generic ui-icon class too.. So change your code to the following to make it work
<p:column headerText="Vota" width="30" filterBy="#{vot.estado}">
<h:outputText value="#{vot.estado}" style="float:right" styleClass="ui-icon #{vot.estado == 1 ? 'ui-icon-check' : 'ui-icon-close'}"/>
</p:column>

You can use rendered attribute with the outputText itself, like below:
<p:column headerText="Vota" width="30" filterBy="#{vot.estado}">
<h:outputText rendered="#{vot.estado == 1}" value="#{vot.estado}" style="float:right" styleClass="ui-icon-check"/>
<h:outputText rendered="#{vot.estado != 1}" value="#{vot.estado}" style="float:right" styleClass="ui-icon-close"/>
</p:column>

<p:column headerText="Vota" width="30" filterBy="#{vot.estado}>
<h:outputText value="#{vot.estado}"/>
<i class="ui-icon #{vot.estado == 1 ? 'ui-icon-check' : 'ui-icon-close'}" style="display: inline-block"/>
</p:column>

Related

How to block a single datatable cell in primefaces with blockUI

I'm creating a datatable with some some dynamically generated columns. In each of the cells of those columns, there's a button to refresh the data of that specific cell.
What I want is that the cell is blocked when the button on that cell is pressed.
Sample code:
<p:dataTable id="table" var="tableVar" value="#{tableValues}">
<p:columns id="column" var="columnVar" value="#{columnValues}">
<f:facet name="header">
<h:outputText value ="#{columnVar}"/>
</f:facet>
<h:outputText value="Some Text"/>
<p:commandButton value="Button Text"
id="button"
update="table"
actionListener="#{some.method()}"/>
<p:blockUI block="?????" trigger="button">
<p:graphicImage name="loading.gif"/>
</p:blockUI>
</p:columns>
</p:dataTable>
I don't know what should go in the block parameter to only block a cell. I also tried to just block="column", but even that wasn't blocking the column as I expected, instead it was just displaying the loading gif near the button but not blocking anything.
I have seen this question How update just specific cell in primefaces dataTable where the answers say it's not possible to specify a single cell, but it's from 2012, and the answers mention that it might get fixed on a later version.
After playing a bit, I found a solution.
You can define a <p:outputpanel id="cell"></p:outputpanel> surrounding the content of the cell, and then block it with block="cell" in the blockUI component.
The result would be something like:
<p:dataTable id="table" var="tableVar" value="#{tableValues}">
<p:columns id="column" var="columnVar" value="#{columnValues}">
<f:facet name="header">
<h:outputText value ="#{columnVar}"/>
</f:facet>
<p:outputpanel id="cell">
<h:outputText value="Some Text"/>
<p:commandButton value="Button Text"
id="button"
update="table"
actionListener="#{some.method()}"/>
<p:blockUI block="cell" trigger="button">
<p:graphicImage name="loading.gif"/>
</p:blockUI>
</p:outputpanel>
</p:columns>
</p:dataTable>

Nested primefaces datatable not submitting values properly for innermost datatable

I have two levels of nested datatables in the form of
<p:dataTable id="necesidades"
value="#{registrarAccionDosBean.accionDos.necesidadesConTema}"
rendered="#{not empty registrarAccionDosBean.accionDos.necesidadesConTema}"
var="necesidad"
rowKey="#{necesidad.idNecesidad}">
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:rowExpansion>
<h:panelGroup id="grupoTema">
<h:panelGroup id="edicion" rendered="#{necesidad.tema.idTema ne null}">
<p:row>
<p:column >
<h:outputLabel value="#{etiq.lbl_comunes_requerido} #{etiq.etiqueta_checkbox_transparenciasFocalizadas}" styleClass="textoAcciones"/>
</p:column>
<p:column >
<!-- Nested data table -->
<p:dataTable id="transparenciasInplace"
var="transparencias"
value="#{registrarAccionDosBean.transparenciasFocalizadas}"
selection="#{necesidad.tema.transparenciasFocalizadas}"
rowKey="#{transparencias.idTf}">
<f:facet name="header">
Objetives
</f:facet>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column>
<h:outputLabel value="#{transparencias.descripcion}" styleClass="textoAccionesSmall"/>
</p:column>
</p:dataTable>
</p:column>
</p:row>
</h:panelGroup>
</h:panelGroup>
</p:rowExpansion>
</p:dataTable>
I am able to retrieve the information and presented on screen properly, but when I send to submit through a command button, all the information is sending but the values of the innermost datatable(the one which id is "transparenciasInplace") are not sending in the right way, in the backing bean I getting the following information which is incorrect
The way I receive the values in the bean
Subject1 ---ObjetivesE,ObjetiveF
Subject2 ---null
Subject3 ---null
The way that I expect and I see on screen
Subject1 ---ObjetivesA (1 object subject and 1 object Objective)
Subject2 ---ObjectiveB,ObjectiveC,ObjectiveD (1 object subject and 3 objects Objective)
Subject3 ---ObjetivesE,ObjetiveF (1 object subject and 2 objects Objective)
The code of my command button
<p:commandButton process="#form" icon="ui-icon ui-icon-disk" id="btnsave"
value="Save" actionListener="#registrarAccionDosBean.guardar}"
widgetVar="btnguardar"
onclick="setTimeout('btnguardar.disable()', 10);" title="#{etiq.btn_guardar}" update="content"/>
I don't know why in the subject1 I am getting the value of the Subject3 and the values of the Subject2 and Subject3 are setting to null
So basically I need to change my datatable to a p:selectManyCheckbox. That's because in the datatable I can not differentiate my source form my target in this particular case, because when I write
<p:dataTable id="transparenciasInplace"
var="transparencias"
value="#{registrarAccionDosBean.transparenciasFocalizadas}"
selection="#{necesidad.tema.transparenciasFocalizadas}"
rowKey="#{transparencias.idTf}">
.
.
The value that is sending is my source and this is shared between the n rows and I think there was the problem, but if we use something like this
<p:selectManyCheckbox id="transparenciasInplace" value="#{necesidad.tema.transparenciasFocalizadas}" layout="pageDirection" columns="1" converter="transparenciaConverter" style="table-layout: auto;font-weight: bold; text-align: justify;font-size :15px">
<f:selectItems value="#{registrarAccionDosBean.transparenciasFocalizadas}" var="transparenciaC" itemLabel="#{transparenciaC.descripcion}" itemValue="#{transparenciaC}" />
</p:selectManyCheckbox>
I clearly separete my source
<f:selectItems value="#{registrarAccionDosBean.transparenciasFocalizadas}" var="transparenciaC" itemLabel="#{transparenciaC.descripcion}" itemValue="#{transparenciaC}" />
from the target (the value that I want to send)
<p:selectManyCheckbox id="transparenciasInplace" value="#{necesidad.tema.transparenciasFocalizadas}" layout="pageDirection" columns="1" converter="transparenciaConverter" style="table-layout: auto;font-weight: bold; text-align: justify;font-size :15px">

How can I change column width of panel grid in PrimeFaces

I am working with Java EE and PrimeFaces. How can I change the column width of a panel grid in PrimeFaces?
Is there an example ?
You can qualify your columns inside the panelGrid using columnClasses. The following code sets different width and stick the cells content aligned to the top-side.
<h:panelGrid columns="2" style="width: 100%" columnClasses="forty-percent top-alignment, sixty-percent top-alignment">
.forty-percent {
width: 40%;
}
.sixty-percent {
width: 60%;
}
.top-alignment {
vertical-align: top;
}
I had a similar problem and here is my solution:
<p:panelGrid style="width:100%"> # notice that I do not define columns attribute in p:panelGrid!!
<f:facet name="header"> # header
<p:row> # p:row and p:column are obligatory to use since we do not define columns attribute!
<p:column colspan="2"> # here I use colspan=2, coz I have 2 columns in the body
Title
</p:column>
</p:row>
</f:facet>
<p:row>
<p:column style="width:150px"> # define width of a column
Column 1 content
</p:column>
<p:column> # column 2 will fill the rest of the space
Column 2 content
</p:column>
</p:row>
<f:facet name="footer"> # similar as header
<p:row>
<p:column colspan="2">
Footer content
</p:column>
</p:row>
</f:facet>
</p:panelGrid>
So as you can see, the main difference is that you do not define columns attribute in p:panelGrid. In header and footer you have to use p:row and p:column, and in my case I also have to use colspan=2 since in body we have 2 columns.
Hope this helps ;)
Have you considered the style attribute ?
Example :
<p:panelGrid columns="2" style="width: 50px">
Otherwise, for columns :
<p:column style="width:50px">
Refer to this thread : how can I adjust width of <p:column> in <p:panelGrid>?

PrimeFaces datatable Scrollbar

I have a form with a primefaces datatable which i have set the columns width in css for it :
.idcol{width: 5%}
.prioritycol{width: 5%}
.titlecol{width: 30%}
.descriptioncol{width: 40%}
.actionscol{width: 10px}
Everything is okay but when i add the scrollable="true" attribute in order to have a scrollable datatable, the result is worst :
This is the declaration of the datatable :
<p:dataTable id="dtable" var="todos" value="#{todo.todoList}" scrollable="true"
resizableColumns="false" scrollHeight="300" lazy="true"
styleClass="idcol,prioritycol,titlecol,descriptioncol,actionscol">
What is the problem?
Thank you!
You can set the column width this way
<p:column headerText="Type" width="70%">
or you can specify style class this way
<p:column headerText="Type" styleClass="idcol" >
You can add scrollWidth some thing like this
<p:dataTable var="data" rowKey="#{data.key}" style="width:70%"
sortOrder="ascending"
selection=""
value=""
selectionMode="single"
scrollable="true"
scrollWidth="71%"
scrollHeight="3%"
>
<p:ajax event="rowSelect" listener=""
update="" />
<p:column headerText="Type" styleClass="" sortBy="" width="70%">
<h:outputText id="dataTYpe" value="" />
</p:column>
<p:column headerText="Category" sortBy="" width="30%">
<h:outputText value="" />
</p:column>
</p:dataTable>
I found the solution,
You have to edit you css and you JSF code at the same time and looking what you have as result,
For my problem i edited my css and the jsf code step by step, here is the code that worked for me :
CSS :
.idcol{width: 5%}
.prioritycol{width: 5%}
.titlecol{width: 30%}
.descriptioncol{width: 40%}
.actionscol{width: 20%}
The Form :
Column 1 : width="25"
Column 2 : width="55"
Column 3 : width="369"
Column 4 : width="469"
Column 5 : width="170"

JSFpanelGrid dynamically populated

I want to render a panelGrid with a fixed number of columns but elements are loaded from a list. The code should be as follows:
<h:panelGrid columns="3">
<h:outputText value="Header 1"/>
<h:outputText value="Header 2"/>
<h:outputText value="Header 3"/>
<ui:repeat value="#{bean.collection}" var="obj">
<p:panel>
<h:outputText value="#{obj.value}"/>
</p:panel>
</ui:repeat>
</p:panelGrid>
The problem is this code is not rendering as I expected, because all panels are enclosed in the first TD generated by panelGrid, and I want a row break every 3 elements. It seems all repeat block is executed prior the rendering. I'm sure I can obtain this behaviour. What I'm doing wrong?
Thanks
ui:repeat is a component and it is part of the component tree. To create what you are planning try using tag handler c:forEach instead.
<c:forEach items="#{bean.collection}" var="obj">
<p:panel>
<h:outputText value="#{obj.value}"/>
</p:panel>
</c:forEach>

Resources