Rails 3 - Ruby running within JS if - ruby-on-rails-3

Why is ruby code ran even if its within an jQuery if statement?
I'm working with a modal (twitter bootstrap) and setting a session when the modal is shown/hidden, the modal has this code:
$("#modal").on("shown", function () {
<% session[:modal] = true %>
})
...
$("#modal").on("hidden", function () {
<% session[:modal] = nil %>
})
What I want is to set the session when the modal is opened, so a method knows when its opened, and set it to nil, so the same method knows when its closed.
Thanks.

Your ruby code is being run on the server and javascript in the browser. So all ruby code executes before javascript.

If you want the client modify something in the rails session, you'll need to send an ajax request to the server.
Another option might be to use session cookies instead of using the rails session. Session cookies are great if you're just setting little bits of data inside the browser. There's a few cookie plugins for jquery. Here's one on github. You could do something like this:
$("#modal").on("shown", function () {
$.cookie('is_modal', '1');
})
Update: I just read your other comment. If you're doing server logic based on that value, then yeah, you'll need to tell the server with an ajax call.

Related

Multi-web server ajax callback with refresh on Enter

Question about how to send a jQuery callback with an onSuccess: refresh from a textInput when the user presses [Enter]. We use the [Enter] press to trigger a search callback.
Our GS Seaside app uses HAProxy. This means the onSuccess: script is handled by a different gem than the one that handles the callback. Because of this, users will sometimes get the refresh because the callback, which to them looks like a lost input (a browser F5 refresh shows the right state). If running single gem or in a VW / Pharo image this problem does not come up.
I can work around the problem by using...
async: false;
...but that prevents me from show any kind of waiting feedback (I normally use a busy gif).
So, the question is: in a multi-web server configuration, how can you code a callback to...
1 - show a busy gif
2 - trigger the search callback
3 - refresh the display when done
...all in that order.
Using a form submission callback is a problem because multiple text inputs can trigger the search, since the callback is 'set value + do search', by virtual of the default [Enter] press.
For the JS callback, I'm using...
self onKeyPress: (
(JSStream
on: '(window.event ? window.event.keyCode : event.which) == 13')
then: (canvas jQuery ajax callback: aBlock value: canvas jQuery this value))
It all works fine, except for the missing busy gif, due to the 'async: false'.
Any suggestions?
You can define a beforeSend and a complete handler to show and hide the loading indicator while the request is being processed. The global parameter set to false is meant to ignore your existing handlers to process request start and end (the mentioned spinner), and only use these defined in the particular instance of the JQAjax object.
((html jQuery ajax)
async: false;
global: false; "https://api.jquery.com/category/ajax/global-ajax-event-handlers/"
callback: aBlock value: canvas jQuery this value;
onBeforeSend: (html jQuery id: 'indicator') show;
onSuccess: ((html jQuery id: 'fieldId') load html: [:h | ]);
onComplete: (html jQuery id: 'indicator') hide;
That said, keep in mind that doing a synchronous AJAX call is discouraged since it will block the whole UI thread until the request is resolved.
So it's not completely clear how you manage the state in different worker images (gems, in this case) returning different things (probably because of having different sessions), so it's also not clear to me why doing an async XHR request will be served differently to doing it synchronously, I never experienced that.
From the small sample you mention, it can't be deduced what is the "refresh" part of your code. So maybe, providing more context will help us give you more accurate answers.
Fix ended up being trivial: needed to include 'event.preventDefault();' in the [Enter] key script. Seems obvious in hindsight.
if ((window.event ? window.event.keyCode : event.which) == 13) {
event.preventDefault();
};'
This problem is confirmed to be a narrow configuration symptom: GemStone with multiple gems. On every other configuration Seaside / javascript behaves as expected. I will follow this up as a vendor problem. Thanks to everyone that looked at it (this was also posted on other forums).

How can I transition to a non-ember URL from a router action?

I'm in the process of transitioning a standard Rails app over to an Ember app with Rails API. This is an incremental process so for the short term users will be switching back and forth between the newer parts of the site (using Ember) and the old legacy views.
At one point, in the ember app, the user creates a new 'Plan' model
plans/new.hbs
<button {{action createNewPlan}}>Create Plan</button>
After the plan has been successfully created, I want to transition to plan/show view ON THE OLD Rails app.
I've defined the createNewPlan action in the plans_new_router, rather than the controller, as I understand the router should be responsible to tracking application state.
plans_new_router.js
App.PlansNewRoute = Ember.Route.extend({
events: {
createNewPlan: function() {
var newPlan = this.controllerFor('plans_new').get('content');
newPlan.get('transaction').commit();
// how can I transition to plans/show in the old rails app ????
}
}
}
I'd like to transitionTo the plans_show view on the old rails app after the model has been saved. How can I do this? transitionTo requires an ember route, I take it. But what I want to do is reset the brownser to the appropriate rails URL with the new plan id. I'm guessing transitionTo isn't what I want to use.
How do I do it?
window.location = maybe? You probably want to wait until the response though? If you do, I think ember-data is becoming promise-based really soon, or master might already be, not too sure.
If it's not yet, you can addObserver to the id property of newPlan and when it changes, set the window.location

Remote AJAX call when checking a ceckbox in Rails 3

If I have a checkbox in Rails3, How can I perform a remote AJAX call when the user changes the value of it.
It sound like a simple task, but I fail to find a good solution for it.
You can pass the value of check-box on change event to the form and by using :remote => true you can use AJAX in form_for.syntax of on changing the check box and submitting the form is ":onchange => "this.form.submit()
I hope this would help you.
Thanks.

Changing HTTP method to POST with link_to

I'm using Rails 3.1 here, and I've got the following code in my view:
<%= link_to "again!", main_pick_path,{:method => :post, :var => #var} %>
The idea is to create a link (not a button) which, when clicked, calls the pick action of the main controller, passing the value of #var in params via a POST request.
This code generates the following HTML in my browser:
a href="/main/pick" data-method="post" rel="nofollow" var="foo">again!</a>
However when I click the link I am still sending a GET request. Is this a limitation of my browser, Chrome? From a design standpoint, should I be using a GET request instead and putting the variable into the URL? Are hyperlinks simply incapable of using the POST method? Is there life after death?
Thanks in advance
You can only do this with AJAX or firing a FORM. The tag A cant do a POST "alone".

Rails: periodically_call_remote then redirect

I need to check some database values with a periodically_call_remote function.
I want to redirect if some values have already a certain state.
How to do this? redirect_to in the function does not seem to work.
Do you need to do a refresh on the entire page? You could use javascript to update your content.
The following javascript may work as well.
window.location = "http://www.address.com/"
redirect_to in the return function does not work because it redirects the ajax request to the new page, it doesn't tell the browser to redirect the entire page. You will need to either render back some javascript in the controller that causes the page to redirect, or better: add a callback to the periodically_call_remote call that checks the return value and runs the javascript that Ben suggested.
Check this thread:
Rails 3 equivalent for periodically_call_remote
The first answer to use javascript setInterval worked perfectly.