ExternalContext.dispatch() not working - jsf-2

On p:ajax call,listener invokes method which contains
FacesContext.getCurrentInstance().getExternalContext().dispatch("/uri.jsf");
doesn't work. Ive set a break point on the line and it remains at the same point on execution.It doesn't move forward, I ve got to restart server to run the application again.
FacesContext.getCurrentInstance().getExternalContext().redirect("/uri.jsf");
redirection works perfectly fine. But i want page forward which is dispatch to navigate to another page.

The ExternalContext#dispatch() does not support ajax requests. It causes JSF to render the HTML output of the given resource which can't be understood by the JavaScript ajax engine. The ajax request has to return a special XML response which can be understood by the JavaScript ajax engine.
The ExternalContext#redirect() supports ajax requests. It will automatically return a special XML response instructing the JavaScript ajax engine to invoke a window.location call on the given URL (you can find an XML example in this answer).
You have 2 options:
Make it a non-ajax request.
Perform a normal JSF navigation.
Making a non-ajax request is most likely not an option for <p:ajax>. In that case, performing a normal navigation is really your only option.
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, "/uri.jsf");
It will in case of ajax requests automatically force an render="#all" with the new content.

Related

difference between Html.BeginForm() and ajax.beginform()

what is the difference between Html.BeginForm() and Ajax.Beginform() in MVC3. I just want to know the scenarios where I can use Html.BeginForm() and where I can use Ajax.Beginform().
Ajax
Won't redirect the form even you do a RedirectAction().
Will perform save , update and any modification operations asynchronously.
Validate the Form using FormMethods - OnSubmit. So you are abort the Post
This creates a form that submits its values using an asynchronous ajax request. This allows a portion of the page to be update without requiring that the entire page be refreshed.
Html
Will redirect the form.
Will perform operations both Synchronously and Asynchronously (With some extra code and care).
Html.BeginForm will always use RouteTable to detrmine the action attribute value.
This will create a form on the page that submits its values to the server as a synchronous HTTP request, refreshing the entire page in the process.
Html.BeginForm() will create a form on the page that submits its values to the server as a synchronous HTTP request, refreshing the entire page in the process.
Ajax.BeginForm() creates a form that submits its values using an asynchronous ajax request. This allows a portion of the page to be update without requiring that the entire page be refreshed.
Html.BeginForm() will use simple posting on page, it means your page will be refreshed when you post your form.
when Ajax.BeginForm() will use ajax posting on page, it means your page will not be refreshed when you post your form.
#Html.BeginForm is used to post the data by full page refresh whereas #Ajax.BeginForm performs Post back function and allows some portion of Html to be reloaded rather than overall page refresh.

Redirection to an external website in a Portlet

I have a portlet where the doView method calls the display.jsp page with the following instruction :
getPortletContext().getRequestDispatcher("/views/display.jsp").dispatcher.include(request, response);
In the display.jsp, I want to do a redirection to an external website :
<%
response.sendRedirect("http://www.google.fr");
%>
Why is it not working at all ?
(I put a <div>foobar<div> in the JSP to see if that works and it does)
Is there another solution to make a redirection to an external URL ?
(The idea is to "stay" in the portlet/portal where the user can see the "targetted" website)
Regards.
If you look at Page 141 of the Portlet 2.0 specification , it mentions that HttpServletRespone#sendRedirect() is a NO-OP in the render phase.
So that is the reason why you don't see this working. As per the semantics, the response object is a HttpServletResponse which corresponds to the response for the whole page and not just the portlet to which this JSP belongs. Since the page is now a composition of multiple portlets and each portlet having it's own lifecycle, you should be using one of the renderResponse, actionResponse objects and avoid using the servlet objects.
I am yet to find a solution for your original problem though.

Rails take base64

