How to render a partial from an assets Javascript - javascript

I am trying to render a partial from a javascript in my assets directory. I found that I can't call the render method within the assets directory. But I cant move my ajax command out of the assets directory either. So my Question is now, how to pass my ajax result onto the action.js file in my view.
So I call the ajax on a onclick jQuery event:
/app/javascript/mymodel.js.coffee
$(document).ready ->
---some actions ----
$('.myid').click ->
---some action---
$.ajax 'mypath'
dataType: 'json'
success: (result)->
---render result in partial on myid-div---
So how do I pass my beloved result and myid onto:
/app/views/mymodel/show.js.erb
$('.myid').html("<%= escape_javascript( render( :partial => 'myartial') ) %>");
To render it out?
I'm banging my head around this for quite some time, so I would really appreciate some help!

You can call the mymodel controller's method to render your partial, but the file name of partial should start with an underscore _
In your example, these code render :partial => 'show' may work for your to render js if you put them into mymodel controller and you should rename show.js.erb to _show.js.erb in the view of mymodel.
To be optimistic, you should be able to render the _show.js.erb and you can see somethings like render _show.js.erb successful inside your terminal.
But It doesn't means that the rails was processing the js.erb as javascript, because there are syntax error in your js.erb ( I am absolutely sure!! ).
So you may also change
$('.myid').html("<%= escape_javascript( render( :partial => 'myartial') ) %>");
to
$('.myid').html('<%= escape_javascript( render( :partial => 'myartial') ) %>');
Check out my questions for more details. I faced the similar problem before.
It will also show you an example of how to send a ajax call and render .js.erb.
:remote => true will send a ajax request to line_items_path.
And according to the routing, it will call the create method, format.js will render create.js.erb by convention. Alternatively, I can render the js.erb with format.js {render :partial=> "create"} if _create.js.erb exist

$(document).ready ->
---some actions ----
$('.myid').click ->
---some action---
$.ajax 'mypath'
dataType: 'json'
params: (pass in what you need, i don't know the exact syntax, just google it)
success: (result)->
---render result in partial on myid-div---
controller
def show
#result = params[:result]
end
view
show.js.erb
$('#some_id').html('<%= render("mypartial").html_safe %>');
#result is accessible now
Pass your result as a parameter from your AJAX call to your controller method. Then instantiate an instance variable (#result for example from the parameter), that way your views is not able to use the instance variable.

Related

The right way to do remote (ajax) calls in Ruby on Rails

I'm making a Single Page Application with Ruby on Rails (it's my first ruby project ever so I'm definitely missing a lot of stuff yet).
So I have a side menu with some links and the right part of the page is supposed to hold a container which is meant to be filled with some content of partial pages.
The typical menu link I have now looks this way:
<%= link_to t('my-groups'), :controller => 'dashboard', :action => 'mygroups', :remote => true %>
I have a dashboard controller, here's the simplified version of it
class DashboardController < ApplicationController
def mygroups
respond_to do |format|
format.js
end
end
I have a dashboard template with the container div in it
<div class="right_col" role="main">
<h2>This is the default content of center page</h2>
</div>
And here's the routes.rb path for it:
get 'dashboard/mygroups' => 'dashboard#mygroups'
I also have one partial page alogside with my dashboard template and it's called _mygroups.html.erb and a javascript file mygroups.js.erb which is called as my controller action
look at the screenshot of the structure
The contents of this js.erb file are:
$('.right_col').html("<%= escape_javascript(render(:partial => 'mygroups')) %>");
It all works and the partial contents appear inside the container on link click just fine.
But there are still 2 problems I couldn't google the answer for
The questions part:
1) It works with Ajax call but if I simply put this http://localhost:3000/dashboard/mygroups to my browser's navigation line and hit enter, it will give me this error
ActionController::UnknownFormat in DashboardController#mygroups
ActionController::UnknownFormat
Extracted source (around line #70):
def mygroups
respond_to do |format|
format.js end end
How can I avoid this and just redirect to index in this case?
I understand that ajax uses POST, but I tried to use post instead of get in routes.rb for this action, and it didn't work at all
2) What if I have a lot of actions for different partial pages, do I have to create a new js.erb file for each action? Can't it be done in some simplier way with just one file?
3) Is it possible to not specify controller and action on this link explicitly?
<%= link_to t('my-groups'), :controller => 'dashboard', :action => 'mygroups', :remote => true %>
I mean since it's supposed to be a POST ajax request, how come I need to display the url like this http://localhost:3000/dashboard/mygroups to a user?
Add format.html in controller like:
class DashboardController < ApplicationController
def mygroups
if request.xhr?
respond_to do |format|
format.js
end
else
redirect_to root_url
end
end
you can add url in link_to tag like:
<%= link_to t('my-groups'), '/dashboard/mygroups', :remote => true %>
Answers to you questions
When you hit the URL in browser, it sends vanilla HTTP get request(non-ajax) which your controller action is not configured to handle it. You need to add format.html and template named groups.html.erb where generally you will list all the groups, I guess.
respond_to do |format|
format.html
format.js
end
Ideally you have to create separate file for each action but if you can take something common out of different action then you can move common template code to a partial and render it either in a separate template having something special or from the controller action directly.
Yes. The rails way is to use routes helper. Run rake routes to list all available routes in your app and find relevant helpers.
I would strongly suggest to read the rails guide to understand how everything works.

