jQuery Mobile and Rails RESTful actions - ruby-on-rails

I'm having a problem with how jQuery mobile works with RESTful actions in Rails.
For this explaination, let's assume I have a resource called Planet and a PlanetsController and I'm attempting to create a new Planet by sending a post request from /planets/new to /planets. If this action succeeds, my URL is now /planets even though it's actually showing /planets/1. If the action failed, my URL is also now /planets/ instead of /planets/new.
In both of these cases, if I click the Back button to go back to the index action, it won't work because jQuery Mobile thinks I'm already on /planets. I have to reload the page in order to get back.
Is there a way to fix this so normal Rails RESTful actions can be used?

I had the same issue as well, I just added data-ajax = "false" to my form with the downside of having no transitions. Or you can follow another solution I found here: http://www.adobe.com/devnet/html5/articles/jquery-mobile-and-rails.html#articlecontentAdobe_numberedheader_1

Related

Refresh a Sitecore rendering after logon

I feel like this should be obvious, but I'm stumped. We're running Sitecore 7.1 with MVC.
There is a Header rendering that includes conditional logic depending on the status of Sitecore.Context.IsLoggedIn. Works fine.
There is a second rendering that either allows the user to log in OR displays account information. When the [HttpGet] acton is called, the controller checks IsLoggedIn and returns one of two views. When the [HttpPost] action is called (i.e. when the user logs in), The controller calls AuthenticationManager.Login() and then returns the view with the account info. Works fine.
It's a simple solution that allows us to place one rendering on the page, and it works great, except for one thing: the header rendering still shows the not-logged-in content immediately after logging in.
Caching is turned off on the header rendering and in the presentation details. When any link is clicked or the page reloads, the header updates to show the correct info. The problem is only after the initial request/response, when the login form submits and returns an alternate view. Although we've had a complete HTTP request/response cycle, it's like Sitecore doesn't bother to check anything except the rendering that was directly affected.
I know I can solve this by returning a hard Redirect() after logging in but that seems inelegant and creates annoyances, like losing ViewBag info.
What I am really looking for is a way to tell Sitecore, "hey, refresh that other rendering!"
The fact that I can find nothing at all on-line about this 'problem' tells me I might be doing something conceptually wrong.
As I see it there are two ways of handling this problem:
FormHandler
You use #Html.FormHandler to specify a Controller and an Action to handle the authentication. The FormHandler action will execute very early (see: https://twitter.com/dmo_sc/status/480001473745399809) in the page execution, before anything is rendered, and all your Renderings will have the same view of whether users are logged in or not.
Martina did a good writeup on Sitecore MVC and forms:
https://mhwelander.net/2014/05/28/posting-forms-in-sitecore-mvc-part-1-view-renderings/
https://mhwelander.net/2014/05/30/posting-forms-in-sitecore-mvc-part-2-controller-renderings/
Post-Redirect-Get
I really want Sitecore MVC to have this feature build in, as it is useful for all form submission scenarios (bar AJAX). The idea is to handle the POST request and work out what you want to respond (and store this in tempdata). Instead of returning a ViewResult you issue a redirect to the same URL, this forces a GET to the page (at this point all the logged in state is same for all Renderings) where you fish the result out of tempdata. Also P-R-G protects against resubmitting POST requests.
cprakash documented his experience doing P-R-G:
https://cprakash.com/2015/01/12/sitecore-mvc-form-post-simplified/
Off Topic: Multiple forms on single page
This will not solve the OP problem, but worth having a look at in this context:
http://reinoudvandalen.nl/blog/ultimate-fix-for-multiple-forms-on-one-page-with-sitecore-mvc/
In MVC, your renderings are executed sequentially, top to bottom. So if your header rendering comes before the login status rendering, it's going to be done before the user is logged in.
The elegant way to do this would probably be to do your post and update both elements via JavaScript. If you want to keep the header logic separate from the login status logic, your login status script could allow other components to register their own callbacks. You could even build out a client-side message bus, if you will be doing this sort of thing frequently.
You could take a look at Jeremy's approach:
https://jermdavis.wordpress.com/2016/04/04/getting-mvc-components-to-communicate/
The key takeaway, I think, is where he switches the order of the placeholders by placing the results into variables and then render them wherever you want them.
#{
HtmlString main = Html.Sitecore().Placeholder("MAIN");
HtmlString head = Html.Sitecore().Placeholder("HEAD");
}
<head>
#head
</head>
<body>
#main
</body>

AJAX in Rails 4, HTML5 history API and caching

