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

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!!

Related

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.

Disable and empty an input field after an AJAX call using JSF and Richfaces

I am using richfaces 4.2.0.Final and have the following situation: within a rich:dataTable, in which each row describes an article in a shopping cart, I have an input field
in which the user can input the quantity she wants to order. As soon as the user focuses on this input field, I have to perform some controls on the server (using Ajax) and if
the controls fail, I must empty the field and disable it.
My solution:
<rich:dataTable var="article" value="#{cart.articles} >
...
<rich:column>
<h:panelGroup id="orderQty">
<h:inputText id="qtyInput" value="#{article.qty}" disabled="#{article.controlsFailed}">
<a4j:ajax event="focus" bypassUpdates="true"
listener="#{requestBean.doAjaxControls(article)}"
execute="#this" render="qtyInput " />
</h:inputText>
</h:panelGroup>
#RequestScoped
#Named
public class RequestBean{
public void doAjaxControls(Article article){
boolean everyThingOK = doControls();//....
if (!everyThingOK){
article.setControlsFailed(true);
article.setQty(null);
} else {
article.setControlsFailed(false);
}
}
}
Before coming to this solution I tried several other combinations of execute/render, without succeeding in what I need (for example, I tried to use execute="#none" as I don't want
the value of qty to be updated on the server when I perform the ajax call, but this won't work).
My problem is I know this solution is not perfect: when I focus on a position for which the control will fail, and I am faster to type in a quantity than the server performing the controls, the field will be disabled and the server value for article#qty still set to null, but I will see the value I typed in until the next rendering of qtyInput will happen.
More strangely, if I execute this code on JBoss EAP 6.0.0.GA (AS 7.1.2.Final-redhat-1, which includes the module jboss-jsf-api_2.1_spec-2.0.2.Final-redhat-1),
every quantity typed in before doAjaxControls() is done will be cleared: this strange behaviour is fortunately not present with JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4, jboss-jsf-api_2.1_spec-2.0.7.Final-redhat-1).
Do you know if/how could I improve my solution?
Thanks in advance for helping!

JSF binding with setValueExpression read-only?

I try to create an InputField in the backing bean and add it to the view, but the databinding seems to work just read-only.
I create a UIInput in the Backing-Bean like this:
UIComponent textInput = new UIInput();
textInput.setId("operandInputText");
textInput.setValueExpression("value", ef.createValueExpression(elCtx, "#{row.operandValues[0]}", String.class));
textInput.setValueExpression("rendered", ef.createValueExpression(elCtx, "#{row.inputType == 'text'}", Boolean.class));
mInputPanelGroup.getChildren().add(textInput);
The panelGroup is inside a column of a dataTable and bound to the bean:
<p:column id="operandColumn">
<h:panelGroup id="inputPanelGroup" binding="#{locateEmployeeBean.inputPanelGroup}" >
<h:inputText id="testInput" value="#{row.operandValues[0]}" />
</h:panelGroup>
</p:column>
The <h:inputText/> inside the PanelGroup is just for testing and this is where I found out that the binding I did with setValueExpression(...) works at least read-only.
In the browser I now have 2 inputFields, first the 'testInput' and then 'operandInputText'.
When I enter a value in 'operandInputText' and submit, the value does not get saved, but when I enter a value in the 'testInput'-Field, it get's submitted and in addition the value gets displayed in BOTH inputFields.
The operandValues is a simpe object array:
private Object[] mOperandValues = new Object[2];
Could this have anything to do with the dataType I pass to setValueExpression(...)?
I tried Object, but that didn't change anything.
Any idea why this happens?
Thanks in advance!
I found the solution to my problem. Honestly it was an article by #BalusC Using Datatables: Populate datatable what took me on the right path.
Previously I added the components during PreRenderView-Phase, then I saw in your example that you populate the bound component ONCE in the getter (which is then obviously way earlier during RestoreView-Phase). That is how I've done it now and it works flawlessly, the Inputfields now work both ways (read+write).
Thanks alot for your work #BalusC!

How to do multiple selection in jsf or primefaces dataTable?

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>

Richfaces extendeddatatable sorting problem

I am developing a web app using JSF, RichFaces, EJB3, Hibernate and Seam.
I have an extended data table and showing a list (say userList) which has multi columns in it. Moreover, because of that this datatable is selectable, I want to keep the selected row indexes even if the sorting is changed by the user.
In other words of what I mean is that when the sorting of columns is changed, the order of row indexes is changed as well. Therefore, I want to invoke an action when the user clicks on sorting on each time. I tried many ways, but could nt find a solution to achieve it yet.
Do you have any idea about which listener or method is being called when sorting is clicked by the user in rich extendeddatatable? I cant understand what the point is in that...
Any help would be appreciated.
Many Thanks,
Baris
A code sample would have been nice, but it sounds like you have a separate list that contains the selected indices, and only update that list on a selection event.
Have you considered having the selection state live with the data object via a bean:
public DataBean {
private DataModel model;
private boolean selected;
//standard getters and setters omitted
}
JSF code:
<h:column>
<h:selectBooleanCheckbox value="dataBean.selected">
<a4j:support event="onclick" ajaxsingle="true" />
</h:selectBooleanCheckbox>
</h:column>
Tie your selection state to the model like this and sorting won't be an issue at all.

Resources