Hi i am new to JSF & Primefaces. I've been stuck for two days trying to persist dynamically selected check-values to DB.
I'm successfully displaying check-boxes using labels from DB using 3 tables:
First table: DEM_checkbox which contains checkbox ID, label
Second table: DEM_checkboxval which contains fileid, checkbox_id, value
Third table: DEM_folder where all files save in table format in database
I've used separate mappers, services and classes for table.
This is my xhtml code:
<ui:repeat value="dossierBean.dossier.dui.demCheckBoxList" var="c">
<h:panelGrid columns="2" columnClasses="LeftColumn,LeftColumn">
<h:selectBooleanCheckbox value="#{c.checkboxlabel}" styleClass="benefSelection" />
<h:outputText value="#{c}" styleClass="subSectionTitle" />
</h:panelGrid>
</ui:repeat>
I'm using this loop to save selected values:
public List<DEMCheckBoxUI> getDemCheckBoxList() {
if (demCheckBoxList==null){
demCheckBoxList = new ArrayList<DEMCheckBoxUI>();
for (DEMCheckboxes cblabel :dossier.getDemCheckBoxList()){
DEMCheckBoxUI cbui = new DEMCheckBoxUI();
cbui.setLabel(cblabel);
List<String> valueList = services.getDemCheckboxValueService().getCheckboxValue(dossier.getId(), cblabel.getCheckboxlabel());
DEMCheckboxesValue cbvalue = new DEMCheckboxesValue();
cbvalue.setDossier(dossier.getId());
cbvalue.setId(cblabel.getId());
cbvalue.setValue(valueList.get(0));
cbui.setCboxvalue(cbvalue);
demCheckBoxList.add(cbui);
}
}
return demCheckBoxList;
}
Labels are retrieved from DB via DENCheckboxes.java
Saved values are inserting via DEMCheckboxesVal
DemcheckboxUI is UI code looks like:
public class DEMCheckBoxUI {
private DEMCheckboxes label;
private DEMCheckboxesValue cboxvalue;
public DEMCheckboxesValue getCboxvalue() {
return cboxvalue;
}
public void setCboxvalue(DEMCheckboxesValue cboxvalue) {
this.cboxvalue = cboxvalue;
}
}
To save to database i am using the below code:
demCheckboxService = DossierManager.getCurrent().getDemCheckboxService();
if (dossier != null) {
dossier.setDemCheckBoxList(demCheckboxService.getCheckboxesList());
if (PgzTools.notEmpty(dossier.getId())) {
reloadDossier(dossier.getId());
}
}
I think there is a problem in the loop.
It would be help if anyone give suggestion or other method to fix.
Related
This question already has answers here:
How can I pass selected row to commandLink inside dataTable or ui:repeat?
(4 answers)
Closed 7 years ago.
I am new to java ee and dont have much idea about jsf and all. I am making a simple java web application that fetches data from database and shows in dataTable. I need to edit data selected by user from dataTable for which i need to get value of the row selected/clicked. But i havent been able to do it. Can any one please help me with my code ? I hope someone would tell me how can i do it with my following codes.
showRecords.xhtml
h:dataTable value="#{studentList.studentL()}" var="student" styleClass="studentTable"
columnClasses=",,,fixedWidth">
<h:column>
<f:facet name="header">Student ID</f:facet>
<h:outputText value="#{student.studentId}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">Name</f:facet>
<h:outputText value="#{student.fname}"></h:outputText>
</h:column>
Student.java
#ManagedBean(name="student")
public class student {
#Id private String StudentId;
private String Fname, Lname, Mname="noname";
/*******getters and setters** and database transaction****/
}
studentList.java
#ManagedBean(name="studentList")
#SessionScoped
public class studentList {
public List<student> studentL(){
List<student> list = new ArrayList<student>();
PreparedStatement ps = null;
ResultSet rs = null;
Connection con = null;
try{
Class.forName("org.apache.derby.jdbc.ClientDriver");
con = DriverManager.getConnection("jdbc:derby://localhost:1527/tourManager","administrator","pass");
String sql = "Select * from student";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()){
student student1 = new student();
student1.setFname(rs.getString("FNAME"));
student1.setLname(rs.getString("LNAME"));
student1.setStudentId(rs.getString("STUDENTID"));
list.add(student1);
// return list;
}
}catch(Exception e){
e.printStackTrace();
}
return list;
}
public void editStudent() throws IOException{
int index = Integer.parseInt(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("index").toString());
System.out.println(" the selected row is "+index);
}
}
You can pass a parameter using expression language.
In your bean, have a function like
public void editStudent(String studentId)
{
// do something with id
}
Now, using expression language, you can call that method using #{yourbean.editStudent('id')}
Since you are iterating through your data using a datatable, you can access the student's id from the var variable.
<h:dataTable value="#{studentList.studentL()}" var="student" ...>
...
<h:commandButton value="Edit" action="#{studentList.editStudent(student.studentId)}" />
...
</h:dataTable>
The expression language will access the getStudentId() (getter method from studentId) method from the specific student.
I used data table (OpenFaces) for selecting a row in data table using the attribute o:checkboxColumn rowDatas this will filter the selected rows only.
<o:checkboxColumn rowDatas="#{tBean.srInventoryList}">
<f:facet name="header">
<o:selectAllCheckbox />
</f:facet>
</o:checkboxColumn>
When I click a button it displays all the list, but I want only other rows which are not selected whether any attributes for filter the row list.
Actually it's not possible by the API of checkboxColumn by itself, You need to add some additional logic inside your bean for example:
<o:dataTable id="bookMultipleSelection"
var="book"
value="#{BookList.books}">
<o:multipleRowSelection rowDatas="#{BookList.list}"/>
<o:selectionColumn>
<f:facet name="header">
<o:selectAllCheckbox/>
</f:facet>
</o:selectionColumn>
/**other columns here**/
</o:dataTable>
<o:commandButton execute="bookMultipleSelection" action="#{BookList.updateList}" render="bookMultipleSelection" value="Click ME"/>
End something like this in your backing bean :
private List<Book> books;
private List list = new ArrayList();
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public List<Book> getBooks() {
return books;
}
public void updateList(){
books.removeAll(list);
}
I don't seem to get multiple selection in PrimeFaces dataTables working.
I'm trying to implement a list of clients (dataList) and show their respective bookings in nested dataTables with a possibility to select multiple bookings for billing:
<p:dataList value="#{clientController.allClients}" var="client">
<p:column>
<p:dataTable value='#{client.bookingsDataModel}' var='item' selection="#{client.bookingsToBill}">
<p:column selectionMode="multiple" />
</p:dataTable>
</p:column>
</p:dataList>
My controller and backing bean classes:
public class ClientController {
public List<Client> getAllClients() {
return clients;
}
}
public class Client {
private List<Booking> bookings;
private Booking[] bookingsToBill;
public LeistungDataModel getBookingsDataModel() {
return new BookingsDataModel(bookings);
}
public Booking[] getBookingsToBill() {
return bookingsToBill;
}
public void setBookingsToBill(Booking[] bookingsToBill) {
this.bookingsToBill = bookingsToBill;
}
}
The data model class:
public class BookingsDataModel extends ListDataModel<Booking> implements SelectableDataModel<Booking> {
public BookingsDataModel(List<Booking> data) {
super(data);
}
#Override
public Booking getRowData(String rowKey) {
List<Booking> bookings = (List<Booking>) getWrappedData();
for(Booking booking : bookings) {
if(("booking_"+booking.getId().toString()).equals(rowKey)) {
return booking;
}
}
return null;
}
#Override
public Object getRowKey(Booking booking) {
return "booking_"+booking.getId().toString();
}
}
The browser posts the following data to the server, when I submit the form with my selections:
j_idt9%3Aj_idt13%3A0%3Aj_idt15_selection:booking_300,booking_301,booking_302
j_idt9%3Aj_idt13%3A1%3Aj_idt15_selection:booking_566,booking_567
j_idt9%3Aj_idt13%3A2%3Aj_idt15_selection:
Also, I found during debugging that the getRowData method of the BookingsDataModel returns the correct Booking objects (the selected ones).
However, always empty arrays are passed to the setBookingsToBill of my Client objects. What could be going wrong here?
Update:
An empty array is only passed the first Client objects - it doesn't matter if a booking has been selected or not. All other Client objects' setBookingsToBill methods are called with a parameter value of null.
Not really, if you want multiple selection with check box you have to do as jfs did:
In the showcase there is one example showing just that. It will create a column containing the boxes for the user to select. You can also do as you've said, using an attribute of p:dataTable, however this will not create the boxes and the user will have to control+click to do multiple select.
The selectionMode should be a part of the <p:dataTable> tag.
Here is a link to the showcase which has an example.
http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf
I'm trying to create a paginated, sortable datatable using MyFaces. The sorting works fine; I can click on a column header and it will sort the data based on the column. Also the pagination works fine for the most part. The datatable will split itself appropriately with some number of items per page. In addition, I want the user to be able to change the number of items displayed per page. Again, this seems to be working until I want all of the items displayed on one page.
According to this reference (also here), if you set the "rows" attribute of t:datatable to "0", it will display the remaining rows in the table. However, when I try this, I get an exception that includes this message:
javax.faces.FacesException - You need to set a value to the 'rows' attribute of component 'myComponent'
I'm trying to set the number of items per page using an attribute in a backing bean. My t:datatable looks like this:
<t:dataTable id="myComponent" var="cur"
value="#{backingBean.list}" sortAscending="#{backingBean.ascending}"
sortColumn="#{backingBean.sortColumn}" sortable="true"
styleClass="myClass" rowClasses="oddRow,evenRow"
rows="#{backingBean.itemsPerPage}" preserveDataModel="false">
<!-- data here -->
</t:datatable>
Later, I have a t:dataScroller to control the pagination:
<t:dataScroller id="pageNavigation" for="myComponent"
paginatorActiveColumnStyle="font-weight:bold;"
renderFacetsIfSinglePage="false"
binding="#{backingBean.scroller}"
paginator="true" >
<!-- facets here -->
</t:dataScroller>
Then, I have a h:selectOneMenu to select the number of items per page
<h:selectOneMenu id="myScroller"
value="#{backingBean.itemsPerPage}"
required="true" onchange="this.form.submit();"
valueChangeListener="#{backingBean.updateItemsPerPage}">
<f:selectItems value="#{backingBean.itemsPerPageArray}" />
</h:selectOneMenu>
My backing bean looks something like this:
public class BackingBean {
private boolean ascending;
private Long itemsPerPage;
private String sortColumn;
private ArrayList<SelectItem> itemsPerPageArray;
private ArrayList<SomeObject> list; // data for table
private HtmlDataScroller scroller;
// constructors, getters, setters, and other stuff here
public void updateItemsPerPage(ValueChangeEvent valueChangeEvent) {
itemsPerPage = (Long) valueChangeEvent.getNewValue();
resetScrollerIndex();
}
private void resetScrollerIndex() {
if (scroller!=null && scroller.isPaginator())
scroller.getUIData().setFirst(0);
}
// called in constructor
private void constructItemsPerPageArray() {
itemsPerPageArray = new ArrayList<SelectItem>();
itemsPerPageArray.add(new SelectItem(new Long(10), "10"));
itemsPerPageArray.add(new SelectItem(new Long(50), "50"));
itemsPerPageArray.add(new SelectItem(new Long(100), "100"));
itemsPerPageArray.add(new SelectItem(new Long(0), "All"));
}
}
To sum up, when I select the "All" item from the h:selectOneMenu, I get the exception mentioned above. Hopefully, I've included an appropriate level of detail. Thanks!
Alright, I think I found the answer...
If I remove the first line from the updateItemsPerPage method, the problem is fixed. The method now looks like:
public void updateItemsPerPage(ValueChangeEvent valueChangeEvent) {
resetScrollerIndex();
}
It thought I had tried that...
I have a problem with selecting rows in the Primefaces Datatable. I use dynamic columns, so the standard row selection mechanism is not usable here, I implement checkbox selection myself.
To help, here's s simplified version of what I have in my xhtml:
<h:form>
<p:dataTable id="table"
var="result"
value="#{tableBean.results}">
<p:columns value="#{tableBean.columnNames}" var="column" columnIndexVar="colIndex">
<f:facet name="header">
#{column}
</f:facet>
<h:panelGroup rendered="#{colIndex==0}">
<h:outputLabel>#{rowIndex}</h:outputLabel>
<h:selectBooleanCheckbox value="#{tableBean.selectedRows[result[0]]}"/>
</h:panelGroup>
</p:columns>
</p:dataTable>
<h:commandButton value="Submit"></h:commandButton>
</h:form>
And here's what I have in the managed bean to select the checkboxes:
package testpackage;
import java.util.*;
import javax.faces.bean.*;
#ManagedBean
#SessionScoped
public class TableBean
{
private Map<String, Boolean> selectedRows = new HashMap<String, Boolean>();
List<List<String>> results = new LinkedList<List<String>>();
public TableBean()
{
List<String> row1 = new LinkedList<String>();
List<String> row2 = new LinkedList<String>();
row1.add("row1.ref");
row1.add("row1.id");
row1.add("row1.status");
row2.add("row2.ref");
row2.add("row2.id");
row2.add("row2.status");
results.add(row1);
results.add(row2);
//selectedRows.put("row2.ref", true);
}
public Map<String, Boolean> getSelectedRows()
{
return selectedRows;
}
public String submit()
{
List<List<String>> selectedResults = new ArrayList<List<String>>();
for (List<String> result : results)
{
if (selectedRows.get(result.get(0)) != null)
{
selectedResults.add(result);
selectedRows.remove(result.get(0));
}
}
return null;
}
public List<List<String>> getResults()
{
return results;
}
public List<String> getColumnNames()
{
List<String> columnNames = new LinkedList<String>();
columnNames.add("");
columnNames.add("REF");
columnNames.add("ID");
columnNames.add("STATUS");
return columnNames;
}
}
The getSelectedRows method works great, but the problem is that the setSelectedRows method is never called, so I don't know which checkboxes the user has selected. Maybe I overlook something very trivial, but cannot find the solution.
Any ideas on this? I would be very glad if you helped, or give any other row selection solution for the dynamic columns.
Thx in advance,
Levi
To me it looks you are rendering the wrong field in selectBooleanCheckBox.
You should be using variable or field from the result variable.
My solution:
In your situation you are rendering an object from List as a form of table row so if you want to make some changes and retrieve the status of that row then you should be using the variable from that object only.
I understand you are submitting the whole form and want to pickup all updated rows, in that case you will have to loop through the whole List and find all the rows which have been updated by checking the status in Request Handler(Action) bean.
Hope that helps.
The setter is never called for nested objects. You're the one who's responsible for creating them, not JSF. JSF just gets the nested object and then calls the setter on it (which is the put() method in case of a Map). You just need to determine the selected rows in the action method. Add an action method to the commandbutton:
<h:commandButton value="Submit" action="#{bean.submit}"></h:commandButton>
which is definied like follows (guessing/assuming that var="result" is in essence an Object[]):
public String submit() {
List<Object[]> selectedResults = new ArrayList<Object[]>();
for (Object[] result : results) {
if (selectedRows.get((String) result[0])) {
selectedResults.add(result);
selectedRows.remove(result[0]); // Reset.
}
}
// Now selectedResults contains all selected results.
}