How to submit form using Ajax request in Liferay?

非 Y 不嫁゛ 提交于 2019-11-27 18:51:11

When making ajax requests on portal your portlet should implemet

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.

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)).

Your SearchResultPortlet class should be

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

<%@ 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

<%@ 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)

<%= request.getAttribute("result") %>

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+.

Step 1: clicking the search button on portletA will trigger the folowing javascript function on the browser:

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.

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).

myEvent is the event fired, this.get('responseData'); are the data retrieved from the server.

Step 3: client side portletB listen on myEvent and render the data

portletB will listen on myEvent and then render the data:

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:

   if(portletId.indexOf('YOUR_PORTLET_A_ID') > -1){...

You can remove that check if you don't have others portlets firing the same event.

Hope this help.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!