Actually I have two, three questions but the heart of three question is same as written in Title . But I make my all points clear here in description
Following will be the specification of my question
Javascript file path => assets/javascript/
js.erb file path => views/customers/index.js.erb
view file name => views/customerS/html.erb
controller name => customers
action name => index
point # 1
If I make ajax call to my customers/index through my javascript file (with the mentioned path) then will it hit the index.js.erb file ?
point # 2
can we use js and js.erb file for the same action . what i mean is 'is it possible to send ajax from js file in assets folder and after controller action say index method handle the response in index.js.erb file in view folder ?'
point # 3
Say we can handle the response in index.js.erb file then how can / or if we can stop sending back the response / data in js file
if I have missed some more related points then kindly edit the question and place those , so that maximum people can enjoy the knowledge
Also have a look at This question and answer if you can
Update
I made a small experiment , by keeping the same function as mentioned in the
1: linked question , if ajax is sent through js file then js.erb doesn't do any thing but if i made the ajax call using the :remote => true , then it hits the js.erb file . Any explaination will be appreciated . For having a look at code sample in js, controller and js.erb kindly see the linked question
I think some language barrier is making it hard to completely understand your question by I'll try an answer.
The flow in Rails for :remote => true is this:
click on :remote => true link (foo) -> AJAX call is made to the controller requesting it to execute foo -> the controller executes the code contained in the foo action, it will then look for a file in the same view's folder called foo.js.erb and execute that JS -> that code will update the portion of the original HTML page using a file called foo.html.erb in the same view's folder.
Any call to a JS function contained in assets/javascript/ will just execute the JS called, whether it is AJAX or not.
So assets/javascript/ = a place to put JS code instead of putting it in <script> tags in the HTML file
:remote => true = an AJAX call to a specific controller action that then renders a similarly named .js.erb file and .html.erb file to update the page asynchronously.
Actually the flow of assets pipeline and js.erb files is much different . All the thing asked in the question is
what is difference if ajax is called from assets pipeline and if ajax is called through :remote => true . Now the answer is
,"There is almost no difference in the sense of functionality but there can be some minor (but in some case) very important differences depending upon our rendering methods and codes in js and js.erb files" e.g
If I make the ajax from the view i.e by using :remote=> true , then It'll simply goto controller action, perform whatever is defined , after that looks into js.erb file and finally the html.erb file . That's it . Here no assets js is looked for .
Now there is case when we make call from assets javascript , there are two cases for it .
First case is that i want to handle the response in the same js file from where the ajax is sending then no worries , control will come back to success function by default , so don't specify the respond_to method in the controller's action .
Second case is , when we want ajax to be fired from assets javascript , but want to handle the response in the js.erb file then specify the respond_to as below
respond_to do |format|
format.js #{ render 'index.js.erb' }
format.html
end
Now it will hit to js.erb file also . Point to remember is control of program will get back into assets success function also but at this scenario , response will contain the data present in the js.erb file instead the data of controller function
From the above explanation one should remember that assets js is
called before getting into rails controller while js.erb functionality
is performed after the rails controller has finished it's work .
Related
Some clarifications first.
I'm trying everything on local development environment.
In my UsersController I have a summary_csv method that builds a csv file and stores it in the /tmp/your-csv-file.csv location .
Once the system checks that the file is ready for download, I have a summary_csv.js.erb file that runs some javascript to help the user download the file, specifically, in summary_csv.js.erb, I try to do window.location="/users/download_csv"; and there is a download_csv method in the Users controller.
So I want the download to happen, but not sure about 2 things:
How should I configure routes.rb for this download_csv method
so that the download happens without throwing some kind of 'missing
views' error? (at this point I don't care whether user has to
directed to another view or can stay on the same page).
What should go into the body of download_csv method so that
window.location="/users/download_csv"; will initiate the download,
for the file located at /tmp/your-csv-file.csv?
1) Put a get method inside users resource and collections like this
resources :users do
collection do
get 'download_csv'
end
end
2) You just need to send_file, passing your file path to it, since it's ready.
Result
def download_csv
send_file(
"/tmp/your-csv-file.csv",
filename: "your_custom_file_name.csv",
type: "text/csv"
)
end
I ended up finding out the solution. Thanks to all who offered help
So window.location was the best method to use after all.
1) Set it to controller/method .
2) send_file appropriately in the body of the above method .
3) Set the correct routes in the right order.
Step 3 was critical to getting it work.
The route for controller/method must be configured exactly to not make Rails confused as to where it should route your action.
resources :users do
collection do
get 'download_csv' => 'specify which controller#which_method_name'
end
end
I have a js file called create.js.erb that is in my view folder. It's supposed to be called when I try to create a record, but it isn't being called. I can't figure out why, and to be totally honest, don't even know how my app calls a js file in the view folder, so I'm not sure what code to paste here to help debug the problem.
Can anyone explain to me how js in a view folder is executed, and when I would want to put a js file in my view folder instead of in the asset pipeline?
*.js.erb files are rendered when you are using AJAX/JS with your controller actions. By default, when you call the create method, Rails will respond using HTML. This will load a new page. Sometimes you want to use AJAX instead, and that's why you create js.erb files in the view folders.
For this to work, the form and/or link_to objects you are using must be AJAX enabled (they should have a :remote => true attribute on them) If they are not specified as remote forms, they will execute the HTML instead of the JS and the create.js.erb file will never be called.
Your controller method also needs to know how to respond to js requests. You need something like:
respond_to do |format|
format.js
end
That code tells Rails to look for a file called "method".js.erb in your view folder, so in this case, create.js.erb.
These files are completely different from regular JS files you put in the asset pipeline -- these are view templates to be rendered as the result of a controller action.
You might find some Rails/AJAX tutorials helpful...here's a pretty good one that walks you through this whole process:
http://net.tutsplus.com/tutorials/javascript-ajax/using-unobtrusive-javascript-and-ajax-with-rails-3
Hope that helps, if you need more assistance please post the code for your controller and any of the view files...
I have a JavaScript file to use with a view. There needs to be Ruby code in it, and I need to do render in Ruby, so I understand that I can't put the JavaScript file in the asset pipeline. I can put it in the same view folder as the .html.erb file.
How do I include the JavaScript file, or use that JavaScript file for that view file? I tried javascript_include_tag in my view (that uses the asset pipeline apparently), using script src="myfile.js" for the myfile.js.erb file (but it can't find myfile.js), and names my js.erb file (users.js.erb) the same as my .html.erb file (users.html.erb), but all to no avail.
javascript_include_tag won't work js.erb declared in the view folder itself. There are three different ways you can have the javascript.
1] Write the code in the view, i.e., in the html.erb itself.
2] Create js file in public/javascripts folder and include it using javascript_include_tag.
3] In case you want to make the request as Ajax:
Create the js.erb in the view folder itself with the same name as that of the action.
In the view where some form is created which will be calling this action, make the request using :remote => true.
In the called action, use code as follows:
def action
respond_to do |format|
format.js
end
end
you can do this by
render :partial => "myfile"
you have to keep your file in controller's view directory with name _myfile.js.erb
Now you can write your own code (js,ruby) here and probably can separate out js with javascript_include_tag to avail asset pipline
This file will be first rendered by erb engine and then as javascript.
RoR has controllers that render views. One day I wanted a controller not only to render a specific view, but also to run some javascript code using data from contoller (#product, for example) after rendering.
1. Inline javascript
So I went to my products/show.html.erb and wrote something like:
<%= javascript_tag "alert('#{#product.name} is just awesome!')" %>
2. Assets with server data
But we're all grown up boys and know about unobtrusive javascript, so I included some javascript files to my layout:
<%= javascript_include_tag "#{params[:controller]}/#{params[:action]}" %>
and then went to app/assets/javascripts/products/show.js.erb and wrote:
$(document).ready(function(){
alert('<%= #product.name%> is just awesome!');
});
But than I remembered that assets are being precompiled in production and continued to think.
3. HTML data attributes
Another way to pass some data to javascript is by using html5 data attributes in view files:
<div class="product" data-product-name="<%= #product.name %>">
Then in your asset you can write something like:
$(document).ready(function(){
$('*[data-product-name]').each(
alert($(this).data('product-name') + ' is just awesome!');
);
});
4. One more request to server
Anyway if you want to be able to cache your view files and assets, it seems as if the only way to transfer data to javascript is by using an additional Ajax request. I wonder if it is good practice to create a separate action that will send #product to client?
Can anyone say, what is the nicest way to send data from server to a javascript while rendering a view and why?
I am new to Rails but I come from PHP, in which it was almost always the case that whenever I have an HTML AJAX response, I can always load it in a container(any element) using jquery's .load()
I did that with Rails too, but recently came into another approach: use .js.erb files. Use getScript() to a controller action, then the js.erb file will respond to the js (ajax) request, the do the loading in the .js.erb file.
given general.js:
$.getScript(url, function(){});
given index.js.erb:
$('#products').html("<%= escape_javascript(render_cell :products, :index, {:products => #products})%>");
but this appears to be quite repetitive when I can do the loading in general.js! Fire an ajax request to this template that a controller has and load that in a container(I can use jquery .load()'s selector to just select the elements I want, and I can use an application_controller condition to not render the layout):
<ul>
<%= render_cell :products, :index, {:products => #products} %>
</ul>
Is there any way I can make more effective use of .js.erb files in this case?
Note: I had to use the 2nd approach because I am using twitter-bootstrap tabs. I initially used the first approach but I think the 2nd way is more "the Rails way". This is a learning project so why not? XD