I'm using HightCharts library to draw some charts under Play Framework. I've set up an ajax request when the user click on the chart. The request returns a Result with a page rendered. I'd like to perform a redirect to the rendered page.
This is the snippet code of my request:
plotOptions:{
column:{
colorByPoint: true
},
series: {
cursor: 'pointer',
point: {
events: {
click: function (event) {
var jsonMsg = JSON.stringify({category: data.categories[event.point.y], product: data.products[event.point.x]});
$.ajax({
type: 'POST',
url: '#namespace.controllers.modules.routes.MailchimpController.createSegmentByCorrelation()',
data: jsonMsg,
contentType : 'application/json; charset=utf-8',
dataType: 'json'
});
}
}
}
}
}
And this is my return statement:
return ok(template.render(
RolesDao.getRole(session().get("role")),
session("email"),
Template.getList(apikey),
segmentId.toString()));
Any ideas about how I can do it?
With your ajax action you don't can't return the rendered page (HTML code de facto), instead just create link to the page which will render as common Result.
Note: if parameters can contain sensitive data like some credentials, it's worth to add some effort, i.e. in AJAX action save the parameter set in DB or Cache with some unique ID and random security token and return the redirect URL with this ID and security token, later you'll be able to retrieve these credentials using given ID and render the view in your target action. Security token is to prevent the crawlers from unauthorized access.
De facto using built-in cache API you can just put the Result within the cache, so it could be quite fast solution.
Related
I have this interceptor function where I configure my session.
if (request.getRequestURL().indexOf("profile") > 0) {
if (session.getAttribute("access").equals("sub-admin")) {
System.out.println("This is request to profile - admin");
} else {
System.out.println("This is request to profile - user");
response.sendRedirect(request.getContextPath() + "/error"); //ERROR HERE YOU ARE JUST A USER NOT AN ADMIN, I WILL REDIRECT YOU TO ERROR PAGE
}
}
Now I am using jQuery and AJAX in my front end.
If I am just a user and I will access localhost:8080/sample/profile, It will work. It redirected me to the error page.
But, when I access it in my menu in the home page and click profile, it doesn't work.
I think it is because I am using AJAX and the path doesn't change, the view only.
$.ajax({
url: ROOT_URL + '/sample/profile',
type: "get",
dataType: "text"
}).done(function(data) {
$('#idcontainer').html(data);
});
How do you let the session work in my AJAX front end?
If you'd like to handle the redirect from an AJAX call, you can take a look at the following question:
How to manage a redirect request after a jQuery Ajax call
A better solution might be to check if the request is AJAX, and send a JSON response with an HTTP status that you can handle on the frontend:
JSON Response:
{
"error": "Unauthorized",
"message": "You must be logged in to view this content",
"code": 401
}
And in your interceptor:
boolean ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
if (ajax) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(responseToClient);
response.getWriter().flush();
response.getWriter().close();
} else {
response.sendRedirect(request.getContextPath() + "/error");
}
Note that not all AJAX libraries include the X-Requested-With header, but jQuery along with most other modern libraries do.
Then in your JavaScript function:
$.ajax({
url: ROOT_URL + '/sample/profile',
type: "get",
dataType: "text"
}).done(function(data) {
// handle success HTML
}).fail(function (data) {
// parse JSON and alert error message
});
In addition, it seems that you're using the AJAX request to replace the contents of the page with the HTML returned from the AJAX request. Instead of using a JSON response, you could also just return the error HTML instead and display that in the same way that you are returning the profile HTML content:
HTML response:
<h1>Error</h1>
<p class="error">You must be logged in to view this content.</p>
And set the HTML the same way as in your done callback:
.fail(function (data) {
$('#idcontainer').html(data);
});
My problem is kinda weird. I have a JSP page that calls servlet using JQuery/ajax on combobox change. Everything works fine, I get the response but html is displayed as text. Other thing worth mentioning is when I call servlet directly by URL, everything is fine.
Servlet response code:
for(int i=0;i<tabstr.length;i++){
wyjscie.println(i+": "+tabstr[i]+" <br>");
}
JSP ajax call:
$('#com2').change(function() {
$.get('filtr', function(responseText) {
$('#result').text(responseText);
});
});
result is an ID of a DIV inside JSP page. I've done some servlets without ajax in the past and I didn't encounter this problem before. Any idea how to deal with it?
you have to set as html not text try this
$('#result').html(responseText);
I think your server doesn't specify the mime type of the response. So you have to specify it or you can specify dataType in you ajax call.
$.ajax({
url : "myUrl",
dataType : "json",
data : {
param1 : value1,
}
});
ajax api:
dataType: The type of data that you're expecting back from the server. If none
is specified, jQuery will try to infer it based on the MIME type of
the response...
I am using The play framework 2.1.3 and have a question concerning form validation using jquery and ajax. I have followed the advice in this post (http://franzgranlund.wordpress.com/2012/03/29/play-framework-2-0-javascriptrouter-in-java/) for setting up JavaScript routing and that part is working great! I need help with the second part, returning a rendered form containing error messages and displaying it on my page. I have created the following example to illustrate my problem.
The routes file looks as follows:
# AJAX calls
POST /validateForm controllers.Application.validateForm()
# JavaScript Routing
GET /assets/javascripts/routes controllers.Application.javascriptRoutes()
The Application Controller looks as follows:
private static Form<User> form = Form.form(User.class);
public static Result validateForm() {
Form<User> boundForm = form.bindFromRequest();
if (boundForm.hasErrors()) {
return badRequest(user_form.render(boundForm));
} else {
return ok();
}
}
public static Result javascriptRoutes() {
response().setContentType("text/javascript");
return ok(Routes.javascriptRouter("jsRoutes", controllers.routes.javascript.Application.validateForm()
));
}
Without getting too technical, I am using Twitter Bootstrap to render my forms so I have created the following view element (see this post for more information Form validation and form helper) which is rendered by the validateForm action and returns it to the calling jquery.ajax() .
#(userForm: Form[User])
#import helper._
#implicitFieldConstructor = #{ FieldConstructor(twitterBootstrapInput.f) }
#form(routes.Application.createUser(), 'id -> "createUserForm") {
<fieldset>
<legend>New User</legend>
#inputText(userForm("name"), 'class -> "form-control", 'placeholder -> "First Name")
#inputText(userForm("surname"), 'class -> "form-control", 'placeholder -> "Last Name")
<button id="createUserBtn" type="button" class="btn">Create User</button>
</fieldset>
}
I am using jquery and my javascript file looks as follows. For the purposes of this question, assume validation fails and a badRequest is returned.
$("#createUserBtn").click(function() {
jsRoutes.controllers.Application.validateForm().ajax({
type: "POST",
data: $("#createUserForm").serialize(),
success: function(response) {
// something here
},
error: function(response) {
$("#createUserForm").html(response);
}
});
});
Without going into too much detail on the view, I correctly include the JavaScript file in the view and there is an element called #createUserForm.
The communication between client-side and server-side seems to be working great, however, I am unable to load the rendered view element contained in the response onto the page through .html(response). So, how does one accomplish this? Where have I gone wrong? I am fairly new to many of these concepts and would appreciate any helpful input. Thanks.
UPDATE:
Two changes changes will allow this code to work beautifully. (1) Since we are replacing the entire form, including the button, we need to make use of the jQuerys .on() to handle the button click event. (2) Calling responseText property will correctly return the html contained within the result.
$(document).on("click", "#createUserBtn", function() {
jsRoutes.controllers.Application.validateForm().ajax({
type: "POST",
data: $("#createUserForm").serialize(),
success: function(response) {
// something here
},
error: function(response) {
$("#createUserForm").html(response.responseText);
}
});
});
Any comments? How would you do this better?
I am a building project in which I am using java-beans,jsp and servlets. I need to send the response to the client on the same page from where request was made with a slightly modified html. But when I(server) sent the request to the jsp page, the controls in the form are getting reset to their original value. But I don't want to override the user's input after the request was made. One way to achieve this is to take value of the property for each control in the form when request is made and then set them again while responding. Actually there are a large number of controls in my form, taking values of each doesn't seem efficient.
So is there some other way to keep the form in the jsp file unchanged while responding to the client.
you can use ajax for what you are asking, or you have to save the data on form submit, in session or some place and set them back again while responding. Apart from that I think there is no other way you can retain form data even after page reload.
Thanks
Chakri
Why dont you use iframe ? so you dont have to refresh the whole page when the request is made to the same page.
Instead of making the action of the form to the same page, call a javascript function that set the parameters in the link and then
var f = document.getElementById('iframe');
f.src = 'newlink';
f.contentWindow.location.reload(true);
This populated the iframe with the latest content
function openOffenderInfo(i)
{
$.ajax({
url:'../loginServlet',
type: 'POST',
success: function(data)
{
alert("reset your div values in this block");
.... for example .....
documnet.getElementById('reloading Div').innerHTML=data;
},
error: function(data)
{
alert("error");
}
});
}
URL : c=name of the servlet you want to call
this servlet calculates the data and gives the new data you want to reset in your div
success : this is the function which will be executes if your ajax call is made successfully
so you can set the values of your reloading part inside this function
I hope this might serve you the purpose
This is the sample code I am using to hit a URL with fixed time interval.
$(document).ready(function() {
var counter = 1;
$.doTimeout( 1000, function() {
$.ajax({
type: "GET",
url: "<%=encodeUrl%>",
timeout: 10000,
dataType: "text",
complete: function(resp) {
if (resp.status == 200) {
$("#msg").html(counter++);
} else {
$("#msg").html("Failed");
return true;
}
}
});
});
});
Target URL is a servlet which is forwarding the control to another JSP. As per my understanding I must be redirected to new page. But it is showing the same page with the counter value 1. Means, redirect from target servlet is not working. And response is coming back to the same page.
When your AJAX response is a redirect to another page, the redirected page will be fetched as the response of your AJAX request, that's why your are getting only 200 as HTTP status.
You cannot handle redirects based on the HTTP Status codes that you receive with AJAX.
An AJAX response cannot redirect you to a different page unless you program it to do so.
So if you want to redirect based on your AJAX response, you should modify your server side code to send you the redirect URL as a response, rather than redirecting.
Refer one of answers with example solution
AJAX isn't meant to redirect. These headers don't get executed by your browser thus letting you stay on that page!
What is the exact code your servlet gives back?
The code is doing exactly what its written to do. You are firing an ajax call, and on response 200 you are setting counter as html for #msg. There is nothing in the code that'll make you redirect to the New Page.
You do not need ajax here if you want to redirect. Else, if your redirect is based on response returned by the servlet, capture it in complete and set window.location.href = 'your/redirect/url/' to load the New Page.