i have a problem with the datatable component. I want to create a datatable with checkbox like a multiple selection example on primefaces showcase. This is the code:
<p:dataTable id="table_cats" value="#{fooBean.catsList}" var="cat" selectionMode="single" selection="#{fooBean.selectedCatsToDelete}">
<p:column selectionMode="multiple">
<f:facet name="header">Remove</f:facet>
</p:column>
<p:column>
<f:facet name="header">Cat Name</f:facet>
<h:outputText value="#{cat.name}" />
</p:column></p:dataTable>
So, the problem is when a select an item. I don't know how to get all the selected items in the table. Can anyone help me with this problem?
They are all set in the property behind #{fooBean.selectedCatsToDelete} and they are thus accessible in any action/listener method which you have hooked to some command link/button.
E.g.
<p:commandButton value="Remove" action="#{bean.remove}" />
with
public void remove() {
someService.remove(selectedCatsToDelete); // JSF has already put the selected items in selectedCatsToDelete.
}
It's not quite clear what your comment means "this example doesn't work". Are there any errors? Or is selectedCatsToDelete empty?
First guess would be the selectionMode="single" in your <p:dataTable> versus selectionMode="multiple" in the column.
Try to remove the attribute from your table tag.
Related
I want to show a list of key-value pairs in a datatable, where each pair is one row, inside an overlay panel. When a key-value pair is clicked, i want to update a <p:inputText>-Element, which is OUTSIDE the overlaypanel with the key-value of the selected row and simultaniously close the overlaypanel.
I just migrated from PF 4.0 to PF 6.1 and now im facing the issue, that whenever i use an update-attirbute inside the overlay panel, it appears to be empty and no content is shown.
here is an code example:
<p:inputText
id="inputPvId"
styleClass="form_input"
readonly="true"
value="#{bean.selectedValue.get(0)}" />
<p:commandButton
icon="ui-icon-link"
id="selectValue"
value="#{msg_properties.chooseValue}" />
<p:overlayPanel
for="selectValue"
id="overlayValueSelector"
widgetVar="overlayValueSelector
dynamic="true"
styleClass="form_input_widest">
<p:dataTable
var="car"
value="#{dtBasicView.cars}">
<p:column
headerText="Id">
<h:outputText
value="#{car.id}" />
</p:column>
<p:column
headerText="Year">
<h:outputText
value="#{car.year}" />
</p:column>
<p:ajax
event="rowSelect"
update=":form:inputPvId,:form:myTable"
onsuccess="PF('overlayPV').hide()" />
</p:dataTable>
Previously it worked that way. All I changed is the way the Widget gets called from "overlayPV".hide()" to "PF('overlayPV').hide()" as the official Migration Guide suggested. If out cancel out the update=":form:inputPvId,:form:myTable" line in the ajax call, the content is shown properly.
Am I doing somethign wrong? My research showed, that other people also had trouble with the overlaypanel and the ajax update. However, i found no suitable solution for my problem.
I tried using the "onRowClick"-Attribute of the datable along with the widgetHide call like this:
<p:dataTable
onRowClick="PF('overlayPV').hide()" />
and it worked fine, however i could not figure out how to update the <p:inputText>-Element with the choosen value. I had to refresh the page to show the new value. I would be happy if someone suggested a solution for this. Thanks in advance.
I finally resolved the issue.
My initial problem was, that whenever an element inside the <p:overlayPanel> included the "update" attribute, the overlayPanel did not render any content and appeared empty.
i solved my issue with the <p:remoteCommand>-Tag, which I placed OUTSIDE of the overlayPanel as my example Code below shows:
<p:inputText
id="inputPvId"
styleClass="form_input"
readonly="true"
value="#{bean.selectedValue.get(0)}" />
<p:commandButton
icon="ui-icon-link"
id="selectValue"
value="#{msg_properties.chooseValue}" />
<p:overlayPanel
for="selectValue"
id="overlayValueSelector"
widgetVar="overlayValueSelector
dynamic="true"
styleClass="form_input_widest">
<p:dataTable
var="myTable"
value="#{dtBasicView.cars}"
onRowClick="remoteCommand()">
<p:column
headerText="Id">
<h:outputText
value="#{car.id}" />
</p:column>
<p:column
headerText="Year">
<h:outputText
value="#{car.year}" />
</p:column>
</p:dataTable>
</p:overlayPanel>
<p:remoteCommand
name="remoteCommand"
update="inputPvId, myTable"
onsuccess="PF('overlayPV').hide()"/>
Note the onRowClick-Attribute of my dataTable which call the remoteCommand outside of te overlayPanel. The remoteCommand than updates all my Elements that need to be updated and also closes the overlayPanel.
I have a table in Primefaces with a single selection. After the user selects an entry of that table, the whole form should be submitted. I could use a commandbutton to sumbit, but I don't want the user to do this, cause the selection is the last and final step of the form.
<p:dataTable value="#{bean.selectedItems}" var="selItem"
selection="#{bean.selectedItem}"
rowKey="#{selItem.id}"
selectionMode="single"
id="selectedTbl">
<p:ajax event="rowSelect" listener="#{bean.onSelectListener}"/>
<p:column selectionMode="single"/>
...
<p:dataTable/>
The ajax listener as well as the set method of the selectedItem is called, but how do I trigger a submit from ajax?
Update: More detailed example
Case: Only one person per group can be enabled. The user has to decide based on many information in a table. And sometimes the user has to do this very often.
<h:form>
<p:selectOneMenu value="#{bean.group}" valueChangeListener="#{bean.onGroupChange}">
<f:selectItem itemLabel="Select..." noSelectionOption="true"/>
<f:selectItems value="#{bean.groups}"/>
<p:ajax update="selectedTbl"/>
</p:selectOneMenu>
<p:dataTable value="#{bean.selectedItems}" var="selItem"
selection="#{bean.selectedItem}"
rowKey="#{selItem.id}"
selectionMode="single"
id="selectedTbl">
<p:ajax event="rowSelect" listener="#{bean.onSelectListener}"/>
<p:column selectionMode="single"/>
<p:column headerText="ID">
<h:outputText value="selItem.id"/>
</p:column>
<p:column headerText="Name">
<h:outputText value="selItem.name"/>
</p:column>
<!--Some more Information about the person, based on the the user makes a decision.-->
<p:dataTable/>
<!--only one User per Group can be enabled-->
<p:commandButton value="Enable" action="#{bean.enableSelected}" onclick="submit()"/>
</h:form>
bean:
public void enableSelected(){
manager.modifyPerson(selectItem);
selectedItems.clear();
selectedItem = null;
group = null;
}
public void onSelectListener(SelectEvent event){
selectedItem = (Person) event.getObject();
}
The bean is pretty simple only getter and setter. The onGroupChange Method loads new values for selectItems from the db.
I want to get rid of the commandbutton and move the functionality from enableSelected to onSelectListener. When I move the db-Function to enableSelected it works but the page isn't refreshed.
When I add update="#form" to ajax it doesn't work so I wanted to use submit().
Try to add process="#form" in your ajax.
<p:ajax event="rowSelect" process="#form" listener="#{bean.onSelectListener}"/>
I have p:dataTable, inside column I have a panelGrid where i want the value of the ouputText on the click of the panelGrid without page refresh. The code is something like:
<p:column headerText="5/5" style="width:40px; font-size:9pt;">
<p:panelGrid>
<p:ajax event="click" listener="#{myBean.showSelectedValue(row)}" update=":mainForm"/>
<h:outputText value="#{row.value1}" />
</p:panelGrid>
</p:column>
</p:dataTable>
<h:panelGrid id="ForecastChartTab">
<h:outputText id="value1" value="#{myBean.showValue.value1}" />
</h:panelGrid>
This is working, but the value is seen only on page refresh...! is something wrong here? :(
If you need to update the table, you can use the following
update="#([id$=dtTableId])"
If you need to update the output text you need use the following
update="#([id$= value1])"
With this type of format #([id$= value1]), you can update another component out of the behavior of others.
In my p:datatable, there is a column named Resolution, consisting of a check box and text. If the box is checked, the text is Resolved, If the box is not checked, then text is Unresolved. I also have a filter box defined for this column so only Resolved or Unresolved entries are shown.
If I filter on Resolved, then uncheck the box, the entry is now Unresolved, but it is still showing up. It shouldn't, because it no longer satisfies the filter. My question is how do I force filter() to execute after the last f:ajax render ?
Here is my code snipet:
<p:dataTable id="measurementHistoryTableId"
value="#{measurements.measurementHistoryList}"
var="meas3"
dynamic="true">
<p:column id="resolutionColumn"
filterBy="#{meas3.resolution}"
filterOptions="#{measurements.measurementHistoryOptions}"
sortBy="#{meas3.resolution}" >
<f:facet name="header">
<h:outputText value="#{msgs.MeasurementResolution}" />
</f:facet>
<h:selectBooleanCheckbox value="#{meas3.resolved}" >
<f:ajax event="click" execute="#all" render="resolutionId #this" />
</h:selectBooleanCheckbox>
<h:outputText id="resolutionId" value="#{meas3.resolution}" />
</p:column>
</p:dataTable>
I tried render=#all, but that didn't help. render=#form gives me jQuery.datepicker undefined. I tried to add 'onclick=widget_measurementHistoryTableId.filter()' to the 'h:selectBooleanCheckbox' , but it causes the filter to fire before the 'f:ajax' is executed.
Thanks for any help you could give me.
Binh
I don't know how primefaces filtering works but, if the onclick=widget_measurementHistoryTableId.filter() works and you jsut want it to be fired after the ajax event, you can do it like this:
<f:ajax event="click" execute="#all" render="resolutionId #this"
onevent="reapplyFilter"/>
And then define the reapplyFilter js function:
function reapplyFilter(e) {
if (e.status == 'success') {
widget_measurementHistoryTableId.filter();
}
}
There is business need to categorize items. Best idea seems to be dragdrop items from one list into list of categories. Number of categories can vary so p:dataTable is used.
Ajax request is sent but onDrop method is not called from inside dataTable. When Removing datatable and column and having outputpanels statically then onDrop is called?
How to best drag and drop items into dynamically changing categories?
<h:form prependId="false">
<h:panelGrid columns="2">
<p:dataTable id="itemstable" value="#{categoryBean.items}" var="item">
<p:column>
<p:outputPanel id="itemrow">
<h:outputText value="#{item}"></h:outputText>
</p:outputPanel>
<p:draggable for="itemrow"></p:draggable>
</p:column>
</p:dataTable>
<p:dataTable value="#{categoryBean.categories}" var="cat">
<p:column>
<p:outputPanel id="cats1">
<h:outputText value="category1"></h:outputText>
</p:outputPanel>
<p:droppable for="cats1"
dropListener="#{categoryBean.onDrop}"
tolerance="pointer"
activeStyleClass="slotActive"
datasource="itemstable">
</p:droppable>
</p:column>
</p:dataTable>
</h:panelGrid>
</h:form>
There is a bug in PrimeFaces, when <p:droppable> is nested in any data repeating element the dropListener does not get called. I also tried using the Facelets repeat tag <ui:repeat> but the dropListener was not called just like dragging to the <p:dataTable> .
In the PrimeFaces showcase all of the drag an drop examples have static droppable areas.
PrimeFaces ShowCase