JSF 2 - f:ajax tag doesn't work
I have a problem with f:ajax tag. In my previous project, everything worked perfectly. Now I have another project and f:ajax tag doesn't work at all and I don't know why.
I have this in JSF page with Facelets:
<h:form>
...
<h:selectOneMenu id="employeeId" value="#{employeeBean.employeeId}">
<f:selectItems value="#{employeeBean.employeesSelectItem}"/>
<f:ajax event="change" listener="#{employeeBean.changeOwner}"/>
</h:selectOneMenu>
...
</h:form>
And employeeBean with changeOwner method with database access:
...
public void changeOwner(AjaxBehaviorEvent event) {
try {
update.updateOwner(...params...);
JSF.setMessage(Messages.UPDATE_OK);
} catch (UpdateDBException ex) {
JSF.setMessage(ex.getMessage());
}
}
...
I can't see anything wrong. Thanks for help.
UPDATE
faces-config:
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<converter>
<converter-for-class>java.util.Date</converter-for-class>
<converter-class>misc.TimeZoneConverter</converter-class>
</converter>
</faces-config>
xhtml page:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./../templates/mainTemplate.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="content">
<h2>Smazání zaměstnance</h2>
Protože s daným zaměstnancem (#{employeeBean.employee.name} #{employeeBean.employee.surname}) souvisejí některé úkoly, je potřeba, aby se jich ujal jiný. Vyberte prosím nové zaměstnance u všech níže uvedených úkolů.
<h:form>
<h:dataTable value="#{taskBean.employeeTasks}" var="item">
<h:column>
<f:facet name="header">ID</f:facet>
<center>#{item.idtask}</center>
</h:column>
<h:column>
<f:facet name="header">Zadavatel</f:facet>
<h:selectOneMenu id="managerId" value="#{employeeBean.newManagerId}" rendered="#{employeeBean.employeeId == item.employeeByIdmanager.idemployee}">
<f:selectItems value="#{employeeBean.otherEmployeesSelectItem}"/>
<f:ajax event="change" listener="#{employeeBean.changeOwner}"/>
</h:selectOneMenu>
<h:outputText value="#{item.employeeByIdmanager.name} #{item.employeeByIdmanager.surname}" rendered="#{employeeBean.employeeId != item.employeeByIdmanager.idemployee}"/>
</h:column>
<h:column>
<f:facet name="header">Zodpovědná osoba</f:facet>
<h:selectOneMenu id="employeeId" value="#{employeeBean.newEmployeeId}" rendered="#{employeeBean.employeeId == item.employeeByIdemployee.idemployee}">
<f:selectItems value="#{employeeBean.otherEmployeesSelectItem}"/>
<f:ajax event="change" listener="#{employeeBean.changeOwner}"/>
</h:selectOneMenu>
<h:outputText value="#{item.employeeByIdemployee.name} #{item.employeeByIdemployee.surname}" rendered="#{employeeBean.employeeId != item.employeeByIdemployee.idemployee}"/>
</h:column>
<h:column>
<f:facet name="header">Čas zadání</f:facet>
<center><h:outputText value="#{item.timestart}"/></center>
</h:column>
<h:column>
<f:facet name="header">Udělat do</f:facet>
<center><h:outputText value="#{item.timetodo}"/></center>
</h:column>
<h:column>
<f:facet name="header">Popis úkolu</f:facet>
#{item.text}
</h:column>
<h:column>
<f:facet name="header">Zákazník</f:facet>
<h:link outcome="viewCustomerDetails">
<h:panelGrid columns="1">
开发者_高级运维 <h:outputText value="#{item.customer.name}"/>
<h:outputText value="#{item.customer.addresscity}"/>
</h:panelGrid>
<f:param name="customerId" value="#{item.customer.idcustomer}"/>
</h:link>
</h:column>
<h:column>
<f:facet name="header">Stav úkolu</f:facet>
#{item.taskstate.state}
</h:column>
<h:column>
<f:facet name="header">Poznámky</f:facet>
<h:outputText escape="false" value="#{item.note}"/>
</h:column>
</h:dataTable>
</h:form>
<h:messages globalOnly="true" styleClass="messages"/>
</ui:define>
UPDATE2
EmployeeBean:
package beans;
import beans.jsf.JSF;
import ejb.Get;
import ejb.Update;
import entities.Employee;
import entities.Permission;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.model.SelectItem;
import javax.validation.constraints.Pattern;
import misc.Messages;
@ManagedBean(name="employeeBean")
@RequestScoped
public class EmployeeBean {
@EJB
private Get get;
@EJB
private Update update;
@ManagedProperty(name="employeeId", value="#{param['employeeId']}")
private int employeeId;
private int newManagerId;
private int newEmployeeId;
private String edit = "none";
@Pattern(regexp=".+", message="Jméno musí být vyplněno.")
private String name;
@Pattern(regexp=".+", message="Příjmení musí být vyplněno.")
private String surname;
private int permissionId;
private Employee employee;
/** Creates a new instance of EmployeeBean */
public EmployeeBean() {
}
public int getNewEmployeeId() {
return newEmployeeId;
}
public void setNewEmployeeId(int newEmployeeId) {
this.newEmployeeId = newEmployeeId;
}
public int getNewManagerId() {
return newManagerId;
}
public void setNewManagerId(int newManagerId) {
this.newManagerId = newManagerId;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
employee = get.getEmployee(employeeId);
}
public String getEdit() {
return edit;
}
public void setEdit(String edit) {
this.edit = edit;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPermissionId() {
return permissionId;
}
public void setPermissionId(int permissionId) {
this.permissionId = permissionId;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
private void showEdit() {
edit = "block";
}
private void hideEdit() {
edit = "none";
}
/**
* Naplní SelectItem všemi zaměstnanci.
* @return seznam zaměstnanců
*/
public List<SelectItem> getEmployeesSelectItem() {
List<SelectItem> employees = new ArrayList<SelectItem>();
for (Employee e : get.getEmployees()) {
employees.add(new SelectItem(e.getIdemployee(), e.getName() + " " + e.getSurname()));
}
return employees;
}
/**
* Vrátí seznam zákazníků.
* @return seznam zákazníků
*/
public List<Employee> getEmployees() {
return get.getEmployees();
}
/**
* Načte úkol pro editaci.
*/
public void loadEmployee() {
Employee e = get.getEmployee(employeeId);
if (e != null) {
name = e.getName();
surname = e.getSurname();
permissionId = e.getPermission().getIdpermission();
showEdit();
} else {
JSF.setMessage(Messages.DB_RETURN_NULL);
}
}
/**
* Naplní SelectItem všemi oprávněními.
* @return seznam oprávnění
*/
public List<SelectItem> getPermissionsSelectItem() {
List<SelectItem> permissions = new ArrayList<SelectItem>();
for (Permission p : get.getPermissions()) {
permissions.add(new SelectItem(p.getIdpermission(), p.getPermissionname()));
}
return permissions;
}
/**
* Zapíše úpravy úkolu.
*/
public void updateEmployee() {
try {
update.updateEmployee(name, surname, employeeId, permissionId);
JSF.setMessage(Messages.EMPLOYEE_UPDATE_OK);
} catch (Exception ex) {
showEdit();
JSF.setMessage(ex.getMessage());
}
}
/**
* Zruší prováděné úpravy a skryje editaci.
*/
public void cancel() {
hideEdit();
}
public void changeOwner(int taskId) {
System.out.println("taskId: "+taskId);
System.out.println("managerId: "+newManagerId);
System.out.println("employeeId: "+newEmployeeId);
// try {
// update.updateOwner(taskId, newManagerId, newEmployeeId);
// JSF.setMessage(Messages.UPDATE_OK);
// } catch (UpdateDBException ex) {
// JSF.setMessage(ex.getMessage());
// }
}
/**
* Naplní SelectItem všemi možnými stavy pro úkol.
* @return seznam stavů úkolu
*/
public List<SelectItem> getOtherEmployeesSelectItem() {
List<SelectItem> employees = new ArrayList<SelectItem>();
for (Employee e : get.getOtherEmployees(employeeId)) {
employees.add(new SelectItem(e.getIdemployee(), e.getName() + " " + e.getSurname()));
}
return employees;
}
}
This will only work when the input element is inside a form. So put the whole menu in a <h:form>
.
Update: the f:ajax
is in fact a JSF 2.0 tag. If you ever change your JSF libs or the faces-config.xml
to comply JSF 1.2, then the f:ajax
will stop working. Verify if you're using the correct versioned libs and the root declaration of any faces-config.xml
is set to JSF 2.0.
If that doesn't help, then I don't see other causes than that you aren't running the code you think you're running. Did you read the server logs? Did you run the debugger? Did you eliminate the surrounding code so that the JSF page ends up with only the code as in your question inside the h:body
?
Update 2: the EmployeeBean
is set as @RequestScoped
which means that it's garbaged at end of request (after sending the response). The loading of the employee is depending on the presence of an employee ID which is been set as a request parameter. Basically you need to pass the employee ID on every request to get the employee to load, including ajaxical requests. Also, the rendering of the dropdown is depending on the presence of a valid employee in the request. If the rendered condition evaluates false
during ajaxical request, the ajax action won't be invoked. I am not sure about this complex case, but in theory passing the employee ID as hidden parameter should help:
<h:inputHidden value="#{employeeBean.employeeId}" />
Put it in the form next to the table.
Since f:ajax
listener
expects to AjaxBehaviorEvent
change it to:
public void changeOwner(AjaxBehaviorEvent event) {
try {
update.updateOwner(...params...);
JSF.setMessage(Messages.UPDATE_OK);
} catch (UpdateDBException ex) {
JSF.setMessage(ex.getMessage());
}
}
EDITED: Check if any other component in the form blocks the form from being submitted. (Maybe h:selectonemenu etc.)
精彩评论