[英]AJAX not firing in JSF 2.0
I have a problem that my AJAX requests are not firing in JSF, for unknown reasons. 我有一个问题,由于未知原因,我的AJAX请求没有在JSF中触发。
admin.xhtml Snippet: admin.xhtml代码段:
<h:form id="adminPanel">
...
<f:subview id="editCustomer#{customer.id}">
<p class="#{adminService.getEditCustomerClass(customer.id)}">
<h:inputText id="email#{customer.id}" value="#{adminService.customerEmail}"/><br/>
<h:inputText id="firstName#{customer.id}" value="#{adminService.customerFirstName}"/>
<h:inputText id="lastName#{customer.id}" value="#{adminService.customerLastName}"/><br/>
<h:commandButton id="saveEdit#{customer.id}" type="button" value="Save">
<f:ajax render="@form" event="click" listener="#{adminService.saveCustomer()}"/>
</h:commandButton>
<h:commandButton id="cancelEdit#{customer.id}" type="button" value="Cancel">
<f:ajax render="@form" event="click" listener="#{adminService.cancelEdit()}"/>
</h:commandButton>
</p>
</f:subview>
...
</h:form>
AdminService.java Snippet: AdminService.java代码段:
@Named
@Stateless
@LocalBean
public class AdminService {
public String getEditCustomerClass(int id) {
return id != customerId ? "hidden" : "";
}
public void saveCustomer() {
cancelEdit();
}
public void cancelEdit() {
movieId = -1;
customerId = -1;
orderId = -1;
actorId = -1;
employeeId = -1; //if none of the id's match, p should return 'hidden' class and not be seen.
}
}
Originally I had problems because instead of hiding and showing with CSS, I was using the "rendered=" attribute. 最初,我遇到了问题,因为我没有使用CSS隐藏和显示,而是使用了“ rendered =”属性。 However, I heard that partial rendering of views can break AJAX, so I phased it out, hoping that not partially rendering the view (only hiding and showing it) would fix the problem.
但是,我听说部分渲染视图会破坏AJAX,因此我逐步淘汰了它,希望不部分渲染视图(仅隐藏和显示它)可以解决此问题。
However this ajax is still not calling the method I specified in the listener attribute (the entire page is a lot bigger and uses a lot more AJAX, though the rest of it works until these buttons are pressed, then other ajax buttons stop responding.) 但是,此ajax仍未调用我在listener属性中指定的方法(整个页面要大得多,并使用更多的AJAX,尽管其余的部分将一直工作到按下这些按钮,然后其他ajax按钮停止响应。)
If I change the button type to submit, it will actually perform the listener method if I press the button twice, but then the other ajax links don't call their respective listener methods. 如果我更改按钮类型以提交,则如果我按两次按钮,它将实际上执行侦听器方法,但是其他ajax链接不会调用它们各自的侦听器方法。
How can I get this to work? 我该如何工作?
Update: 更新:
Here is the information from POST request that JSF fires on click: 这是JSF在点击时触发的POST请求中的信息:
Request Headers: 请求标头:
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:2186
Content-type:application/x-www-form-urlencoded;charset=UTF-8
Cookie:JSESSIONID=7342e0de92edc023eecbf706dae3
Faces-Request:partial/ajax
Host:www.minimalcomputers.com:8181
Origin:https://www.minimalcomputers.com:8181
Referer:https://www.minimalcomputers.com:8181/MovieProject/Admin/admin.xhtml
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Form Data: 表格数据:
adminPanel:adminPanel
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:1:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:2:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:3:editCustomer1:lastName1:
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:email1:phroph@yahoo.com
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:firstName1:
adminPanel:representativeActionPane:customerPane:customersList:4:editCustomer1:lastName1:
javax.faces.ViewState:1088200739038195170:4402027985833798256
javax.faces.source:adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1
javax.faces.partial.event:click
javax.faces.partial.execute:adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1 adminPanel:representativeActionPane:customerPane:customersList:0:editCustomer1:cancelEdit1
javax.faces.partial.render:adminPanel
javax.faces.behavior.event:click
javax.faces.partial.ajax:true
Response Header 响应标题
Cache-Control:no-cache
Content-Type:text/xml;charset=UTF-8
Date:Thu, 02 May 2013 21:45:05 GMT
Server:GlassFish Server Open Source Edition 3.1.2.2
Transfer-Encoding:chunked
X-Powered-By:Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2.2 Java/Sun Microsystems Inc./1.6)
X-Powered-By:JSF/2.0
Update 2: 更新2:
When I switch to commandButtons of type "submit" without AJAX, it works as expected (except some of the buttons requires two clicks to activate). 当我切换到不带AJAX的“提交”类型的commandButtons时,它会按预期工作(除了某些按钮需要单击两次才能激活)。 So the problem is localized to the f:ajax tags.
因此,问题仅限于f:ajax标签。
Update 3: 更新3:
The entire base of code for admin.xhtml. admin.xhtml的整个代码库。 IT's a bit unclean because it's in the process of being debugged and trying things to make it work.
IT有点不干净,因为它正处于调试和尝试使其正常运行的过程中。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"/>
<h:outputStylesheet name="header.css" library="css"/>
<link href='http://fonts.googleapis.com/css?family=Noto+Sans' rel='stylesheet' type='text/css'/>
<title>VideoPile - Administration</title>
</h:head>
<h:body>
<div id="body">
<ui:insert name="header" >
<ui:include src="/templates/header.xhtml" />
</ui:insert>
<div id="content">
Admin.
<h:form id="adminPanel">
<!--<h:commandButton id="admin" value="Administrative Actions" rendered="{adminService.hasAdminPrivileges()}">
<f:ajax render="@form" event="click" listener="{adminService.toggleAdminPane()}"/>
</h:commandButton>-->
<h:commandButton id="manager" type="button" value="Manager Actions" rendered="#{adminService.hasManagerPrivileges()}">
<f:ajax render="@form" event="click" listener="#{adminService.toggleManagerPane()}"/>
</h:commandButton>
<h:commandButton id="representative" type="button" value="Representative Actions" rendered="#{adminService.hasRepresentativePrivileges()}">
<f:ajax render="@form" event="click" listener="#{adminService.toggleRepresentativePane()}" />
</h:commandButton>
<br/>
<!--<f:subview id="administrativeActionPane" rendered="{userService.showAdminPane}">
Admin Pane
</f:subview>-->
<f:subview id="managerialActionPane">
<div class="#{adminService.getShowManagerClass()}">
Manager Pane:
<h:commandLink id="editmovies" value="Movies">
<f:ajax render="@form" event="click" listener="#{adminService.toggleMoviePane()}"/>
</h:commandLink>
<h:commandLink id="employes" value="Employees">
<f:ajax render="@form" event="click" listener="#{adminService.toggleEmployeePane()}"/>
</h:commandLink>
<h:commandLink id="sales" target="_blank" value="View Sales Report" action="/Admin/salesreport"/>
<h:commandLink id="employees" target="_blank" value="View Most Active Employees" action="/Admin/activeemployees"/>
<h:commandLink id="customers" target="_blank" value="View Most Active Customers" action="/Admin/activecustomers"/>
<h:commandLink id="movies" target="_blank" value="View Most Active Movies" action="/Admin/activemovies"/>
<br/>
<f:subview id="moviesEditPane">
<span class="#{adminService.getShowMovieClass()}">
Movies.
<ui:repeat value="#{adminService.currentMoviePage}" var="movie">
#{movie.name}
<h:commandLink id="edit" value="Edit">
<f:ajax render="@form" event="click" listener="#{adminService.editMovie(movie.id)}"/>
</h:commandLink>
<h:outputText rendered="#{adminService.movieId eq movie.id}" value="edit"/>
<br/>
</ui:repeat>
</span>
</f:subview>
<f:subview id="employeesEditPane">
<span class="#{adminService.getShowEmployeeClass()}">
Employees.
<ui:repeat value="#{adminService.currentEmployeePage}" var="employee">
#{employee.firstName} #{employee.lastName}
<h:commandLink id="edit" value="Edit">
<f:ajax render="@form" event="click" listener="#{adminService.editEmployee(employee.id)}"/>
</h:commandLink>
<h:outputText rendered="#{adminService.employeeId eq employee.id}" value="edit"/>
<br/>
</ui:repeat>
</span>
</f:subview>
</div>
</f:subview>
<f:subview id="representativeActionPane">
<div class="#{adminService.getShowRepresentativeClass()}">
Customer Representative Pane:
<h:commandLink id="recordOrder" value="Record Order">
<f:ajax render="@form" event="click" listener="#{adminService.toggleOrderPane()}"/>
</h:commandLink>
<h:commandLink id="customers" value="Customers">
<f:ajax render="@form" event="click" listener="#{adminService.toggleCustomerPane()}"/>
</h:commandLink>
<h:commandLink id="mailingList" target="_blank" value="View Mailing List" action="/Admin/mailinglist"/>
<f:subview id="orderPane">
<span class="#{adminService.getShowOrderClass()}">
Create new order.
</span>
</f:subview>
<f:subview id="customerPane">
<span class="#{adminService.getShowCustomerClass()}">
Customers.
<ui:repeat id="customersList" value="#{adminService.currentCustomerPage}" var="customer">
<f:subview id="editCustomer#{customer.id}">
<p class="#{adminService.getEditCustomerClass(customer.id)}">
<h:inputText id="email#{customer.id}" value="#{adminService.customerEmail}"/><br/>
<h:inputText id="firstName#{customer.id}" value="#{adminService.customerFirstName}"/>
<h:inputText id="lastName#{customer.id}" value="#{adminService.customerLastName}"/><br/>
<h:commandButton id="saveEdit#{customer.id}" type="submit" value="Save" actionListener="#{adminService.saveCustomer()}">
<f:ajax render="@form" event="click" execute="@form"/>
</h:commandButton>
<h:commandButton id="cancelEdit#{customer.id}" type="submit" value="Cancel" actionListener="#{adminService.cancelEdit()}">
<f:ajax render="@form" event="click" execute="@form" />
</h:commandButton>
</p>
</f:subview>
<f:subview id="viewCustomer#{customer.id}">
<p class="#{adminService.getViewCustomerClass(customer.id)}">
#{customer.email}<br/>
#{customer.firstName} #{customer.lastName}<br/>
<h:commandLink id="suggestion" target="_blank" value="View Suggestions" action="/Admin/customersuggestions">
<f:param name="user" value="#{customer.id}"/>
</h:commandLink>
<h:commandButton id="edit" type="submit" value="Edit" action="#{adminService.editCustomer(customer)}">
<f:ajax render="@form" event="click" execute="@form" />
</h:commandButton>
</p>
</f:subview>
<br/>
</ui:repeat>
</span>
</f:subview>
</div>
</f:subview>
</h:form>
</div>
</div>
</h:body>
</html>
I found the answer, and the cause of it is really quite strange, but it makes sense. 我找到了答案,其原因确实很奇怪,但这是有道理的。
In my ID's, I was using EL to define unique ID's for UIComponents (even though this was not necessary). 在我的ID中,我使用EL为UIComponents定义了唯一的ID(即使这不是必需的)。 When I remove the EL from the ID's, the ajax works!
当我从ID上删除EL时,ajax起作用了!
I'm presuming (though I'm sure BalusC would give a more thorough answer), was that because the id's aren't static, even though the ID in concept would be the same, it was affecting the way JSF finds UIComponents. 我假设(尽管我确定BalusC会给出更彻底的答案)是因为ID并不是静态的,即使ID在概念上是相同的,也影响了JSF查找UIComponents的方式。
Now I feel dumb, because the problem would've been completely avoidable if I didn't add any superfluous elements. 现在,我感到很愚蠢,因为如果不添加任何多余的元素,该问题将完全可以避免。
For example, the code in my original post should be as follows: 例如,我原始帖子中的代码应如下所示:
<h:form id="adminPanel">
...
<f:subview id="editCustomer">
<p class="#{adminService.getEditCustomerClass(customer.id)}">
<h:inputText id="email" value="#{adminService.customerEmail}"/><br/>
<h:inputText id="firstName" value="#{adminService.customerFirstName}"/>
<h:inputText id="lastName" value="#{adminService.customerLastName}"/><br/>
<h:commandButton id="saveEdit" type="button" value="Save">
<f:ajax render="@form" event="click" listener="#{adminService.saveCustomer()}"/>
</h:commandButton>
<h:commandButton id="cancelEdit" type="button" value="Cancel">
<f:ajax render="@form" event="click" listener="#{adminService.cancelEdit()}"/>
</h:commandButton>
</p>
</f:subview>
...
</h:form>
Is there any reason for submitting the form by the Javascript Event onclick? 是否有任何理由通过Javascript事件onclick提交表单? I suggest you to call the action like this:
我建议您这样调用操作:
<h:commandButton id="saveEdit#{customer.id}" value="Submit" actionListener="#{adminService.saveCustomer()}">
<f:ajax render="@form" execute="@form"/>
</h:commandButton>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.