How to do multiple selection in jsf or primefaces dataTable? - jsf

I want to try out building a simple grid that has a delete column, consisting of checkboxes, just like the usual one in email.
User can then tick the checkboxes, and press delete, and i can get all the checked records, and delete them one by one.
Im trying to find a way to achieve this, but so far im still in doubt.
These are what i have in mind, each with it's own implementation question, haha :
How to get the checked row indexes ? Using actionlistener for each toggle on each checkbox ? (but how do i pass the clicked index to the actionlistener ?)
Or is there a way where i can get all the grid model, and loop the data to find out which one is checked, just like swing ? (but how do i get the grid model in the jsf bean ?)
Or perhaps i should bind them to a simple list that contains only the checkbox column data ? (but how do i bind each checkbox to the list using indexes ?)
Im currently using primefaces, but i think the JSF solution can also be applied to primefaces datatable.
Please share your thoughts on this !
Thank you !

Isn't this example from Primefaces showcase exactly what you are looking for?
It looks that it is simply adding a column to the p:dataTable this way:
<p:dataTable var="item" value="#{yourBean.allElements}"
selection="#{yourBean.selectedElements}">
<p:column selectionMode="multiple" />
... other columns
</p:dataTable>

Related

Refactoring a DataTable with a large number of attributes

I've got a data table with 17 attributes. The table can be rendered in two modes: with row selection enabled and without it.
<p:dataTable selection="#{isDefaultSelectionMode ? null : widget.selected}" />
It doesn't work because selection expects a reference to a property to be able to set/get it.
I could create a dummy property widget.ignored and it's going to work. I don't like this for the obvious reason.
<p:dataTable selection="#{isDefaultSelectionMode ? widget.ignored : widget.selected}" />
I could split the table into two separate templates. I would exclude selection from one and duplicate 16 other attributes. It's not a good one, either.
I am looking for an elegant solution to either make the attribute optional (not to render it under some condition) or to avoid defining a dummy property.
I am new to JSF and PrimeFaces, feel free to correct. Any help would be welcomed.
Fortunately, I didn't have to apply any of my terrible workarounds.
As suggested by #Kukeltje (thank you) and the links he provided, I defined the attribute conditionally
<c:if test="#{isDefaultSelectionMode}">
<f:attribute name="selection" value="#{widget.selected}"/>
</c:if>
For more details, visit these questions:
JSF 2.0 dynamic attributes without creating new components
How not to set an attribute of a component inside a composite component if it is empty?
What is f:attribute used for in this example?

How to build a dynamic grid and only show three columns in a row (JSF 2.2 and BootsFaces)

