Reputation: 307
I have a MVCPortlet and I try to call ajax in a jsp page.
My jsp is as follows:
<%@include file="/html/init.jsp"%>
<portlet:resourceURL var="updateRatAjax" id="updateRatAjax" ></portlet:resourceURL>
<script type="text/javascript">
function selectRat(){
var rat = new Object();
rat.nom = $('#ratsList').val();
alert(rat.nom + ' '/* + portletURL*/);
$.ajax({
url: "${updateRatAjax}" ,
type: 'POST',
dataType: 'json',
data: JSON.stringify(article),
contentType: 'application/json',
mimeType: 'application/json',
success: function (data) {
alert('ajax' + article.nom);
}
});
alert('end of function');
}
</script>
....
<select class="offset2 span4 form-control" name=ratsList id = ratsList onchange="selectRat()">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<input name = "selectedRat" id ="selectedRat"></input>
My controler portlet resource is as folliws:
public class MainControllerPortlet extends MVCPortlet {
...
public void updateRatAjax( ResourceRequest request, ResourceResponse response)
throws IOException, PortletException {
System.out.println(" updateRatAjax");
}
}
I also tried to call the url this way into the js function:
url:"<%= updateRatAjax %>",
and
var portletURL = "<%= updateRatAjax %>";
url: portletURL,
no chance.
alert(rat.nom + ' '/* + portletURL*/);
oes display
but then nothing so the js method must be stopping when $.ajax({...}) is called.
The issue might have to do with the application not being able to map the resourceURL with the updateRatAjax method. In this project, the actionURL are correctly mapped to the controller's methods without I map them in web.xml nor I use any allocations. I took it that I don't need to map the portlet:resourceURL either, but I might be wrong there. First time I use portlet:resourceURL so I have no knowledge about them.
thx in advance for your assistance.
EDIT: following Sudakatux's answer, I changed the JS function to : ...
var portletURL = "${updateRatAjax}"; // "<%= updateRatAjax %>";//working //
alert(rat.nom + '\n ' + portletURL); //portletURL displays correctly with both options on previous line
$.ajax({
url: portletURL ,
type: 'POST',
dataType: 'text',
cache: false,
success: function (data) {
alert('success ajax' );
},
error: function(http, message, exc) {
alert('error ajax');
}
});
Strangely enough, I get the success message but the controller method is never called :
public void updateRatAjax( ResourceRequest request, ResourceResponse response)
throws IOException, PortletException {
//public void updateRatAjax(ActionRequest request, ActionResponse response) throws PortalException, SystemException {
System.out.println("MainController portlet : updateRatAjax");
}
Upvotes: 2
Views: 1624
Reputation: 48087
Looks good to me - some sanity checks:
alert(rat.nom + ' '/* + portletURL*/);
but not alert(rat.nom + portletURL);
(of course with an initial var portletURL = "<%= updateRatAjax %>";
)?strip=0
to the URL - that makes it easier to read.Upvotes: 1
Reputation: 4730
Yes, you are right, your AJAX call (
resourceURL
) is not getting mapped with appropriate listener in action class.
The problem is that you are highly focusing on linking AJAX call to specific method of the controller based on the its var
attribute for default MVC portlet, like we have feasibility to do in Spring MVC portlet using @ResourceMapping("xxx")
annotation.
See following lines taken from the Multiple Ajax calls liferay portlets:
Adding more in this. We can not use the
serveResource
method likeprocessAction
. There can be multipleprocessAction
in single Liferay portlet(Which is not Spring MVC portlet), while in case ofserveReource
it will be single.
Now, simply override serveResource
as following:
public void serveResource( ResourceRequest request, ResourceResponse response)
throws IOException, PortletException {
System.out.println(" updateRatAjax");
}
Moreover, if you have multiple AJAX calls, you have two options:
1. Filter requests using resourceRequest.getResourceID()
in serveResource
after adding id
attribute to <portlet:resourceURL>
tag, like:
<portlet:resourceURL id="updateRatAjax" ></portlet:resourceURL>
public void serveResource( ResourceRequest request, ResourceResponse response)
throws IOException, PortletException {
if(resourceRequest.getResourceID().equals("updateRatAjax")){
System.out.println(" updateRatAjax");
}
}
2. Filter requests using additional parameter through <portlet:resourceURL>
or AJAX data
:
<portlet:resourceURL>
<portlet:param name="action" value="updateRatAjax" />
</portlet:resourceURL>
OR
data: {
article: JSON.stringify(article),
action: 'updateRatAjax'
},
Controller:
public void serveResource( ResourceRequest request, ResourceResponse response)
throws IOException, PortletException {
String action = ParamUtil.getString(request , "action", "");
if(action.equals("updateRatAjax")){
String article = ParamUtil.getString(request , "article", "");
System.out.println(" updateRatAjax");
}
}
Upvotes: 2
Reputation: 4508
Give This a try
<portlet:resourceURL var="timeSyncURL" id="serverTimeSync" />
<script type="text/javascript">
var serverTimeFunction = function serverTime() {
var time = null;
$.ajax({url: '<%=timeSyncURL.toString() %>',
async: false, dataType: 'text',
success: function(text) {
console.log("updated time "+ text);
time = new Date(Number(text));
console.log("time is "+time);
}, error: function(http, message, exc) {
time = new Date();
}});
So here im calling a service which does have the same signature as your updateRatAjax method. and is working fine for me
This is a less elegant option but it should certainly work Override the serveResource method
@Override
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse)
throws IOException, PortletException {
if(resourceRequest.getResourceID().equals("serverTimeSync")){
PrintWriter out = resourceResponse.getWriter();
out.println(new Date().getTime());
}
The serveResource is for AJAX calls so this will certainly work.
Upvotes: 3