In rails i need to take a base64 string, and use it to generate a picture in rails. Now i'm having trouble, because i need to interact with AJAX calls (im strictly working on the server side, another guy is doing that client work) to send pictures. So far i've been taking requests in my application by having data transferred through the url (in the AJAX requests) but now im not sure if it's possible to transfer such a huge string through the url. How could i take in the data (like how could he pass it to me) to generate a picture.
Note: i've been using paperclip for my application so far, but now uploading through the form is not an option, it needs to be in an AJAX call where data is passed in a single call.
You're right, most browsers limit the length of a URL. The limit on IE8/9 is 2083 characters. Even if your particular browser has a higher limit, many servers limit the URL length as well (apache's default limit is right around 8k). It would be best to submit the image as a POST request with the data in the POST body.
I would use jQuery to POST JSON data to the server. In the controller, if this is set up correctly, you won't have to do a thing to parse the JSON. ActiveSupport will recognize the content type and parse it out into the params hash automatically.
Actually posting the data will depend on which javascript library you're using. Here's an example in jQuery, which you'd probably want to wire up to the onclick event of a submit button. This assumes you have a named route called process_image. This code would go in your view.
$.post(<%= process_image_path %>, { b64_img: "your_base64_image_data" });
In your controller, you can access the posted data with params[:b64_img]. If you want to return something from the controller back to the client, you can do this in the controller:
render :json => #model_object
And change the jquery call to look like this so you can do something with the return value:
$.post(<%= process_image_path %>, { b64_img: "your_base64_image_data" },
function(data) {
// do something with the data returned by the controller
});
Hope this helps. You can read more about the jQuery post call I used here: http://api.jquery.com/jQuery.post/
Dan

rails 3: (probably ajax question) need embeddable a banner on a html page that pulls a different 'joke' from our app every N seconds

I've never done ajax stuff myself, and this seems like an ideal feature to add to my app to learn how to do it...
My app maintains a database of jokes.
I'd like to provide a simple way for anyone to add a small banner to the html on their webpage that will display a new joke every N seconds.
It seems the two approaches are:
1) iframe where the url/view hit by the iframe has a meta refresh tag and randomly pulls a joke each time the url is hit. But iframes can resize to fit content, and I'm not sure if browsers will refresh the contents of the iframe.
2) the right way ... ajax. But I have no idea if this is a "big" or "trivial" job for a rails 3 app, and no idea where to get started.
Any pointers on doing this would be deeply appreciated!
I'll use jQuery for this example but the overall technique should work pretty much the same with any other AJAX framework.
In your JavaScript, you'll want to use $.ajax to grab a new quote from your server and setTimeout to get periodic updates; something like this:
var n_seconds = 5; // Or whatever you want.
var timer = null;
function replace_quote() {
// Do a $.ajax call to your server.
$.ajax({
url: '/some/route',
type: 'get',
dateType: 'htm;',
success: function(data) {
// Replace the quote with the new one.
$('#quote-container').html(data);
// And restart the timer.
timer = setTimeout(replace_quote, 1000 * n_seconds);
}
});
}
replace_quote();
If you start out with an empty quote box then you can simply call replace_quote() to give it an initial value through your AJAX call.
You could also use setInterval to call your quote replacer. Then you wouldn't need to manually restart the timer with the setTimeout call but you would run the risk our updates fighting each other if an AJAX call takes longer than n_seconds.
If you still want to provide a link for updating the quote then bind the link to a JavaScript function something like this:
function manually_replace() {
clearTimeout(timer);
replace_quote();
}
Calling clearTimeout will, effectively, reset the timer when they change the quote themselves.
Then, in your Rails app, you'd add a route for /some/route and the controller would simply grab a random quote from your database and then use render :partial => 'quote' to send back just the HTML snippet for the quote without all the usual layout wrapping.
Handling AJAX requests in Rails (or any other framework) is pretty much the same as handling any other request, the only difference is that you won't send back a full page, you just send back a little piece of HTML or a blob of JSON (or XML) for the client to process and render. Hence the size difference between the client-side and server-side outlines above.

rails ajax redirect

Here is my use case
I have a search model with two actions search_set and search_show.
1 - A user loads the home page which contains a search_form, rendered
via a partial (search_form).
2 - User does a search, and the request goes to search_set, the search
is saved and a redirect happens to search_show page which again
renders the search_form with the saved search preferences. This search
form is different than the one if step1, because it's a remote form
being submitted to the same action (search set)
3 - Now the user does another search, and the search form is submitted
via ajax to the search_set action. The search is saved and executed
and now I need to present the result via rjs templates (corresponding
to search_show). I am told that if the request is xhr then I can't
redirect to the search_show action? Is that right? If yes, how do I
handle this?
Here is my controller class
http://pastie.org/993460
Thanks
That's right. Either make the request non-XHR and redirect as normal, or you could try rendering the URL you want to redirect to as text or part of a JSON object which your AJAX request then uses to call document.location.href = [whatever] (but this seems hacky).
Right now what's happening is your XHR request is returning the result of the redirect, and not actually redirecting the page that made the XHR request.

Resources