I am following the example given here. I have to show CheckBox and RadioButton for a list of Employees, where user can select many CheckBoxs, but only one RadioButton. Just the normal behaviour. I started with Radiobutton first and after running all my radiobuttons are selected automatically.
I have the below index.xhtml page
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:event listener="#{userPreferenceBean.preRender}" type="preRenderView" />
<h:head>
<title>Datatable with Checkbox and RadioButton Example</title>
</h:head>
<h:body>
<h:form>
<p:dataTable id="employeeDataTable" var="employee" value="#{userPreferenceBean.employeeList}"
rowKey="#{userPreferenceBean.employeeDataModel}" paginator="true" rows="10"
selection="#{userPreferenceBean.selectedEmployeeList}">
<f:facet name="header">
Showing employee List
</f:facet>
<p:column selectionMode="single" style="width:2%"></p:column>
<p:column headerText="Name" style="width:48%">
#{employee.name}
</p:column>
<p:column headerText="Department" style="width:48%">
#{employee.department}
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
My Backing bean is:
#ManagedBean
#SessionScoped
public class UserPreferenceBean implements Serializable{
private static final long serialVersionUID = 1L;
private List<Employee> employeeList;
private List<Employee> selectedEmployeeList;
private EmployeeDataModel employeeDataModel;
public void preRender(ComponentSystemEvent ebent){
System.out.println("Inside prerender");
}
#PostConstruct
public void initializeEmployeeList(){
createEmployeeList();
employeeDataModel = new EmployeeDataModel(employeeList);
}
private void createEmployeeList(){
employeeList = new ArrayList<>();
employeeList.add(new Employee("Sudipta",29,"Computer"));
employeeList.add(new Employee("Bunty", 29, "Electrical"));
employeeList.add(new Employee("Pradipta", 24, "Computer"));
}
//Other Getter and Setters
Below is the POJO Class of Employee:
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String department;
//Constructor and Getters+Setters
And this is my DataModel class:
public class EmployeeDataModel extends ListDataModel<Employee> implements SelectableDataModel<Employee>{
public EmployeeDataModel(){
}
public EmployeeDataModel(List<Employee> employees){
super(employees);
}
#Override
public Employee getRowData(String rowKey) {
#SuppressWarnings("unchecked")
List<Employee> employees = (List<Employee>) getWrappedData();
for(Employee employee : employees){
if(employee.getName().equals(rowKey))
return employee;
}
return null;
}
#Override
public Object getRowKey(Employee employee) {
return employee.getName();
}
}
Do you have any idea why all radiobuttons are getting selected automatically and what changes I need to do? Thanks. Attached is the screenshot
You are not using the employeeDataModel properly, your value attribute of the table should be init in the following way
value="#{userPreferenceBean.employeeDataModel}"
and I think you can remove the rowKey attribute
Take a look at the following example DataTable - Instant Row Selection
I don't think it's possible to have a list of radiobuttons where only 1 can be selected and then 1 checkbox to select all the radiobuttons. Normal behavior with radiobuttons is that only 1 can be selected. If you only use checkboxes this is possible, but even then only the displaying page will be selected. You can test this in the showcase.
If I were you I would implement the solution with only the checkboxes.
Finally I am able to solve the problem. The problem was below:
Since my selectionMode was single like
<p:column selectionMode="single" style="width:2%"></p:column>
so I need selection="#{userPreferenceBean.selectedEmployee}" rather than the list of employees.
Now the index.xhtml looks like:
<p:dataTable id="employeeDataTable" var="employee" value="#{userPreferenceBean.employeeDataModel}"
paginator="true" rows="10" selection="#{userPreferenceBean.selectedEmployee}">
<f:facet name="header">
Showing employee List
</f:facet>
<p:column selectionMode="single" style="width:2%" />
<p:column headerText="Name" style="width:48%">
#{employee.name}
</p:column>
<p:column headerText="Department" style="width:48%">
#{employee.department}
</p:column>
</p:dataTable>
And I added the below member in my backing bean.
private Employee selectedEmployee; with getters and setters. Now it is working fine.
Full code is # myGitHubRepo
Thanks.
Related
I've one table embedded into another table. My problem: How to render only the inner table when a row was removed?
Bean:
#Named
#ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = -5633666299306108430L;
private List<String> strLst1;
private List<String> strLst2;
#PostConstruct
public void init() {
strLst1 = Arrays.asList("a", "b", "c");
strLst2 = Arrays.asList("d", "e", "f");
}
public List<String> getStrLst1() {
return strLst1;
}
public List<String> getStrLst2() {
return strLst2;
}
public void removeFromStrLst2(String val) {
strLst2.remove(val);
}
}
Facelet:
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form id="form">
<h:dataTable
id="outerTable"
var="str1"
value="#{testBean.strLst1}"
border="1">
<h:column>
<h:panelGroup id="innerTableContainer">
<h:dataTable
id="innerTable"
var="str2"
value="#{testBean.strLst2}"
border="1">
<h:column>
<h:outputText value="#{str1}: #{str2}" />
</h:column>
<h:column>
<h:commandButton
id="removeButton"
action="#{testBean.removeFromStrLst2(str2)}"
value="RemoveFromStrLst2">
<f:ajax render="innerTableContainer" /> <!-- Problem location -->
</h:commandButton>
</h:column>
</h:dataTable>
</h:panelGroup>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
My problem is the Ajax-render attribute which doesn't get the correct id (examples for the first row):
innerTableContainer leads to mojarra.ab(this,event,'action',0,'innerTableContainer') It doesn't work!
innerTable leads to mojarra.ab(this,event,'action',0,'form:outerTable:0:innerTable:0') It doesn't work!
#parent leads to mojarra.ab(this,event,'action',0,'form:outerTable:0:innerTable:0:j_idt14') It doesn't work!
#namingcontainer leads to mojarra.ab(this,event,'action',0,'form:outerTable:0:innerTable:0') It doesn't work!
#form works but this isn't I was looking for.
The correct and working id would be form:outerTable:0:innerTableContainer but how to get it?
Mojarra 2.3.9.SP01
I thought I'd try and get a primefaces datagrid working with my JSF code, but I always got "no results found". So I'm trying to set up a simple example but I get the same error messages so I must be doing something fundamentally wrong.
I have the following backing bean:
#ManagedBean
#ViewScoped
public class CarBean {
private static final Logger logger = Logger.getLogger("datagrid.ejb.CarBean");
private List<Car> cars;
public CarBean() {
cars = new ArrayList<Car>();
cars.add(new Car("myModel",2005,"ManufacturerX","blue"));
logger.log(LogLevel.INFO, "added car");
//add more cars
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
}
And the following xhtml page:
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<p:dataGrid var="car" value="#{carBean.cars}" columns="3"
rows="12"layout="grid">
<p:column>
<p:panel header="#{car.model}">
<h:panelGrid columns="1">
<p:graphicImage value="/images/cars/#{car.manufacturer}.jpg"/>
<h:outputText value="#{car.year}" />
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
</h:body>
</html>
I can see from the logs and debugger that the CarBean is instantiated but still I get the no records found error. Any ideas?
Thanks,
Zobbo
I currently have a primefaces datatable table with a conditional delete button that will delete the row if clicked. Clicking on it the first time works. It would delete the row and the table will be refreshed with the new table. When I try to delete something from the table again, the table would refresh itself with no entries. If I update the table using one of the buttons that I created, the table would show up again with the entry that I tried to delete still there. Looking into it, I see that the method in action is being called when I deleted the first one successfully. However, when I try it again, the method is not being invoked. Why isn't it?
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:dataTable id="carTable" var="car" value="#{dtBasicView.cars}">
<f:facet name="header">
Car Table
</f:facet>
<p:column headerText="Id" sortBy="#{car.id}">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year" sortBy="#{car.year}">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand" sortBy="#{car.brand}">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color" sortBy="#{car.color}">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Delete Option">
<p:commandLink action="#{dtBasicView.deleteCar(car)}"
update="#form" rendered="#{car.isWhite}" value="Delete" ajax="true">
</p:commandLink>
</p:column>
</h:form>
</h:body>
</html>
And the bean
#ManagedBean(name="dtBasicView")
#ViewScoped
public class BasicView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Car selectedCar;
private List<Car> cars;
private List<Car> oneHundredCars;
private int numberOfcars=0;
#ManagedProperty("#{carService}")
private CarService service;
#PostConstruct
public void init() {
oneHundredCars = service.createCars(100);
}
public void setNumberOfcars(String num) {
this.numberOfcars = Integer.parseInt(num);
cars = oneHundredCars.subList(0, numberOfcars);
}
public List<Car> getCars() {
return cars;
}
public void setService(CarService service) {
this.service = service;
}
public Car getSelectedCar() {
return selectedCar;
}
public void setSelectedCar(Car selectedCar) {
this.selectedCar = selectedCar;
}
public boolean getIsEmpty() {
return cars == null || cars.isEmpty();
}
public void deleteCar(Car car) {
cars.remove(car);
int size = cars.size();
setNumberOfcars(""+size);
}
}
A little update: I still haven't fixed my problem. I have shifted some things around so that the list is not resizeable. Now whenever I click on the second delete commandlink, the whole datatable gets refreshed with new random data.
Another update: It appears as if it is calling the #PostConstruct again after hitting the second delete. By doing so, it is recreating a whole new set of arrays of cars.
After spending the whole day yesterday trying to figure out why this is happening, I have finally fixed it. I have changed the commandlink to commandbutton and neither of those changes worked. What worked for me was instead of letting the button be an ajax submit, it would instead be a non-ajax submit. I still do not know why this worked, so if anyone can explain it would be greatly helpful.
Sample.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:event listener="#{sample.dosamplelist}" type="preRenderView" />
</h:head>
<h:body>
<h:form>
<h:panelGrid id="samplesetting" columns="6" cellpadding="5">
<f:facet name="header">Name Setting</f:facet>
<h:outputLabel for="samplename" value="Name:" />
<p:inputText value="#{sample.name}" id="samplename"
required="true" label="samplename" />
</h:panelGrid>
<p:panel id="sampleview" header="Sample List">
<p:dataTable var="spl" value="#{sample.samplelist}" rowKey="#{spl.name}"
selection="#{sample.selectedname}"
selectionMode="single">
<p:column headerText="Name">
<h:outputText value="#{spl.name}" />
</p:column>
<p:column>
<p:commandButton id="one" value="View Details" action="#{sample.setSelectedsample(spl)}" update="#form:samplesetting">
</p:commandButton>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
Managed Bean
#SuppressWarnings("serial")
#ManagedBean(name = "sample")
#RequestScoped
public class Sample implements Serializable
{
private String name;
private List<Sample> samplelist;
private String selectedname;
//getters and setters
public void dosamplelist(ComponentSystemEvent event)
{
List<Sample> samplelist = new ArrayList<Sample>();
Sample configA = new Sample();
configA.setName("John");
samplelist.add(configA);
Sample configB = new Sample();
configB.setName("David");
samplelist.add(configB);
this.samplelist = samplelist;
}
public void setSelectedsample(Sample smpl)
{
this.name = smpl.name;
}
}
This is the sample of little big form, and the need is, when we select the table row from the bottom, it will be display to top input box for editing purpose.
But when I press the command button it do not work. why? and what is the reason please?
Possible Problem
One obvious problem is that at the class level, you've defined:
private List<Sample> samplelist;
Then you go ahead and hide the variable in doSampleList with
List<Sample> samplelist = new ArrayList<Sample>();
Combined with the fact that you have your bean marked as #RequestScoped, it will guarantee that the content of the samplelist will not be consistent during the JSF request processing.
To Solve:
Mark your bean as #ViewScoped instead and resolve the variable hiding problem as you see fit.
Further reading:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
I am trying to update the page size of a PrimeFaces datatable dynamically, after the datatable is displayed on the page but I can't seem to be able to do that. I am using a lazy loaded datatable if that matters... putting an EL expression in the rows attribute and doing a table refresh does not work and causes the paginator to return no data.
Any ideas if this is a bug and how to fix it?
Thanks
You need not refresh or update the datatable. Use EL expression in rowsPerPageTemplate attribute of <p:dataTable> and after loading datatable just change the rows number.
<p:dataTable value="#{managedBean.users}" var="user" lazy="true" paginator="true" rows="10" rowsPerPageTemplate="10,25 #{fn:length(managedBean.users)}">
And include this xmlns:fn="http://java.sun.com/jsp/jstl/functions" in page.
What exactly are you trying to do? This works for me (Mojarra 2.1.26, PrimeFaces 3.5):
#ManagedBean
#ViewScoped
public class Bean {
public class Item {
private String name;
public Item(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private List<Item> items;
public Bean() {
Item item1 = new Item("item1");
Item item2 = new Item("item2");
items = Arrays.asList(item1, item2);
}
public List<Item> getItems() {
return items;
}
private int tableSize = 1;
public int getTableSize() {
return tableSize;
}
public void actionSwitchSize() {
tableSize = tableSize == 1 ? 2 : 1;
}
}
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:form>
<p:dataTable id="table" var="item" value="#{bean.items}"
rows="#{bean.tableSize}" paginator="true">
<p:column>
#{item.name}
</p:column>
</p:dataTable>
<p:commandButton value="switch size" action="#{bean.actionSwitchSize}"
update="table" />
</h:form>
</h:body>
</html>