I have a view with an ajax form:
<%= form_tag( {:action => 'some_action'}, {:remote => true}) do %>
...
<%= submit_tag "Submit" %>
<% end %>
Now, in the target action, I want to display a partial
def some_action
# some logic
render :partial => "some_partial"
end
The partial is just html. _some_partial.html.erb could be
<br>Hi, this is the partial</br>
When I submit the form, I see the html response packet is received in the browser (with firebug's net logs), but the html doesn't show up anywhere. Where should the html be? How to render a partial html view from an action?
you are rendering a partial but not specifying where to render it.
in rails 2 you could do it with:
def some_action
# some logic
render :update do |page|
page.replace_html 'some_div_id', :partial => 'some_partial'
end
end
but in rails 3, above code is no longer valid.
see Unobtrusive Javascript
create a file named some_action.js.erb and write the code in it:
// update div with id some_div_id
$("#some_div_id").html("<%= escape_javascript(render :partial => 'some_partial') %>");
in controller
def some_action
# some logic
respond_to do |format|
format.js
end
end
I figured out how to send and display html. From theReq, just add :remote => true, "data-type" => "html" to the form and then in the javascript of the page, capture the returned html on ajaxSuccess to display it:
$('form#whatever').on('ajaxSuccess', function (event, data, status, xhr) {
$('div#target').html(data);
}
)
Related
I have a time logger controller method that calls from my view, called _embed_menu.html.erb
<%= link_to l(:start_time_logger) + ' #' + #issue.id.to_s + ' ',
{:controller => '/time_loggers', :action => 'start', :issue_id => #issue.id},
:class => 'icon icon-start',
:"data-replace" => '#time-logger-menu',
:remote => true
%>
The part of 'start' method, where I shown an error:
respond_to do |format|
format.js{ flash[:error] = l(:start_time_expired_error)}
end
Now to the part of the rendering flash messages. application_helper.rb
Have render_flash_messages function.
def render_flash_messages
s = ''
flash.each do |k,v|
s << content_tag('div', v.html_safe, :class => "flash #{k}", :id => "flash_#{k}")
end
s.html_safe
end
and that function called on base.html.erb template.
<%= render_flash_messages %>
So the result - I launch a start method and flash shown only after I reload the page. I also tried to redirect with the hope that after this redirect the error will show.
redirect_to controller: 'issues', format: 'js'
but no result.
Maybe I can trigger re-rendering of <%= render_flash_messages %>?
What happens when you click a remote: true link is that Rails creates a request for text/javascript and then runs the resulting javascript in that page.
Usually a js.erb template contains some javascript that modifies the document:
$("<%= escape_javascript(render #user) %>").appendTo("#users");
So if you want to alter the flash messages on the page you need to target the wrapping element and append it:
$("<%= escape_javascript(render_flash_messages) %>").appendTo("#flashes");
This assumes you have a wrapping element around the flash messages. Otherwise just add one to the layout.
<div id="flashes">
<%= render_flash_messages %>
</div>
Use flash.now[:error] if you need to use the flash message on the same request.
https://api.rubyonrails.org/classes/ActionDispatch/Flash/FlashHash.html#method-i-now
https://guides.rubyonrails.org/action_controller_overview.html#flash-now
replace flash to flash.now.
for example,
respond_to do |format|
format.js{ flash.now[:error] = l(:start_time_expired_error)}
end
and in js.erb file re-render the partial where you want to update.
I just manually redirect to the page by window.location solution - here I just call issues index controller, but here can any link.
flash[:error] = l(:start_time_expired_error)
respond_to do |format|
format.js{ render js:"window.location='/issues/"+#issue.id.to_s+"'"}
end
I have a Rails app where on the home page home/index.html.erb, I show a partial for the model workorders. It currently defaults to the home_controleer.rb with the action index.
Can I select the workorders_controller.rb and action index2?
I tried this in the home/index.html.erb view file:
<%= render :partial => "workorders/index7", :controller => "workorders", :action => "index2" %>
But it's not working.
Try this instead:
<%= render :template => "workorders/index2" %>
source: https://stackoverflow.com/a/6051812/2128691
edit: in response to your last comment...
I haven't really worked with bootstrap, but maybe you could do something like this [pseudocode]:
def home
if [x condition]
redirect_to index_seven_path
else
render :action => [y action]
end
end
I'm new to Rails, and I'm having an issue where I can't render a .js.erb file. I think the root of the issue is that Rails' internal routing mechanism expects me to name and configure my files just so, but I'm missing one or two pieces, and I'm not sure how to look for what needs to be fixed.
I have an HTML view with a link to a controller action:
<%# snip %>
<div id="holding_issues_list">
<%= link_to "Show issues on hold", {
:action => "show_user_issues",
:controller => "support",
:issue_type => "holding",
:user_id => #user.id },
:remote => true %>
</div>
<%# snip %>
I think (but I'm not sure) that :remote => true causes the link to make an AJAX call.
This is the corresponding controller action in the controller app/controllers/support_controller.rb:
def show_user_issues
#target_div = params[:target_div] || "holding_issues_list"
user = User.find(params[:user_id])
issue_type = params[:issue_type]
#snip - set the value of #issues
end
I want this file, named show_user_issues.js.erb and placed in app/views/support, to be rendered when the controller exits:
$("#<%= #target_div %>").show();
alert('test');
$("#<%= #target_div %>").html(
"<%= escape_javascript render :partial => '_show_user_issues', :locals => {:target_div => #target_div, :issues => #issues} %>");
This is app/views/support/_show_user_issues.html.erb, the partial I want show_user_issues.js.erb to render:
<% for issue in #active_issues %>
<div id="issue_<%= issue.id %>_display">
<%= render :partial => 'show_issue_mini', :locals => {:issue => issue} %>
</div>
<% end %>
When I try clicking the link in my original HTML view, nothing happens. When I open it up in a new tab, I get this error message:
Template is missing
Missing template support/show_user_issues,
application/show_user_issues with {:locale=>[:en],
:handlers=>[:builder, :erb], :formats=>[:html]}. Searched in: *
"/home/<>/app/views" *
"/home/<>/gems/kaminari-0.14.1/app/views"
The alert('test') that I put into show_user_issues.js.erb doesn't show up, so I think that Rails is getting hung up on rendering that file - that is, the routing mechanism can't find it. How can I correct this issue?
P.S. I double-checked that I put in all the file names exactly as they are in the code base.
Change your controller action to handle the type of request.
def show_user_issues
#target_div = params[:target_div] || "holding_issues_list"
user = User.find(params[:user_id])
issue_type = params[:issue_type]
#snip - set the value of #issues
respond_to do |format|
format.js
end
end
This will check the format of the request which is .js in case of :remote => true. So it will handle it by rendering the show_user_issues.js.erb file.
A couple other problems that I ran into after applying Manoj Monga's answer that I suspect other new Rails devs might run into:
In show_user_issues.js.erb, I had
[...].html("<%= escape_javascript render :partial => '_show_user_issues',[...]
The underscore before '_show_user_issues' caused the ERB builder to fail. It should have just been 'show_user_issues'.
In _show_user_issues.html.erb, I had
<% for issue in #active_issues %>
If you look closely at show_user_issues.js.erb, though, I named the variable #issues, not #active_issues:
[...]:locals => {:target_div => #target_div, :issues => #issues}[...]
So I changed the line in the HTML partial to
<% for issue in #issues %>
After these last couple changes, the new functionality I was adding worked as expected.
I am stuck; I did a search and I can't find a pointer on how to get this project to work. I have a form on my index.html.erb as:
<html> <head>
<title>Ajax List Demo</title> <h1>Listing posts</h1>
<%= javascript_include_tag "prototype" %> </head> <body>
<h3>Add to list using Ajax</h3>
<% form_tag ( :remote=>true, :update => 'my_list', :action => :list , :method=>:post, :format =>:xml ) do %>
Enter the url:
<%= text_field_tag 'url' ,'', :size => 80 %>
<%= submit_tag "Find" %>
<% end %>
<div id="my_list"><%= render :partial => 'profiles/list' %></div> </body> </html>
Now I have a div with this called my_list. When I submit the form I want my partial _list.html.erb (inside profiles dir, tried home dir too) to update with the results of list.
My home controller has this method:
def list
puts "here!!!!"
reader = Reader.new
#profiles = reader.processURL(params[:url])
render :partial=>'profiles/list', :locals => { :profiles => #profiles}
end
I end up getting this error:
ActionView::MissingTemplate (Missing partial profiles/list with {:locale=>[:en, :en], :handlers=>[:rjs, :builder, :rhtml, :rxml, :
erb], :formats=>[:xml]} in view paths "C:/Users/....tree/app/views"):
app/controllers/home_controller.rb:22:in `list'
Rendered C:/Ruby187/lib/ruby/gems/1.8/gems/actionpack-3.0.0/lib/action_dispatch/middleware/templates/rescues/missing_template.erb
within rescues/layout (1.0ms)
Could anyone help me or send me in the right direction to understand how to update a div rendering via Rails on form submit? Thanks again.
First of all I am getting ajax to render(#homepages) in index.html.erb via index.js.erb OK, but my search to update #homepages is not working.
In your javascript_include_tag you missed out rails.js which I think handles the ajax request. javascript_include_tag :defaults would have done all that for you plus some others that you do not need. Providing you are not using jquery you need prototype and rails.js as a minimum.
I do not think the format of this form_tag is correct:
<% form_tag (:remote=>true, :update => 'my_list', :action => :list , :method=>:post, :format =>:xml) do %>
The first value after the "(" should be the item_path, then the conditions :action => :list.
:method => post should take you to the create or new action.
:update => 'my_list' would be done in the list.js.erb using javascript (prototype)
The code for jquery and prototype is similar, but slightly different (see Railscast 205)
Why format xml in the form_tag, put it in the controller "list" mine is:
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #homepages }
format.js
end
Don't sure if you can get away with 'url' should not it be :url you might be able to use either.
When I was getting the missing template it was because it was looking for a search.html.erb file. In your case it is looking for a list.html.erb.
How to reload only the div id on a page?
I just need to reload a certain div.
in my controller I have
def mycontrolleraction
...
render(:update) do |page|
reload_only_the_div('adiv'), :controller => 'my_controller'
end
end
Is this possible?
You can replace a div's content with a partial like this.
render :update do |page|
page.replace_html 'person-45', :partial => 'person', :object => #person
end
Where the div id is person-45 the partial's name is person. Also you can pass an object to your partial, in this case the object is #person. For more information please see the documentation.
ref ajax-on-rails tutorial.To replace the html content of some div use replace_html
render :update do |page|
replace_html 'div', 'new refresh data'
end
use partials to update particular div in view
render :partial => "fileame", :layout => false