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

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!

Related

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

jsf inputtext doesn't show value from bean

I have the follow situation:
I have a bean that send to form some data, but only in outputlabel the data from the bean is displayed.
I tried to use primefaces, but the same problems persist.
my code:
<h:outputLabel value="#{Bean.name}" id="name2" />
<h:inputText value="#{Bean.name}" id="name" />
<p:inputText value="#{Bean.name}" id="name3" />
Any idea why?
You should have given the bean's code also, to help us better analyze the problem.
Normally you should check for the following:
Check whether you are specifying a correct bean name. Normally
bean's name is same as that of class, except that first letter
should be lowercase. In your case it should be #{bean.name} or else,
specify your custom name with #Named("Bean").
Check whether the getters and setters such as getName() are properly
provided. It may happen that you might have reset the name property in
your bean in the get method itself. Because of which first time it
shows you properly in outputLabel and then in next call to getName it may give you null or empty String. To check this, try put your inputText tag first, and check.
I solve my problem.
When I tried show the values, I was trying recover data from database by pass an ajax action. So, When I clicked at button to retrieve the datas, some of my inputText were set as a required. And because this the data is just displaying into label and not inside of inputtext with required. But because ajax, the request were not called correctly.
When I remove the required from inputtext, it works fine.

JSF validation for client side injected elements

I know there is a property in asp.net (probably this EnableEventValidation of "<%# Page%> tag) .Which, once caused problem when i try to add select items to a component using javascript ,I want to know how jsf handling this. That is,
if i send a h:select* like below and client add a new item "option3 " to item list, is jsf detect this automaticly before update model values .
<h:selectOneMenu id="type"
value="#{foo.value}"
required="true"
requiredMessage="Type is required"
style="width:100px">
<f:selectItem value="option1}"/>
<f:selectItem value="option2}"/>
</h:selectOneMenu>
I think what you need to understand regarding JSF is that the client/server parts of the components are tightly coupled together. You are probably better off thinking of them strictly as one entity, and forget about fiddling with one side only, reverting to custom Javascript when that is the only solution left.
The other way to think of it is that the server side renders the client side, not vice versa! So whenever you need to update a component the update must be done on the server side first, which will propagate to the client side (the browser).
In your example the proper way to add and element to the select* items is to store the selectable items in a data structure within a bean (probably #ViewScoped), and then do a partial update via AJAX for the select* component or its container component, when the server side gets the chance to become aware of the changes and can update the client side properly as well.
Sure, you can hack your way through Javascript only, but then why use JSF? The whole point of JSF is to avoid the need for hacks like this.
Remember, JSF is not JSP, which is basically a println macro for html output. JSF stores the page components' representation on the server side, mirroring the browser's representation.
Check the Primefaces showcase for examples on how to do partial updates. More specifically this is the example you could be looking for. This is available in standard JSF2, for JSF 1.2 you must use a component library to get AJAX support.
You should not add the new option by JavaScript, but you should add the new option by JSF. JSF needs to know about the new option somehow in order to allow the submitted value. The new option really needs to be served by <f:selectItem(s)>. Otherwise you will face Validation error: Value not valid all the time when submitting the option value which is added by JS. This is after all just a safeguard of JSF to prevent clients from manipulating the request and submitting values which they are not supposed to submit.
The following kickoff example should work:
<h:form>
<h:selectOneMenu id="menu" value="#{bean.item}">
<f:selectItems value="#{bean.items}" />
</h:selectOneMenu>
<h:inputText id="newItem" value="#{bean.newItem}" />
<h:commandButton value="add" action="#{bean.addNewItem}">
<f:ajax execute="#this newItem" render="menu" />
</h:commandButton>
<h:commandButton value="submit" action="#{bean.submit}" />
</h:form>
with a #ViewScoped managed bean something like follows:
private String item;
private List<String> items = Arrays.asList("option1", "option2");
private String newItem;
public void addNewItem() {
items.add(newItem);
}
// ...

JSF: Reload page after data change

Using a DataModel<MyObject>, I fill a data table according to this response
Now at the end of each line I have a delete button which calls a certain method of my bean. The data gets cleanly deleted. But as the data has been changed after the deletion, I'd like to reload the page in order to reflect the changes.
My attempt was to add a navigation rule in faces-config.xml:
overview
/overview.jsp
deletedsubscription
/overview.jsp
If I have <redirect /> or not, either way it's not reloading or doing anything else at all. The data is deleted, therefore the bean's method is actually called.
My button looks like this:
<h:dataTable border="1" value="#{overviewBean.overviewModel }" var="item" first="0">
<h:column id="column13">
<f:facet name="header">
<h:outputText value="#{messages.overviewDeleteItem }"></h:outputText>
</f:facet>
<h:commandButton action="#{overviewBean.deleteItem}" value="X"/>
</h:column>
</h:dataTable>
Setting the attribute type="submit" actually solves the problem. The pages gets reloaded.
My question now: is the submit really required? Doesn't JSF (Apache MyFaces) have some mechanism of using AJAX to eliminate the line just deleted?
Thanks for trying to help a JSF-newbie.
Just remove the item from the backing list of the datamodel. The changes will be reflected in the model.
Basically:
private List<MyObject> overviewList;
private DataModel overviewModel;
public OverviewBean() {
overviewList = overviewDAO.list();
overviewModel = new ListDataModel(overviewList);
}
public void deleteItem() {
MyObject myObject = (MyObject) overviewModel.getRowData();
overviewDAO.delete(myObject);
overviewList.remove(myObject); // See?
}
A redirect thereafter is not necessary. If the action method returns void (or null), it will go to the same page anyway.
Ajaxical capabilities have been introduced in JSF 2.0, but if I am not wrong, you're still on JSF 1.x. Your best bet is then adopting a 3rd party component library like Ajax4jsf (currently part of RichFaces), for the case that you consider this necessary.

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