Ruby on Rails -> Create div dynamically

I work on a task manager app, and I want to create html div 'cards' (with title, duration etc...), with all the datas I got on a database in rails.
I guess that I have to use javascript functions, but I can't get a way to do it.
I saw a lot of things on google, but I can't find exactly javascript calls from a rails controller (because I only catch all datas in the controller).
Here is my controller :
def new
# Retrieve all tasks in the project
#taskModel = Task.new()
#projectTasks = #taskModel.getProjectTasks()
# Add tasks on html
(0..#projectTasks.length).each do |i|
respond_to do |format|
format.js { render :js => "window.createTask();" } # I need to pass parameters in the createTask function
end
end
end
and my js file :
window.createTask = (title, content, duration) ->
card = document.createElement('div');
document.getElementsByClassName('content')[0].appendChild(card);
With my code, I get this error : ActionController::UnknownFormat
ActionController::UnknownFormat indicated that your ajax request is interpreted as a request with the wrong format. To answer this part better you'd have to post the javascript with the ajax call.
Secondly, you have to rethink the render in this block
(0..#projectTasks.length).each do |i|
respond_to do |format|
format.js { render :js => "window.createTask();" } # I need to pass parameters in the createTask function
end
end
You are calling respond_to multiple times which is just wrong. Put this loop into a new.js.erb view.

Ruby ajax call initiates unwated Popup Box

I have an AJAX call for one of my routes in my Ruby on Rails project. It calls a method in a Ruby Controller to update flags on several of my objects, and then I need the page to reload to reflect those changes. This was my solution, at the end of the Ruby method:
respond_to do |format|
format.js {render js: "window.location = '#{processed_items_path(params)}'" }
end
This does exactly what I need it to do, it refreshes the page and pulls the user back to the top to see a flash notice. However, before doing so, it pops up a window that says:
The page at localhost says:
"window.location = '#{processed_items_path(params)}'"
And it requires you to click "OK" before you can continue on. Is there any way to get rid of that box?
According to the comments above, instead of redirecting it'll be better to just render your partial containing your table
I'm assuming your ajax call is working (as it's taking you to your method). For rendering your partial you can do:
def your_method
#your logic of updating attributes
respond_to do |format|
format.js {} # this will let rails look for a file named your_method.js.erb in your view
end
end
Now you simply need to render your partial in your_method.js.erb
$("#some_id_of_parent_element").html("<%=j render partial: "partial_containing_table", locals: { :your_local => partial_local} %>");
For details refer to Working with javascript in rails

Rails render JS partial printing code to page

I'm using AJAX in my Rails app to render a JS error message when needed. It was working initially, but now coming back to it some time later, it still shows the JS error message but for some reason it now also prints the entire JS file as HTML in the window. This is what's called in the controller:
respond_to do |format|
format.js { render :partial => 'error' }
end
My file named _error.js.erb contains some JS which isn't relevant as regardless of what it contains Rails prints it to the window still.
This is what the JS looks like outputted to the window: (I tried commenting out the JS to see if it made a difference)
You can try it with some modification :
respond_to do |format|
format.js
end
Inside the action and in the view action_name.js.erb write your js code ar if you want to put your erb then use escape_javascript.
Check the following link :
Why escape_javascript before rendering a partial?
I did it! In case there will be someone else wondering a few years later, there's the answer: you should put rendered value in a javascript_tag inside your html.erb. Like this:
javascript_tag render: 'error'
that will put what rendered between <script>...</script> tags and escape all unnecessary code.
Here's the documentation on it

Missing template after link_to_remote

I'm using link_to_remote to update a partial on my page. The problem is that Rails isn't finding my partial.
I am specifying the full path to my partial(an html.erb file) in the controller method:
def my_method
create something
render :partial => '/shared/partials/my_partial_form', :layout => 'false'
end
I know the controller method is getting hit, since "something" gets created. I get the error "Template missing [:controller_name]/[:method_name].js.erb not found".
Can anyone explain why Rails appears to be using a default path to a js.erb?
Thanks in advance!
Rails is responding to the JS format. render :partial doesn't count as the action's 1 render/redirect call per action. Without a proper render or redirect call, Rails will call render with default arguments based on the format, controller and action.
Render :partial just returns text to the caller, it does not build a response. In this case the partial is rendered into HTML, but then nothing is done with it. P.S. :layout => false option is superfluous when rendering a partial.
You want to use render :update or RJS files to do the same through a template.
Assuming you want to replace the entire web page, the short version is do something like this:
def my_method create something
render :update do |page|
page.replace_html :body, :partial => '/shared/partials/my_partial_form'
end
end
Going the RJS route you could create the app/views/resource/my_method.rjs file and fill it with
page.replace_html :body, :partial => '/shared/partials/my_partial_form'
Try removing the / in front of shared.
render :partial => 'shared/partials/my_partial_form', :layout => 'false'

Categories

Resources