I am using Rails and jquery, and I need a dynamic content with ajax.
But I don't know how to get the current user ID
For example the url is www.mywebsite.com/users/20
In my javascript file I need the user ID (20)
$.get("/users/<%= **20** %>.json", function(data)
{
}, "json");
Thanks in advance for any help.
Is there another way to do this ?
Generally i put a hidden field with the id somewhere in the page, where i can easily access with $("#user_id") on the javascript file, then the request would be something like this:
var id = $("#user_id").val();
$.get("/users/"+id+".json", function(data) { }, "json");
You can assign the rails variable value to a javascript variable in your view file like
"<%= javascript_tag "var userId = #{#current_user.id};" %>"
and access the variable inside js file wherever you want.
$.get("/users/<%= params[:id] %>.json", function(data)
{
}, "json");
Should do the trick.
Include the snippet into the .erb file or create a .js.erb partial with this.
Lots of choices:
If you have a current user object with the id (Note: this must be in a file ending with .js.erb):
$.get("/users/<%= #current_user.id %>.json", function(data){...}, "json");
If you don't want to use a .js.erb file, but still need the value to be set somewhere on the page, then set a data-attribute or hidden input with the id value.
If you have the id value in the url (as in the current url you are on looks like www.mywebsite.com/users/20 and you want the GET request to use 20 as the value), you can use document.url or window.location.href and some string manipulation to get the id.
Try
<%= escape_javascript(params[:id]) %>
I'm not completely sure if escape_javascript is necessary or will help.
Related
There are two ways I know of to pass variables defined in a controller (/action) to JS...
The official way is
.js.erb:
var banana = "<% #banana %>"
Another way (that I'm currently using is)
.html.erb
<span id="banana-variable" style="display:none"><% #banana %></span>
.js
var banana = $("#banana-variable").html()
This js file is loaded on multiple actions/views across the controller. It makes sense to me to not use a .erb extension: users cache it the first time they hit any action/view in the controller. They then won't have to download different versions of the file when they browse to different pages. Am I right?
Yes, are right. The javascript will be cached on the client's browser.
Still you want to send data on the 'js' or script files you can use this gem called Gon.
http://railscasts.com/episodes/324-passing-data-to-javascript
I recommend you use gem 'gon', which is thoroughly introduced in RailsCast. It makes your controller cleaner. Your method will make it more troublesome if you're trying to pass an array or hash to js.
I think your issue is that you are using <% %> which will execute the code, instead of <%= %> which will execute the code and render the result back into the template.
With Gon you can access the page only after the html page is loaded. From what I understand it uses web page as a proxy to transfer data from rails server to javascript.
But if you want to use the variable at any point of time you want, you can do an ajax(post) request from javascript to the rails controller and retrieve the value as json.
Example:
AJAX Request:
$.ajax({
type: "POST",
url: <PageURL>,
async: false,
dataType: 'application/json',
success: function(data){
data = JSON.parse(data);
},
});
your "data" will contain the returned value.
On the controller side it should be:
Controller:
def <PageURL>
render :json => {:result => <value_you_want_to_return>}
end
Do not forget to define the controller's path in routes.rb file.
I'm trying to get data from my controller into a javascript file in a rails application. The html immediately invokes an ajax request using the select option and the organization id as parameters.
In a before_filter I have
def set_org_id
if params[:id].present?
#org_id = klass.find(params[:id]).id
else
#org_id = 0
end
end
And in the js file I have:
$.ajax({ url: "/admin/analytics/filter",
type: 'GET',
data: {
time_frame: selectedId,
organization_id: <%= #org_id %>
}
})
If I hard code a number as the organization_id everything works fine, but when I try to pass the data from the before filter, I end up with no id in the page.
I should add that the index route is admin/analytics/. The filter action is admin/analytics/filter. The user never navigates to that page, only ajax hits the filter route to get relevant data. Could this be that the ajax request is being send before the instance variable is set? If so, what is the proper solution?
Your JS won't be able to access your #instance variablesunless you call them from your controller itself. The problem here is that if you're loading the ajax to access an instance varialbe - which simply won't work.
Let me explain...
JS
Javascript is known as a client side language - meaning it provides you with the ability to access elements in your HTML / DOM with relative impunity. The problem here is that Rails / Ruby, much like PHP, is server-side, and consequently is only able to provide rendered data to your browser
This means that calling the following simply won't work:
data: {
time_frame: selectedId,
organization_id: <%= #org_id %>
}
As explained, the reason for this is that you cannot access the #org_id from your Javascript. Firstly, you don't know if the #org_id variable will be set (in case you want to use the Rails helpers), and secondly, your JS won't be able to access the variable anyway (because it's Rails)
--
Fix
The purest fix for this is to somehow create the data you need in the DOM. I see from your answer that you have set a hidden field for your form. A much better way to do this is to set an HTML5 "data" attribute, or to use an id
You'd be better doing this:
<%= form_tag route_path, data: { org_id: #org_id } %>
This will give you the ability to call:
$(document).on("submit", "form", function(){
$.ajax({
...
data: {
time_frame: selectedId,
organization_id: $(this).data("org_id")
}
});
});
I was able to solve this by passing the data to a hidden field in the html.erb page.
<%= hidden_field_tag('org_id', #org_id) %>
Then in the javascript refer to the data through the selector.
organization_id: $('#org_id').val()
I don't love this, but at least it works.
I have a URL like this for each record:
http://localhost:3000/items/3/stuff.json
http://localhost:3000/items/1/stuff.json
http://localhost:3000/items/4/stuff.json
http://localhost:3000/items/9/stuff.json
when on a page such as http://localhost:3000/items/3/, the linked JavaScript file has code like this:
$.getJSON(document.URL+'/stuff.json');
this allows me to grab the JSON file without worrying about the record ID number.
The problem arises on a URLs such as:
http://localhost:3000/items/3/news
http://localhost:3000/items/3/photos
as this:
$.getJSON(document.URL+'/stuff.json');
will be looking for:
http://localhost:3000/items/3/news/stuff.json
which of course, does not exist.
Any ideas for how I should solve this?
You can use
$.getJSON("../stuff.json", function(data){
});
if current url is "http://localhost:3000/items/3/anything"
EDIT:
$.getJSON(document.URL.match(/\/items\/\d+\//) + "stuff.json", function(data){
});
If all the urls are of the form http://host/items/id/anything
If this JS is rendered at all by Rails (i.e. it's not something that comes from the Asset Pipeline) then you can use the routing helpers, like this:
<script>$.getJSON("<%= item_news_stuff_path(3, :format => :json) %>")</script>
This would generate a relative-to-root path to the resource, building the route up correctly.
I have 2 text fields. One is for the input of a member's id, and the other is the output of the member's name.
When I type a member's id in the first field and the action onblur is triggered, I would like to show the member's name in the other field.
This is my Javascript function:
function show_name(){
id = document.getElementById('id_member').value;
field_name = document.getElementById("name_member");
field_name.value = "<%= Member.find().nom %>";
}
In the method Member.find() I would like to send the value of the variable id that I've declared at the beginning. Example:
field_name.value = "<%= Member.find(*Javascript "ID" variable value*).nom %>";
How can I insert that value into my Ruby injection?
Thanks.
Javascript is run on the client, ruby is run on the server. You can't pass a javascript variable into the ruby code, unless you make a new request to the server.
Your options are to reload the whole page with a new query, use ajax to make a new query and do something with the result, or to download all possible Members into the page ahead of time and have javascript pull it out of the page somehow.
I have an html text-area which uses ajax-autocomplete where it populates the dropdown as i start typing. When I select an entry from the dropdown it will set some field to the id of that object.
Once I get the id of the object is there a way I could do something like this?
<% #myObjects.find(1) do |myObj| %>
<h1><%= myObj.attr1 %><h1>
<h2><%= myObj.attr1 %><h2>
<% end %>
Right now, when I get the id of the object I am using jquery's attr() function to set the values which exposes my javascript logic which I don't really like. Is there a way I can activate the field? Or, hide the fields and where the id is populated show the field and let ruby do its magic with myObjects.find?
UPDATE:
Right now the way I am populating the fields in the view like this:
$(function() {
// Executes a callback detecting changes with a frequency of 1 second
$("#id_element_placeholder").observe_field(1, function(){
//alert('Change observed! new value: ' + this.value );
$.ajax({
type: "GET",
dataType: "json",
url: "/myobj/get/" + this.value,
success: function(data){
$('#last_name').attr('value', data.myobj.last_name);
$('#first_name').attr('value', data.myobj.first_name);
}
});
});
});
Is there a way around exposing the above javascript code?
There is nothing wrong with your javascript and you seem to be confused between client side and server side technologies. Ruby cannot directly update your page once it has been sent to your user. It is on your web server and your page has been sent to the clients browser. It can however send javascript in response to a further request made by your application from the clients browser to do exactly that, just as you are doing.
You could send a new html snippet to your browser and replace the entire node but really there is no point. What you are doing is the same as everybody else who uses javascript.
Answer is simple, you can't :)
What you are doing is ok, using AJAX for such things is the way to have such a things done.
If you are concerned about exposures don't look at javascript, look at what the server side code allow a user to do with get/post methods ;)