I was trying to "link" <p:ajax event="rowSelect"> and <p:ajax event="rowUnselect"> with <h:selectBooleanCheckbox> so when datatable row is selected, the checkbox would check together and when checkbox is checked, datatable row is selected too.
Problem for now: I can save the state of the checkbox when going to another pagination page but I need to check checkbox then select row then only it will save the state. If I tried to check only checkbox and go to other pagination page, it won't save the state when I come back to the pagination page but if I select row and go to other pagination page, it would save the state. If I select row and check checkbox and go to another pagination page, it won't save the state too. Any idea how to check checkbox and select row when either 1 is clicked and can save state if go to another pagination page?
<p:dataTable value="#{machine.sub}" var="subDir"
id="fileDirectories" rowClasses="row1-whitebg,row2-bluebg"
selectionMode="multiple" selectionPageOnly="false"
rowKey="#{subDir.directory.path}" headerClass="title-column"
rowIndexVar="idx" rows="10" rowsPerPageTemplate="10,20,50" paginator="true"
paginatorAlwaysVisible="false"
paginatorTemplate="#{WebConstant.PAGINATOR_TEMPLATE}">
<p:ajax event="rowSelect" listener="#{machine.selectedRow}"/>
<p:ajax event="rowUnselect" listener="#{machine.unSelectedRow}"/>
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['machine_download']}"/>
</f:facet>
<h:panelGroup id="panelGroupChkSelect">
<h:selectBooleanCheckbox id="chkSelect" value="#{subDir.selected}"
rendered="#{subDir.directory.file}">
<c:if test="#{machineLogExplorerPage.checkButton()}">
<f:attribute name="checked" value="checked"/>
</c:if>
</h:selectBooleanCheckbox>
</h:panelGroup>
</p:column>
</p:dataTable>
Java code
private boolean checked;
public void selectedRow() {
checked = true;
}
public void unSelectedRow() {
checked = false;
}
public boolean checkButton() {
return checked;
}
You don't need to implement the checkbox yourself. Just add a selection column like:
<p:column selectionMode="multiple"/>
To keep track of what is selected use:
<p:dataTable selectionMode="multiple"
selection="#{bean.listOfSelectedItems}"
...>
See:
https://www.primefaces.org/showcase/ui/data/datatable/selection.xhtml
https://primefaces.github.io/primefaces/11_0_0/#/components/datatable?id=multiple-selection-with-checkboxes
Related
I have scenario where i need to validate series selection of rows in datatable . I need to enable button when the rows are selected in series and disabled when the are not selected in series.
Disable Button
Enable Button
XTML
<p:dataTable id="listStackFormTable" var="stackLine"
scrollRows="80" scrollable="true" rowIndexVar="rowIndex"
value="#{stackEditBean.listStackLineForm}"
selection="#{stackEditBean.stackLinesSelected}"
sortBy="#{stackLine.serialNo}" editingRow="cell" editable="true"
rowKey="#{stackLine}"
styleClass="table-f no-h-scroll stack-Listing">
<p:ajax event="toggleSelect"
listener="#{stackEditBean.rowSelect}"
update="listStackFormTable" process="#this"></p:ajax>
<p:ajax event="rowSelect" listener="#{stackEditBean.rowSelect}"
update="listStackFormTable" process="#this" />
<p:ajax event="rowSelectCheckbox"
listener="#{stackEditBean.rowSelect}"
update="listStackFormTable" process="#this"></p:ajax>
<p:ajax event="rowUnselectCheckbox"
listener="#{stackEditBean.rowUnSelect}"
update="listStackFormTable" process="#this"></p:ajax>
</p:dataTable>
Java
private List<StackLineForm> stackLinesSelected;
private List<StackLineForm> listStackLineForm;
public void rowSelect(SelectEvent event) {
StackLineForm selectedRow = (StackLineForm) event.getObject();
List<StackLineForm> list = new ArrayList<StackLineForm>();
for (StackLineForm form : this.stackLinesSelected) {
list.add(form);
form.setSelectedStackLineFlag(true);
}
this.getDimHarvestBackingBean().setListSelectedDim(list);
this.setStackLinesSelected(list);
}
public void rowUnSelect(UnselectEvent event) {
StackLineForm selectedRow = (StackLineForm) event.getObject();
List<StackLineForm> list = this.stackLinesSelected;
for (StackLineForm form : this.stackLinesSelected) {
if (selectedRow.getSaKey().equals(form.getSaKey())) {
selectedRow.setSelectedStackLineFlag(false);
list.remove(selectedRow);
}
}
this.getDimHarvestBackingBean().setListSelectedDim(list);
this.setStackLinesSelected(list);
}
Just put an ajax event handler for rowUnselectCheckbox and rowSelectCheckbox, and enable/disable the button in the scenario you want.
<p:ajax event="rowSelectCheckbox" listener="#{bean.eventListener}" />
<p:ajax event="rowUnselectCheckbox" listener="#{bean.eventListener}" />
Give your dataTable's selection attribute a new list, the same type of your current list.
put 4 ajax in your dataTable with listener and update, in listeners check two lists to see if your condition is met, put it in a boolean and use it in the disabled attribute of your buttons. don't forget to update the buttons with client id if they're in another form.
<p:dataTable id="datalist"
value="#{bean.items}" var="item"
selection="#{bean.selectedItems}
editable="true"
editMode="cell"
rowKey="#{item.id}">
<p:ajax event="rowSelect" update="form:disabledBtn form:enabledBtn" listener="#{bean.setBtnDisabled()}"/>
<p:ajax event="rowUnselect" update="form:disabledBtn form:enabledBtn" listener="#{bean.setBtnDisabled()}"/>
<p:ajax event="rowSelectCheckbox" update="form:disabledBtn form:enabledBtn" listener="#{bean.setBtnDisabled()}"/>
<p:ajax event="rowUnselectCheckbox" update="form:disabledBtn form:enabledBtn" listener="#{bean.setBtnDisabled()}"/>
<p:column selectionMode="multiple"/>
you can also do the boolean check, client side with javascript, I don't remember much but the general idea is like, take the dataTable dom in your ajax oncomplete, cycle through the children and check for elements with selected class and check your boolean in there, disable your buttons whether with css and pointer-event or with a remoteCommand to switch your boolean. (its the general idea, there're a little more details).
I have a need to display a list of Strings on a page, which a user will need to be able to add, edit, and delete entries. I figured I would use a DataTable to accomplish this.
The page appears to work properly - values are displayed in the DataTable, rows are deleted when the Delete icon is clicked, and rows are added when the Add button is clicked. However, when engaging the RowEditor by clicking the pencil icon, changes are never reflected when clicking the checkmark; the value of the row just goes back to being blank.
Here is a GIF showing the problem happening - http://imgur.com/a/dxlht
I've copied the majority of the DataTable markup from other pages in my project, which all work properly. The only difference I can see here is that this is a DataTable of Strings, not a complex object. Does this affect the "input" facet of the RowEditor when the value of the InputText is just a simple String?
Here is the DataTable markup:
<h:form>
<p:dataTable id="configTable" value="#{bean.configs}" var="config"
editable="true" editMode="row" emptyMessage="No entries exist.">
<p:column>
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{config}" /></f:facet>
<f:facet name="input"><p:inputText value="#{config}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
<p:column>
<p:commandLink update="configTable" styleClass="ui-icon ui-icon-trash" process="#this"
actionListener="#{bean.removeEntry(config)}" />
</p:column>
<f:facet name="footer">
<p:commandButton value="Add Entry" update="configTable" icon="ui-icon-plus" style="float:right;" process="#this"
actionListener="#{bean.addEntry()}" />
</f:facet>
</p:dataTable>
</h:form>
Here is the relevant bean code:
private List<String> configs;
public List<String> getConfigs() {
return this.configs;
}
public void setConfigs(List<String> configs) {
this.configs = configs;
}
public void removeEntry(String entry) {
this.configs.remove(entry);
}
public void addEntry() {
this.configs.add("");
}
I am using PrimeFaces 5.3/JSF 2.0.
Please note that when you press the check mark (to finish editing a row) JSF calls the setter method of whatever class your table rows are.
String class doesn't have a setter method, thus you will need to create a wrapper class with just one field (with getter and setter) and change your configs object to a List of yourClass objects.
I have a primefaces datatable with multiple checkbox selection and I can't find a way to check if there is at least one item selected using postValidate event
xhtml
<p:dataTable
var="item"
value="#{myBean.list}"
selection="#{myBean.selectedItems}">
<p:column selectionMode="multiple" />
<p:column>
<f:facet name="header">
<h:outputText value="Item" />
</f:facet>
<h:outputText value="#{item.value}" />
</p:column>
<f:event listener="#{myBean.isSelectedItem}" type="postValidate" />
</p:dataTable>
My Bean
public void isSelectedItem(ComponentSystemEvent event) {
HtmlDataTable table = (HtmlDataTable) event.getComponent();
//no idea how to get checkboxes inside datatable
}
How can I get elements inside datatable ?
I think that you can do it using your back bean method by checking if the selection list "selectedItems" contains values or not.
Working with the next table, I am not able to fire the listener when I select a row clicking the checkbox.
Does somebody know what I am doing wrong?
Thanks!
<p:dataTable
var="department" value="#{departmentCtrl.departmentTable}"
selection="#{departmentCtrl.departmentList}">
<p:ajax event="rowSelectCheckbox" listener="#{departmentCtrl.departmentSelected}" />
<p:column selectionMode="multiple" />
<p:column headerText="#{msgs.id}">
<h:outputText value="#{department.id}" />
</p:column>
<p:column headerText="#{msgs.name}">
<h:outputText value="#{department.name}" />
</p:column>
</p:dataTable>
public void departmentSelected(SelectEvent event) {
//This method never executes ¿?
}
I want to do the same as in the Checkbox Based Selection sample (http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionRadioCheckbox.jsf); but working with the rowSelectCheckbox and rowUnselectcheckbox events as stated in the documentation (pg 141 of Primefaces USER’S GUIDE v3.3)
[SOLVED]
In the manage bean I change from:
List departmentList;
to
Department[ ] departmentList;
I have a p:datatable with multiple selection mode and a paginator.
<p:datatable value=#{rows} selection=#{selectedRows} pagintor="true" rows="20" rowsPerPageTemplate="10,20,50,100" paginatorPosition="bottom">
<p:column selectionMode="multiple"/>
<p:ajax event="toggleSelect"/>
... columns ...
</p:datatable>
When i click the header checkbox all rows are selected. When i click on the header checkbox to select all rows and then want to export the selected rows (by using the values of 'selection'), it only returns 20 objects. I expect that when i use the header checkbox it selects all rows of the datatable, and not only the one of the page. I have a datatable with more then 200 pages, so you can imagine it is a very tedious job to export all of the when using a paginator ;).
I suppose it is a bug I should log, or am I missing something? I looked through the documentation but it says nothing about using multiple selection mode together with pagination... Thanks for your feedback!
I had the exact same requirement - select all rows across pages.
What I did - provided an <p:inputSwitch /> to toggle all rows across all the pages.
Copied and is as below -
<p:dataTable id="id" var="var" widgetVar="wvar" rowsPerPageTemplate="7,15" reflow="true"
value="#{backingBean.dataModel}" paginator="true" rows="7" rowIndexVar="index" rowKey="#{var.id}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
selection="#{backingBean.selectedItems}">
<c:facet name="header"...
<p:inputSwitch value="#{backingBean.allRecords}" onLabel="All" offLabel="None" >
<p:ajax onstart="if (PF('wvar').getSelectedRowsCount() == 0) PF('wvar').selectAllRows(); else PF('wvar').unselectAllRows();" />
</p:inputSwitch>
private boolean allRecords;//Getter++Setter++
And, defined toggleSelect event as below -
<p:ajax event="toggleSelect" onstart="if (PF('wvar').getSelectedRowsCount() == 7 || PF('wvar').getSelectedRowsCount() == 15) PF('wvar').selectAllRows(); else PF('wvar').unselectAllRows();" />
where 7 and 15 comes from the datatable rowsPerPageTemplate="7,15".
Works for me.(PrimeFaces 5.3)
FOR JSF 2 ,for selected all rows on datatable in selectionMode multiple with paginator=true:
In Page
<p:dataTable widgetVar="tableArea" yourtags...>
<p:ajax event="toggleSelect" oncomplete="teste()" /> /// toggleSelect is dispared on click to checkbox header
<p:column id="columnId" selectionMode="multiple"/>
In js:
function teste(){
var checked = $(document).find(":checkbox")["0"].checked; ///Find checkbox header and verify if checkbox is checked
if(checked == true){
PF('tableArea').selectAllRows(); // if true, selectAllRows from datatable
} else {
PF('tableArea').unselectAllRows(); //
}
}
Sample Code:-
**JAVA (your backing bean class)
==============================**
//Stores the checked items from data table.
private List<String> selectedIds = new ArrayList<>();
private List<String> getSomeList() {
// return list of strings to data table
return someList;
}
public void selectAllCheckboxes(ToggleSelectEvent event) {
if (selectedIds != null) {
selectedIds.clear();
if (event.isSelected()) {
selectedIds.addAll(someList); //Add all the elements from getSomeList()
}
}
}
**XHTML
=====**
<p:dataTable id="data-table-id" value="#{backingBean.someList}"
selection="#{backingBean.selectedIds}" rowKey="#{id}" var="id"
paginator="true" rows="10" paginatorPosition="bottom"
paginatorAlwaysVisible="false" rowSelectMode="checkbox"
rowsPerPageTemplate="10,20,30,50">
<p:column selectionMode="multiple" />
<p:ajax event="toggleSelect"
update="#this"listener="#backingBean.selectAllCheckboxes}"/>
</p:dataTable>
I expect that when i use the header checkbox it selects all rows of the datatable, and not only the one of the page.
This is a wrong expectation.
I suppose it is a bug I should log,
Nope.
or am I missing something?
No, it is by design. So other than having the wrong expectation you did not miss anything. The fact that you are the first one in SO to ask this and the second one if you count the number of requests in the PrimeFaces forum to is an indication of this.
Not even GMail does this btw. They give you the option to select all message on the page you are on, and when you do this they give you an additional option to select all messages across all pages