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">
Related
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>
I have this datatable:
<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 have n rows collapsed with information inside of each of them, this information was persisted in different times and days, so I need to save some information plus the n rows as a whole, the problem is that the rows are collapsed when is show on screen and I want to be in that way because a can have a lot rows on screen and if I show them expanded it will be hard to read, but when I send it through a command button the table inside my collapsed row are setting null, I need to expand each of them in order to properly send all the information.
So I want to send the information collapsed but in some way force to fetch the information inside of each of them
I am getting the information from the database right, because there I just fetch my query and get the information right, so my problem is on my jsf page I think
I would like to display a list of label/input using <p:dataGrid>. My code is so simple, but I can't get the expected result.
This is my code:
<p:dataGrid columns="2" value="#{scriptManagerForm.params}" var="conf">
<p:column>
<p:outputLabel value="#{conf.name}" />
</p:column>
<p:column>
<p:inputText value="#{conf.value}" required="true" />
</p:column>
</p:dataGrid>
And this is the result that I get now:
And this is what I need to get:
You need the property layout="grid" in the dataGrid
I am sure you need a panelGrid instead of a dataGrid.
Inside you can also work with <p:row> and <p:column> if you want.
http://www.primefaces.org/showcase/ui/panel/panelGrid.xhtml
I hope this helps!
This question already has answers here:
Input field in <h:dataTable> always receives value of last item in list
(3 answers)
Closed 7 years ago.
I'm using h selectOneMenu in a datatable and when user press the Set Fixture button i'm saving the value changed in the dropdown, for now i'm using a String variable to get the selected value but the issue is it have the selected value from only the last dropdown. My question is how to get list of all the dropdowns ?
<h:form id="chooseAlmFixtureForm">
<p:panel style="width:80%" header="Set Fixture for Alarms">
<p:dataTable id="tbsetFixtureTable" value="#{setAlmFixtures.alarms}" var="alarmvar" dynamic="false">
<p:column>
<p:commandLink value="View" update=":viewUnknownAlarm" immediate="true" oncomplete="viewDialog.show()">
<f:setPropertyActionListener target="#{currentalarms.viewAlarm}" value="#{alarmvar}"/>
</p:commandLink>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Alarm Time"/>
</f:facet>
<h:outputText value="#{alarmvar.recvTime}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Alarm Type"/>
</f:facet>
<h:outputText value="#{alarmvar.alarmType}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Controller Name"/>
</f:facet>
<h:outputText value="#{alarmvar.controllerName}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Controller Type"/>
</f:facet>
<h:outputText value="#{alarmvar.controllerType}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Choose Fixture"/>
</f:facet>
<h:selectOneMenu id="selectAlarmSite" value="#{setAlmFixtures.selectedFixture}">
<f:selectItems value="#{setAlmFixtures.fixtures}" />
</h:selectOneMenu>
</p:column>
</p:dataTable>
<p:commandButton value="Set Fixtures" actionListener="#{setAlmFixtures.setAlarmsFixtures}" action="#{horizontalmenu.actionCallAlarmsPage}" styleClass="dialogButton"/>
</td><td>
<p:commandButton value="Cancel" actionListener="#{setAlmFixtures.releaseAlarms}" action="#{horizontalmenu.actionCallAlarmsPage}" styleClass="dialogButton"/>
</p:panel>
</h:form>
Currently, your dropdown-value refers to a single variable in your bean (which seems to be selectedFixture of class SetAlmFixtures). How would a single variable represent a state (value) for multiple row (here: alarms)?
You need to link the selected value to the row (alarm) it refers to. To do so, you have several options, two approaches following:
Use the variable of your alarm-object, just the same way as you used them as outputvalues inside the other columns. This way, the alarm's fixture is set directly on value (form) processing. Currently, both of your buttons submit the form (type="submit" is default), depending on what your actionlisteners do, you might consider changing the Cancel-button's type to button.
Map the fixtures and alarms. You could use something like Map<Long, Fixture> fixturemap; mapping alarm-id's to their selected fixture, assuming all alarms have a non-null id. The map's value can be referred by setAlmFixtures.fixturemap['alarmvar.id']. Make sure you provide a getter for the map and the id. Also, you need to initialize the map with the initial fixture values for each alarm.
I want to make a footer in dataTable and I need to update when the values inside the DT changes.
The problem is that ajax update simply don't occurs.
I've tried two ways:
<p:dataTable
id="dataTableAvaliacao" var="aluno"
value="#{alunoAvaliacaoMB.alunos}">
<p:column>
<p:inputText id="inputNota"
value="#{aluno.getNota(avaliacao.property).vlNotaString}">
<p:ajax event="change"
update=":form:dataTableAvaliacao:mediaAluno, :form:dataTableAvaliacao:mediaAvaliacao" />
</p:inputText>
</p:column>
<p:columnGroup type="footer" id="mediaAvaliacao">
<p:row>
<p:column
footerText="Nota média da avaliação" />
</p:row>
<p:row>
<ui:repeat value="#{alunoAvaliacaoMB.colunasAvaliacoes}"
var="avaliacao">
<p:column id="colunaMedia"
footerText="#{alunoAvaliacaoMB.getMediaAvaliacao(avaliacao.property)}"/>
</ui:repeat>
</p:row>
</p:columnGroup>
<p:dataTable>
The update doesn't occurs...
second way (based on this answer on SO: How to ajax update an item in the footer of a PrimeFaces dataTable?):
<p:remoteCommand name="refreshFooter" update=":form:dataTableAvaliacao:outputMediaAvaliacao"/>
<p:dataTable
id="dataTableAvaliacao" var="aluno"
value="#{alunoAvaliacaoMB.alunos}">
<p:column>
<p:inputText id="inputNota"
value="#{aluno.getNota(avaliacao.property).vlNotaString}">
<p:ajax event="change"
update=":form:dataTableAvaliacao:mediaAluno" oncomplete="refreshFooter();" />
</p:inputText>
</p:column>
<p:dataTable>
<f:facet name="footer">
<h:outputText colspan="1" value="Nota média da avaliação:"/>
<ui:repeat value="#{alunoAvaliacaoMB.colunasAvaliacoes}"
var="avaliacao">
<h:outputText id="outputMediaAvaliacao"
value="#{alunoAvaliacaoMB.getMediaAvaliacao(avaliacao.property)}"
</ui:repeat>
</f:facet>
I've also tried
<p:remoteCommand name="refreshFooter" update=":form:outputMediaAvaliacao"/>
If I put
<p:ajax event="change"
update=":form:dataTableAvaliacao:mediaAluno, :form:dataTableAvaliacao" />
in the first way, it works, but I don't wanna update all dataTable every time.
What I'm doing wrong? is it a bug?
Referring on 2nd way from your question that you based on this answer...
actually it is possible to update p:dataTable footer (even from within table itself)...but with one modification of your code.
Reason why your implementation does not work is that you did not take into account that <h:outputText id="outputMediaAvaliacao"../> is wrapped with ui:repeat.
In that case, p:remoteCommand is not able to find h:outputText component ID defined in update attribute because that ID does not exist in DOM:
ui:repeat is actually copying h:outputText as many times as list from value attribute is long and appending all parent IDs to newly created native HTML components
<span id="form:dataTableAvaliacao:avaliacao:0:outputMediaAvaliacao">...</span>
<span id="form:dataTableAvaliacao:avaliacao:1:outputMediaAvaliacao">...</span>
<span id="form:dataTableAvaliacao:avaliacao:2:outputMediaAvaliacao">...</span>
...
(you can see the same using DOM inspector of your favorite browser)
SOLUTION
After you learn and understand all facts stated above (like I did :) ), solution is quite simple:
wrap ui:repeat with some parent element and assign ID to parent element. For example like this
<f:facet name="footer">
<h:outputText value="Nota média da avaliação:"/>
<h:panelGroup id="footerPanel">
<ui:repeat value="#{alunoAvaliacaoMB.colunasAvaliacoes}"
var="avaliacao" id="avaliacao">
<h:outputText id="outputMediaAvaliacao" value="#{alunoAvaliacaoMB.getMediaAvaliacao(avaliacao.property)}" />
</ui:repeat>
</h:panelGroup>
</f:facet>
and modify p:ajax of p:inputText to update newly created element after text is changed
<p:ajax event="change" update=":form:dataTableAvaliacao:footerPanel" />
On this way all children elements of h:panelGroup will be updated (meaning only footer will be updated and not entire table).
And now, after you solved updating, you can focus on designing of all UI elements under h:panelGroup to make them fit your requirements.