I'm moving a Rails app which loads new views through URLs to a completely AJAX version. The way we're doing this is that loading all views through AJAX and changing the URL through HTML5 History API. We also want to use HTTP caching throughout so that we can cache each partial.
But now we're stuck on one issue. There are now essentially two ways to load each page - through the URL or by clicking on something which loads that partial via AJAX. But this has lead us to create two different views and controllers for essentially loading the same thing - one directly from URL and one by clicking in the main page and loading via AJAX and history API. So how do we ensure that the same view loads from the browser cache when loading directly via URL and with AJAX?
To give an example, GitHub uses in their tree slider. You can access code directly by browsing to it in the window or directly using the URL path for it. I'm sure if the page has been loaded before, they get parts of it from the browser cache.
Is there a way to send requests to the same URL but just render a partial or load the whole page depending on whether the request is sent by clicking on the tab or entered in the address bar? It should use cached partials if they are already there in the browser.
Thanks
If I got it right you want to have different behaviours for the same action, one if the request is get and other one with an ajax request.
You can do it doing this:
mypage_controller.rb
def my_page
...(your logic here)
respond_to do |format|
format.js
format.html
end
end
my_page.js.erb
alert('testing');
.... (further ajax code here)
Here is an article that does this behaviour Rails 4: How to partials & AJAX, dead easy
This way you can have the same action responding for ajax and get request

Open new window from GSP and forward to external URL

I need some help. I am converting a Struts application to Grails.
There is a particular action I am trying to convert.
There is a form in a jsp that asks a user to select a customer from a dropdown list and the user clicks one of two buttons.
When the user clicks on the "View Reports" button, an onclick event calls a javascript function that issues window.open on a STRUTS action class, passing the selected customer and selected action.
In the action class the http request has some attributes set (request.setAttribute (..)) and a forward is performed to an external application. The attributes that where set are used by the application for sign on. This is done as a POST.
My problem is I am not quite sure how to wire this flow using the Grails framework. I was able to get as far as the user selecting a customer, clicking an actionSubmit button, reading the selected customer from params, adding my attributes to 'request' and then..I am stuck.
How to open a new window? (Tried javascript way as was done with Struts).
Also I am able to issue a redirect to the external site in the controller, however a redirect is done as a GET and not a POST, as well as the redirect is done in the same window. Any help in laying this out would be awesome. Thanks
You can't redirect a user from server using POST.
I can see some possible solutions:
1 . If you don't need to pass through your server to validate or request some data, you can use this:
<form action="http://someotherserver.com" method="post">
2 . Create a controller that redirect to a page in your own site and in this page make a treatment that receives the paramters and then redirect the user to another domain using ajax.
In Grails, I've used createLink, with the 'base' attribute to do this.
<g:createLink base="${params.dynamicURL}">Link</g:createLink>
I think something like this would work, but you can research it here: http://grails.org/doc/latest/ref/Tags/createLink.html

How to build Preview functionality before form submit in Rails ?

I have a simple scaffold and I want the user to see (preview) the form data before he submits it. It looks to be fairly straight forward problem but surprisingly I am not able to figure out how to do it. I found this but it looks to be somewhat dated (2010 question)
Is there any gem or jquery plugin which can simplify this preview functionality ? any suggestions on how to do it in rails 3.2.x ?
Thanks
It really depends on what kind of "preview" you want to include - either "preview page" or "rendered fragment":
Preview page is what some services are showing: summary of all inputs shown in form of separate page with button "confirm". It doesn't require javascript or anything fancy - just click "next" on form page, see data typed just a second ago and click "confirm" or "back to edit". If this is what you require then you can do it simply by creating new controller action(preview?) which would initialize model with passed parameters(just like "create" action would, but without saving) and generate template with "preview" shown and hidden form that will be passed to "create" action after clicking "confirm". Alternatively you can simply modify "new" form so it would hide form depending on called action and show preview instead.
Second option is "render fragment" - it will live-update part of your current page via javascript. Depending on how complicated this view will be and what kind of operations you will need to do before showing template it might be good to use some javascript plugin or send request to server and obtain rendered partial. In former case you can select from very easy implementations(like this) up to complete solutions dedicated to it. On the other hand if you choose to render it on server then simple ajax request with all params of form should be enough to provide you with HTML output that can be put directly into DOM element.
I don't know about any gem which can do that.
I think showing a modal with jquery and getting data from data-elements is a simple way to go.

Extra refresh after a submit

I know that whenever you submit a form, you will refresh a page. But is there a way of using javascript or whatsoever that allows the webpage to refresh one more time after a submit button is being input?
Thank you guys so much.
I am guessing that what you need to implement is the Post, Redirect, Get pattern, which is the recommended way in Grails applications. if you type grails generate-controller [somedomainclassname], you will see that that controller actually employs this pattern.
It works as follows:
Your form submits to a action inside a controller, let's call it save()
Your save() action then performs the necessary operations to actually save the object, when it is done, it sends the browser a 'redirect', much like this: redirect(action: "show", id: mySavedObject.id)
This will cause the browser to issue a GET for the url /mycontroller/show/{id}
That request is picked up by the show action of your controller. It then goes on to display the object that was just created.
This approach plays well with HTTP semantics and avoids annoying "do you want to repost your form data" questions for the end user.

Resources