f:ajax listener isn't called - java

I've got a problem considering JSF and AJAX.
I am trying to update some customer details after a visitor inserts the customer id.
Firstly, a excerpt from the xhmtl code:
<h:form>
<h:panelGrid columns="2">
<h:panelGrid columns ="2" border="1" id="customer_grid">
<h:outputLabel value="#{mbean_msg.reservation_lblCustomerNo}" for = "customer_id"/>
<h:inputText id = "customer_id" value="#{reservationHandler.customer.customer_id}">
<f:ajax listener="{reservationHandler.autocompleteCustomerDetails}"
render="customer_grid" />
</h:inputText>
<h:outputLabel value="#{mbean_msg.reservation_lblLastname}" for="lastname"/>
<h:inputText id="lastname" value="#{reservationHandler.customer.lastname}" required ="true"
requiredMessage="#{error_msg.errmsgLastname}" validator="#{reservationHandler.validateCustomer}"/>
<h:outputLabel value="#{mbean_msg.reservation_lblFirstname}" for="firstname"/>
<h:inputText id="firstname" value="#{reservationHandler.customer.firstname}" required ="true"
requiredMessage="#{error_msg.errmsgFirstname}" validator="#{reservationHandler.validateCustomer}"/>
The listener method is implemented within my java file (ReservationHandler.java) like that:
public void autocompleteCustomerDetails(){
System.out.println("Auto Complete"); // for testing
}
Basically I am trying to call the method autocompleteCustomerDetails with the Listener. Unfortunately this method is never called. Anyways, the render seems to work just fine, since the other inputTexts update themselves (visibly).
Does anybody have an idea, why the listener isn't called?