I am trying to layout a page with Bootsfaces and JSF 2.2. I like to show only three column in a row and then start new row but don't know, how to implement this.
<h:form>
<b:container>
<b:row>
<ui:repeat value="#{ClientBean4.custs}" var="custs">
<b:column col-md="4"><h:outputText id="output" value="#{ClientBean4.counter}" /> </b:column>
<h:panelGroup rendered="#{ClientBean4.counter == 0}">
</b:row><b:row>
</h:panelGroup>
</ui:repeat>
</b:row>
</b:container>
</h:form>
after a long time, I wrote above code, but it's givng error like 'h:panelgroup' should be properly closed. It's giving meaning, that I started panelGroup and then closing a row, starting a new row, and then close panelGroup.
So, Is anyone have idea, how to implement a layout, where a row will have three columns (showing customer's object details per column), then close the row and start a new row. obvisouly, I dont know, how many objects will be in the list.
BootFaces offers a component that handles this. More specifically you can use <b:panelGrid columns="3"> to achieve this. This will give you a dynamic grid system that will grow vertically as you populate it but retain the number of rows that you specify.
You can see the component in action here, https://showcase.bootsfaces.net/layout/panelgrids.jsf
PrimeFaces also has a component for this, but I assume you want to use BootFaces as your original code uses it. If you prefer PrimeFaces, you can use the <p:dataGrid> component, which does something similar. This component even handles pagination.

Primefaces datatable returns the same selection item

I need some help by Primefaces dataTable.
I try to implement dataTable with single selection mode.
When I select any row in my table it is selected normally. But I see in debug mode that selectedUser field always have the same value (of the first table's item) regardless the real UI selection.
My question is what is wrong in my code?
Unfortunately google request "primefaces datatable wrong selection" did not return anything that would have helped me and I dared ask the community.
Also I found the following examples:
primefaces datatable selected row always the same value
But it is also not my case.
I thought (according the google examples and PF documentation) when we select a row this action automatically triggers the "selection" object setter. Is it wrong?
My PF version is 5.3
The table has the following definition:
<p:dataTable scrollable="true" id="SearchResultsTable" value="#{searchFormBean.users}" var="item" scrollHeight="300"
widgetVar="SearchResultsTable" selectionMode="single" selection="#{searchFormBean.selectedUser}"
rowKey="#{not empty item.usersListId ? item.usersListId : item.hashCode()}" emptyMessage="No rows found.">
<p:ajax event="rowSelect" listener="#{searchFormBean.onResultTableRowSelect}" update=":searchPage:j_idt68:summaryTable" />
// Columns
I used the following example as template
My "rowSelect" event method is the following:
public void onResultTableRowSelect(SelectEvent event) {
summaryObjects.clear();
summaryObjects.add(selectedUser);
}
where summaryObjects is the List which I pass into another table.
Mentioned SearchFormBean is ViewScoped.
Could you please help me find my mistake. I'll provide any additional information if it necessary.
Thank you.
I found my mistake and solved the issue.
It turned out that item.usersListId which I used as a rowKey for some item was null. It means that that value at least not unique. I supposed the construction not empty item.usersListId ? item.usersListId : item.hashCode() guaranteed the uniqueness. But in my case it was incorrect using.
I just changed rowKey value by another unique and selection functionality became correct.
Thank you.

How to check if instance entity has been modify in the view?

I need a guide here.
Let's say that I'm fetching some records from db an I'm populating a ui datatable with those records.
The datatable can modify the values of the records as its columns are inputs.
<p:dataTable value="#{videogames.videogameList}" var="vg" >
<p:column headerText="Name">
<p:inputText value="#{vg.name}" />
</p:column>
</p:dataTable>
How can I know if some row was modify in order to update the value in the database?
Should I check each element in the list and compare it to a temporal arraylist with the original values? Is there a more "elegant" way to do this?
Do you know any tutorial or docs that can help me to learn all this.
Thanks!
I am working with Java, JSF, primafaces and JPA.
I wish I could post it as a comment, but I lack the rep for it. I hope it serves as an answer (since you've asked for sources to learn it).
I work with PrimeFaces as well, but personally I haven't dealt with editable rows yet. Skimming over the links I give below, what you want should be doable with a RowEditEvent.
The PrimeFaces showcase is sort of a tutorial in and of itself. Here is the link for editable datatables:
http://www.primefaces.org/showcase/ui/data/datatable/edit.xhtml
Navigate through the xhtml and .java examples. It should bootstrap you in the right direction.
PrimeFaces documentation is a great source of info as well:
http://www.primefaces.org/docs/guide/primefaces_user_guide_5_3.pdf
There is an Ajax event called rowEdit that should help you. There is complementing event called rowEditCancel to detect when the user backs out of an edit.
The primefaces website offers a user guide that goes into a fair amount of detail for data tables and the rest of the framework. This is the link for the latest version 5.3.
primefaces 5.3 users guide
I think I found a solution for this case.
What I did, was to add an ajax listener with event="change", to the inputtext that can modify the value of the row, so everytime the value changes, the listener will pass the row as a param to a method, and the method will add the row to a list:
videogames.xhtml
<p:column headerText="Nombre">
<p:inputText value="#{vj.nombre}">
<!--this is the added listener-->
**<f:ajax event="change" listener="#{videojuegos.rowSelectedTest(vj)}" />**
</p:inputText>
</p:column>
<!-- **Button that calls the method for updating the modify entities columns**-->
<p:commandButton value="Actualizar" actionListener="#{videojuegos.updateVideojuego()}"/>
The managed bean receives it, and adds it to a list:
VideoGamesManagedBean.java
List <Videojuego> videojuegoUpdate = new ArrayList<Videojuego>();
//adds the modify row to a list
public void rowSelectedTest(Videojuego videojuego){
videojuegoUpdate.add(videojuego);
}
//calls the method in the EJB for merging each object in the list
public void updateVideojuego(){
if(videojuegoUpdate != null && !videojuegoUpdate.isEmpty() ){
vjbean.mergeVideojuegoList(videojuegoUpdate);
//after merging, cleans up the arraylist.
videojuegoUpdate.clear();
}
}
and last, the EJB iterates through the list and merge each object
VideoGameBean.java
#PersistenceContext
private EntityManager em;
public void mergeVideojuegoList(List<Videojuego> listVideojuegoUpdate){
for(Videojuego vjUpdate : listVideojuegoUpdate ){
em.merge(vjUpdate);
}
}
NOTE:
the only "problem" for this is, if I modify several times the same column before I hit the commandbutton "Actualizar", the list will grow up with the same row. But the merge method will take the last "version" of the column. So for our needs, it is ok.
Thanks for the previous answers, regards!!
If you know any better method or find any corner case, let me know!!

How do I reorder rows in DataTable using drag drop?

I am using PrimeFaces and JSF. Can anyone tell me how do I reorder rows of a DataTable using Primefaces drag and drop component?
Currently with in the PrimeFaces framework (v2.2.1 and 3.0) this is not possible with <p:dataTable>.
There is an open PrimeFaces Issue 511 <p:dataTable> draggable columns to add the Yahoo widget datatable draggableColumns attribute to the PrimeFaces <p:dataTable> but no target version is set yet.
If you would like to see this added to PrimeFaces star the issue to help give it higher priority.
This is definitely an older question, but the answer needs updating. This is now doable using the draggableColumns="true" attribute on your p:dataTable.
Your dataTable would then look as such :
<p:dataTable var="i" value="#{bean.data}" draggableColumns="true">
Sources :
PrimeFaces Showcase : DataTable - Columns Reordering
This feature is now available from PrimeFaces 5.0:
Usage is very simple by just enabling draggableRows option and also an optional rowReorder ajax behavior is provided getting a ReorderEvent with index information for flexibility.
Source : http://blog.primefaces.org/?p=3026
You can also have a look at the showcase here: http://www.primefaces.org/showcase/ui/data/datatable/reorder.xhtml

Resources