ajax 如何在Liferay中使用Ajax请求提交表单?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9272930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to submit form using Ajax request in Liferay?
提问by Scorpion
I am newbie in liferay portal. I have developed one portlet in liferay for demo. I used inter portlet communication in this example. What i am doing is:- I have one search portlet in which i am having one textfield for search. When i click on search button it fetches the data from the database and display that data using search-contained in another portlet. I used ProcessEvent and ActionEvent annotation for this project.
我是liferay门户的新手。我在 liferay 中开发了一个用于演示的 portlet。我在这个例子中使用了 portlet 间的通信。我正在做的是:- 我有一个搜索 portlet,其中有一个用于搜索的文本字段。当我单击搜索按钮时,它会从数据库中获取数据并使用包含在另一个 portlet 中的搜索来显示该数据。我在这个项目中使用了 ProcessEvent 和 ActionEvent 注释。
Now what i want is when i click on the search button then the page should not be refresh(i.e i wish to use the concept of AJAX) and data should be displayed on the other portlet.
现在我想要的是当我点击搜索按钮时页面不应该刷新(即我希望使用 AJAX 的概念)并且数据应该显示在另一个 portlet 上。
Code Snippet
代码片段
Portlet A - view.jsp
Portlet A - view.jsp
<%@include file="/html/init.jsp"%>
<portlet:defineObjects />
<!--
<portlet:actionURL var="actionURL" name="pitchBall"></portlet:actionURL>
//-->
**Change to Resource URL**
<portlet:resourceURL var="resourceURL">
</portlet:resourceURL>
<aui:form method="POST" action="<%= resourceURL%>" name=" <portlet:namespace>fm1</portlet:namespace>">
<aui:input name="search" id="search" />
<aui:button type="submit" name="Search" value="Search" />
</aui:form>
Portlet A - SearchPortlet Class
Portlet A - SearchPortlet 类
package com.test;
/**
* Portlet implementation class SearchPortlet
*/
public class SearchPortlet extends GenericPortlet {
@Override
public void render(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
// TODO Auto-generated method stub
super.render(request, response);
}
@ProcessAction(name="pitchBall")
public void pitchBall(ActionRequest request, ActionResponse response) throws SystemException {
String name = ParamUtil.getString(request, "search");
QName qName = new QName("http://liferay.com/events", "ipc.pitch");
response.setEvent(qName, name);
}
public void init() {
editJSP = getInitParameter("edit-jsp");
helpJSP = getInitParameter("help-jsp");
viewJSP = getInitParameter("view-jsp");
}
public void doEdit(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
include(editJSP, renderRequest, renderResponse);
}
public void doHelp(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
include(helpJSP, renderRequest, renderResponse);
}
@Override
public void doView(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
//super.doView(renderRequest, renderResponse);
System.out.println("In doView code");
renderResponse.setContentType(renderRequest.getResponseContentType());
// file to display...
String url = "/html/searchportlet/view.jsp";
// read the above file and output it...
getPortletContext().getRequestDispatcher(url).include(renderRequest, renderResponse);
//include(viewJSP, renderRequest, renderResponse);
}
@Override
public void serveResource(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
// TODO Auto-generated method stub
//super.serveResource(request, response);
System.out.println("In serveResource code");
response.setContentType("text/html");
String name = request.getParameter("search");
// this seems to be the page that was calling...?
String resourceID = request.getResourceID();
System.out.println("resourceId was : " + resourceID);
System.out.println("message was : " + name);
PrintWriter writer = response.getWriter();
writer.print(name);
}
protected void include(
String path, RenderRequest renderRequest,
RenderResponse renderResponse)
throws IOException, PortletException {
PortletRequestDispatcher portletRequestDispatcher =
getPortletContext().getRequestDispatcher(path);
if (portletRequestDispatcher == null) {
_log.error(path + " is not a valid include");
}
else {
portletRequestDispatcher.include(renderRequest, renderResponse);
}
}
protected String editJSP;
protected String helpJSP;
protected String viewJSP;
private static Log _log = LogFactoryUtil.getLog(SearchPortlet.class);
}
Portlet B - view.jsp
Portlet B - view.jsp
<%@include file="/html/init.jsp"%>
<portlet:defineObjects />
<%
String name = (String)renderRequest.getParameter("name");
%>
<liferay-ui:search-container
emptyResultsMessage="author-empty-results-message">
<liferay-ui:search-container-results
results="<%= KeyurAuthorLocalServiceUtil.getStudentByName(name) %>" />
<liferay-ui:search-container-row className="com.test.model.KeyurAuthor">
<liferay-ui:search-container-column-text name="authorId"
property="authorId" />
<liferay-ui:search-container-column-text name="authorName"
property="authorName" />
<liferay-ui:search-container-column-text name="authorEmail"
property="authorEmail" />
</liferay-ui:search-container-row>
<liferay-ui:search-iterator></liferay-ui:search-iterator>
</liferay-ui:search-container>
Portlet B - SearchResultPortlet Class
Portlet B - SearchResultPortlet 类
/**
* Portlet implementation class SearchResultPortlet
*/
public class SearchResultPortlet extends GenericPortlet {
public void init() {
editJSP = getInitParameter("edit-jsp");
helpJSP = getInitParameter("help-jsp");
viewJSP = getInitParameter("view-jsp");
}
@ProcessEvent(qname="{http://liferay.com/events}ipc.pitch")
public void catchBall(EventRequest request, EventResponse response) {
Event event = request.getEvent();
String name = (String)event.getValue();
response.setRenderParameter("name", name);
}
public void doEdit(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
include(editJSP, renderRequest, renderResponse);
}
public void doHelp(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
include(helpJSP, renderRequest, renderResponse);
}
public void doView(
RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
include(viewJSP, renderRequest, renderResponse);
}
protected void include(
String path, RenderRequest renderRequest,
RenderResponse renderResponse)
throws IOException, PortletException {
PortletRequestDispatcher portletRequestDispatcher =
getPortletContext().getRequestDispatcher(path);
if (portletRequestDispatcher == null) {
_log.error(path + " is not a valid include");
}
else {
portletRequestDispatcher.include(renderRequest, renderResponse);
}
}
protected String editJSP;
protected String helpJSP;
protected String viewJSP;
private static Log _log = LogFactoryUtil.getLog(SearchResultPortlet.class);
}
回答by Martin Gamulin
When making ajax requests on portal your portlet should implemet
在门户上发出 ajax 请求时,您的 portlet 应该实现
javax.portlet.ResourceServingPortlet
GenericPortlet already does but you want to override it, and instead of using <portlet:actionURL />you should use <portlet:resourceURL />fro from action.
GenericPortlet 已经这样做了,但您想覆盖它,而不是使用<portlet:actionURL />您应该使用<portlet:resourceURL />fro from action。
And in your setup you should have search form with hidden field for keywords, and on clicking submit button in search portlet you should copy keywords from that form, with IPC, to search results portlet and invoke submit on search result from (without submitting form in search portlet (A)).
并且在您的设置中,您应该有带有关键字隐藏字段的搜索表单,并且在单击搜索 portlet 中的提交按钮时,您应该使用 IPC 从该表单复制关键字到搜索结果 portlet 并调用从搜索结果提交(不提交表单)搜索 portlet (A))。
Your SearchResultPortlet class should be
您的 SearchResultPortlet 类应该是
public class SearchResultPortlet extends GenericPortlet {
...
public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, java.io.IOException {
// do search and return result
}
...
}
EDIT: complete example
编辑:完整示例
SearchForm
搜索表单
import java.io.IOException;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
public class SearchForm extends GenericPortlet {
@Override
protected void doView(RenderRequest p_request, RenderResponse p_response) throws PortletException, IOException {
getPortletContext().getRequestDispatcher("/WEB-INF/jsp/search.jsp").include(p_request, p_response);
}
}
SearchResult
搜索结果
import java.io.IOException;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
public class SearchResult extends GenericPortlet {
@Override
protected void doView(RenderRequest p_request, RenderResponse p_response) throws PortletException, IOException {
getPortletContext().getRequestDispatcher("/WEB-INF/jsp/result.jsp").include(p_request, p_response);
}
@Override
public void serveResource(ResourceRequest p_request, ResourceResponse p_response) throws PortletException, IOException {
//do your search here and put results in 'result'
p_request.setAttribute("result", "results for: " + p_request.getParameter("search"));
getPortletContext().getRequestDispatcher("/WEB-INF/jsp/html.jsp").include(p_request, p_response);
}
}
search.jsp
搜索.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<portlet:defineObjects />
<script type="text/javascript">
function doSearch() {
Liferay.fire('searchKeywords', document.getElementById("<portlet:namespace/>search").value);
}
</script>
<form>
<input type="text" name="search" id="<portlet:namespace/>search" />
<button name="Search" value="Search" onclick="doSearch()" type="button">Search</button>
</form>
result.jsp
结果.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<portlet:defineObjects />
<portlet:resourceURL var="rurl" />
<script type="text/javascript">
Liferay.on('searchKeywords', function(event, p_data){
var A = AUI();
A.use('aui-io-request', function(aui) {
A.io.request("<%= rurl %>", {
method : 'POST',
data: {search: p_data},
dataType : 'html',
on : {
success : function() {
AUI().one("#<portlet:namespace/>placeholder").html(this.get('responseData'));
}
}
});
});
});
</script>
Search Results:<br />
<div id="<portlet:namespace/>placeholder">
</div>
html.jsp (this is for rendering results)
html.jsp(这是为了渲染结果)
<%= request.getAttribute("result") %>
回答by Tony Rad
You could use Inter portlet communication on the client side. Let's call portletA the search portlet and portletB the search-contained in another portlet. I'm assuming you are using Liferay 6+.
您可以在客户端使用 Inter portlet 通信。让我们将 portletA 称为搜索 portlet,将 portletB 称为搜索包含在另一个 portlet 中。我假设您使用的是 Liferay 6+。
Step 1: clicking the search button on portletA will trigger the folowing javascript function on the browser:
第一步:点击portletA上的搜索按钮,浏览器会触发以下javascript函数:
var A = AUI();
A.use('aui-io-request',
function(aui) {
A.io.request(<portletA_serch_action_url>, {
method : 'GET',
dataType : 'json',
on : {
success : function() {
Liferay.fire('myEvent', this.get('responseData');
}
}
});
}
);
Note the call to A.io.request(<portletA_serch_action_url>...this is the portletA server side action url.
See the following Liferay Blog for more information about Liferay 6 and ajax: http://www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/alloyui-working-with-ajax.
请注意,A.io.request(<portletA_serch_action_url>...对此的调用是 portletA 服务器端操作 url。有关 Liferay 6 和 ajax 的更多信息,请参阅以下 Liferay 博客:http: //www.liferay.com/web/nathan.cavanaugh/blog/-/blogs/alloyui-working-with-ajax。
Step 2: on portletA server response, portletA client side will launch an event with the data retrieved from the server.
Note the call to Liferay.fire('myEvent', this.get('responseData');this is the way in which Liferay supports client side Inter Portlet Communication on the client side(See http://www.liferay.com/community/wiki/-/wiki/Main/Client-side+Inter-Portlet+Communication).
第 2 步:在 portletA 服务器响应上,portletA 客户端将使用从服务器检索到的数据启动一个事件。注意这个调用Liferay.fire('myEvent', this.get('responseData');是 Liferay 在客户端支持客户端 Inter Portlet 通信的方式(参见http://www.liferay.com/community/wiki/-/wiki/Main/Client-side+Inter-Portlet +沟通)。
myEventis the event fired, this.get('responseData');are the data retrieved from the server.
myEvent是触发事件,this.get('responseData');是从服务器检索的数据。
Step 3: client side portletB listen on myEvent and render the data
第 3 步:客户端 portletB 侦听 myEvent 并呈现数据
portletB will listen on myEvent and then render the data:
portletB 将侦听 myEvent 并呈现数据:
Liferay.on(
'myEvent',
function(event, data){
var portletId = data.portletId;
var portlet = data.portlet;
if(portletId.indexOf('YOUR_PORTLET_A_ID') > -1){
alert(data);
}
}
);
Note the check of the provenience of the data from portletA:
请注意对来自 portletA 的数据来源的检查:
if(portletId.indexOf('YOUR_PORTLET_A_ID') > -1){...
You can remove that check if you don't have others portlets firing the same event.
如果您没有其他 portlet 触发相同的事件,您可以删除该检查。
Hope this help.
希望这有帮助。