There are two problems in the code shown so far:
First,
<f:ajax listener="{reservationHandler.autocompleteCustomerDetails}" />
this isn't a valid EL expression. EL expessions have the form of #{}, not {}. Fix it accordingly:
<f:ajax listener="#{reservationHandler.autocompleteCustomerDetails}" />
Second,
public void autocompleteCustomerDetails() {
this isn't a valid default signature of a method expression for <f:ajax listener>. The tag documentation clearly tells the following:
signature must match public void processAjaxBehavior(javax.faces.event.AjaxBehaviorEvent event) throws javax.faces.event.AbortProcessingException.
So, you forgot the argument. Add it accordingly. The throws declaration isn't mandatory for unchecked exceptions, so we can just leave it out.
public void autocompleteCustomerDetails(AjaxBehaviorEvent event) {
Or, if you actually intend to get rid of the argument, then you should put parentheses in the EL method expression:
<f:ajax listener="#{reservationHandler.autocompleteCustomerDetails()}" />
Note that this works only if your container supports EL 2.2.

Try this:
<f:ajax listener="{reservationHandler.autocompleteCustomerDetails()}"
render="customer_grid" />
or change the method to:
getAutoCompleteCustomerDetails
just for testing...
Anyhow, you´re not allowed to use any jsf's components library? Like primefaces ?
It gets the job done in such a easy way...
Anyhow, with primefaces I would do that like this:
<p:ajax event="blur" listener="#{prospectoRadarController.atualizarRadar(data)}" update=":mainForm:painelRadar" />
Another guess would be, add the execute="#this" to the ajax flag...
Sorry, those are all wild guesses, but I really want to help.
PLease feedback!

Related

Primefaces cannot update p:tree

I'm working with primefaces 4.0 and JSF 2.2 and I'm currently trying to update a form with a p:tree on it. The commandButton works correctly but it does not update the form or call the init() method until I manually refresh the page. I don't know what I'm doing wrong since the same code does work for a DataTable element.
Here's the code:
<h:form id="preferenciasForm">
<div id="panelTree">
<p:panel id="defTree" style="margin-bottom: 20px">
<p:tree value="#{dtPreferencesBuilder.root}" var="node"
selectionMode="checkbox"
selection="#{dtPreferencesBuilder.selectedNodes}"
style="width:100%; height:100%;" animate="true">
<p:treeNode>
<h:outputText value="#{node.label}" />
</p:treeNode>
</p:tree>
<p:commandButton value="Add preferences"
icon="ui-icon-pencil"
actionListener="#{dtPreferencesBuilder.insertPrefNodes()}"
update=":preferenciasForm" ajax="true" />
</p:panel>
</div>
</h:form>
And here's is the java class.
#ManagedBean(name="dtPreferencesBuilder")
#ViewScoped //I've tried with or without the ViewScoped, neither work
public class PreferencesBuilderBean {
private TreeNode root;
private TreeNode prefRoot;
private TreeNode[] selectedNodes;
#PostConstruct
public void init() {
System.out.println("Building Tree");
selectedNodes=null;
root=null;
prefRoot=null;
root=getStandardTree();
prefRoot=getPreferedTree();
}
The init() is not called as the print is only show on manual reload so the tree is not updated nor the selectedNodes refreshed. Any ideas why it doesn't work?
As I cannot describe bean scopes better than excellent answers already given for similar questions I'll just refer you to the answers by BalusC and Kishor P here.
The init-method (or any method with the #PostConstruct-annotation) will be called by the framework only when the bean is created, after injections and therefore after the constructor has run as rion18 said. It would not be normal to use the method for anything else than initializing work. So create other methods, and call those from actions and actionListeners.
If you want the bean to be the same when you call it with ajax (as you do) it needs to be at least ViewScoped. If you really do want to call the init() every time it should be RequestScoped, but then the bean will be new when you call it with ajax and not remember a thing.

How to render more JSF components by using a ui:repeat component?

I have a question concerning the jsf component . Here is a small code example:
<ui:repeat var="bean" value="myBean.myListToIterate">
<h:selectOneCheckbox value="#{myBean.specificField}" />
#{bean.car.name}
</ui:repeat>
Question 1: Why the expression #{bean.car.name} alone inside the ui:repeat element and why not for example in a
<h:outputLabel value="#{bean.car.name}" />"?
If i use this, nothing will be displayed.
Question 2: Why does this example doesn´t look very well, if i use a
<h:selectOneRadio value="#{myBean.specificField}"/> component
instead of a
<h:selectOneCheckbox value="#{myBean.specificField}"/> component?
Greetz
Marwief
Answer 1 :
EL JSF expressions are allowed in the last JSF versions. So it can be put without any wrapping tag (like <h:outputText />).
Using this <h:outputLabel value="#{bean.car.name}" /> did not give result, because you did not specify for attribute to point to, in order to be rendered as label of its client id, which means, it cannot be used alone.
Answer 2 :
First, this JSF tag <h:selectOneCheckbox /> doesn't exist, maybe you wanted to mean <h:selectBooleanCheckbox />. Replacing this by <h:selectOneRadio ... /> does not look very well, because this last one needs <f:selectItem /> or <f:selectItems /> to hold choices from where the end user will be able to choose between (i.e at least 2 choices), in the contrary of <h:selectBooleanCheckbox /> which can have no child select item(s) tag(s) in the case of one alone choice to (un)check.

Fire valueChangeListener with submit but after set and get methods

I have a problem I can not solve, I have a selectOneListbox with a Value Chang Listener and submit onclick. It works perfectly but the problem I have noticed is that the Set and Get methods I have for other elements in my form runs after the method that captures the ValueChangeListener. And I can not use the right data from the elements in my form, how do I resolve this?
So i got in my selectOneListbox:
<h:selectOneListbox onclick="Submit();"
valueChangeListener="#{normalbesoksgrenController.setActiveFromAllList}"
size="20" value="#{normalbesoksgrenController.currentVardTillfalleID}">
<f:selectItems itemValue="#{item.vardTillfalle.id}" itemLabel="#
{normalbesoksgrenController.getDateAndTime(item.getVardTillfalle().getStartTid())}"
var="item" value="#{normalbesoksgrenController.besokList}" ></f:selectItems>
</h:selectOneListbox>
And i got my backbean:
public void setActiveFromAllList(ValueChangeEvent event)
{
int id = Integer.parseInt(event.getNewValue().toString());
Doing some stuff..
}
I think you might want to use the ajax event like this:
<h:selectOneListBox .....>
<f:ajax execute="#form" listener="#{normalbesoksgrenController.setActiveFromAllList}" event="change" reder=":whatEverYouWant" />
</h:selectOneListBox>
The execute attribute defines what should be submitted before the ajax request is handled.

How to check a textbox value when the user press tab

The scenario was something like this:
I have 2 textboxes, say txtbox1 and txtbox2. When the user type something on txtbox1 and then press tab, txtbox1 loses focus and txtbox2 got focus. I want to check the value of txtbox1 when it loses focus. If txtbox1 value is invalid, I need to render a <h:outputText value="Invalid field" rendered=#{bean.errorFlag}/>
I used <p:ajax event="blur" /> on txtbox1.
My problem is it doesn't render the outputText even though the value of errorFlag is set to true. I also use update on ajax to update outputText, but it doesn't render it.
You need to specify the client ID of the to-be-updated element in update attribute.
<h:inputText id="input1" value="#{bean.input1}">
<p:ajax event="blur" update="input1Message" />
</h:inputText>
<h:panelGroup id="input1Message">
<h:outputText value="Invalid field!" rendered="#{bean.input1Error}" />
</h:panelGroup>
But... You're basically reinventing JSF validation and not taking benefit of JSF built-in validation API. I strongly recommend to just implement a Validator instead.
#FacesValidator("input1Validator")
public class Input1Validator implements Validator {
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (isInvalid(value)) {
throw new ValidatorException(new FacesMessage("Invalid field!"));
}
}
}
and use it as follows
<h:inputText id="input1" value="#{bean.input1}">
<p:ajax event="blur" update="input1Message" />
</h:inputText>
<h:message id="input1Message" for="input1" />
This keeps your managed bean free from validation and boolean property clutter.
I guess you use p:tabview. if it is correct, you can use tab change listener
you can look this site
http://www.primefaces.org/showcase-labs/ui/tabviewChangeListener.jsf

JSF2 ajax tag throws unknown javascript error in Internet Explorer

Having this lines of code:
<h:commandLink value="Reset Filter" styleClass="button">
<f:ajax event="click" render="filterWindowDiv tableX" listener="#{beanX.reset}" />
</h:commandLink>
and as well as with:
<h:commandLink value="Reset Filter" styleClass="button">
<f:ajax event="click" render="#all" listener="#{beanX.reset}" />
</h:commandLink>
an unknown error will be thrown in Internet Explorer 8:
Object doesn't support this property or method pageX.jsf, line1 character 7
The h:commandLink is within a o:window (OpenFaces 3).
However, I do get the same error if I am using the same lines of code for example for a Delete button which shows after invoking a bean method a o:popupLayer.
Any ideas? Thank you in advance!
I've had JavaScript code within my div which must be rendered adhoc while re-render a part of the page. However, it seems IE cannot handle that issue while FF don't mind. I think to remember I've read something something about this. Anyway, since I've removed the JavaScript error is gone.
But how to invoke my JavaScript code after rendering? I've solved it like this example:
<h:commandLink value="Reset Filter" styleClass="button">
<f:ajax event="click" render="#all" listener="#{beanX.reset}"
onevent="callback" />
</h:commandLink>
Callback method:
function callback(data) {
data.status == "success") {
// your JavaScript code
}
}
Thanks again for all your help!
The problem here lies with click event of <h:commandLink>
Don't know the possible cause, but using mousedown will hopefully solve your problem.

Categories