I'm new to using AJAX in Rails (I know... I know...), and am positive that I'm doing something wrong that's probably just the wrong call or something. But I've hunted and can't seem to find it.
Anyway, I'm rendering out quick partial (this is working right) and then I want to refresh it with an AJAX call. Here's what I thought would work:
<div id="two_on_two"><%= render :partial => "quickread" %></div>
<p><%=link_to_remote "load two new stories", :url => {:partial => 'quickread'}, :update => 'two_on_two' %></p>
that just blows out the page (a quick flash and then just a blank browser window). If I switch from :partial to :action in that AJAX call, then it dynamically loads a "template missing" in that two_on_two div.
Clearly, there's something easy I'm missing here, right?
Thank you so much!
First, read api:
http://apidock.com/rails/ActionView/Helpers/PrototypeHelper/link_to_remote
You should specify your url correctly (controller, action, other params, not partial!) and define your RJS in controller action.
IE:
index.html.erb
<div id='two_on_two'></div>
link_to_remote 'Link Name', :url => {:controller => "bar", :action => "baz"}
bars_controller.rb
def baz
respond_to do |format|
format.js{ render :update do |page|
page.replace_html 'two_on_two', 'Hello world!'
end}
end
end
So when you will click Link Name, in your two_on_two div will appear "Hello world text".
Related
Main page of my website consists of multiple blocks such as last offers, last news, last articles and so on. Each block has controls like "show more" or "refresh" so that when user clicks, the block should refresh or update it's own content through ajax.
Also when a page is loaded the first time, it should already be filled with content (for disabled javascript and search engines).
What's the best, dry, rails-way to build such structure?
That's In my articles_controller.rb:
def line
#articles = Article.filter(params)
respond_to do |format|
format.html { render :layout => false, :partial => "articles/line.html", :locals => {:articles => #articles} }
format.json { render :json => { "html" => render_to_string(:partial => "articles/line.html", :locals => {:articles => #articles}) } }
end
end
When I call /articles/line through ajax it sends json that contains cut of html-code, and all that remains is to append it to a specified div. This works. When I call /articles/line directly it also works and displays required partial of html-code.
But what should I write in my main_controller (it should collect and render all blocks from different controllers)? Where should I write some blocks settings (for example, quantity of records and offset, they required both in static and ajax cases)?
Most convenient for me is to set everything up right in the view template of main page, like that:
<div id="last-news" data-params="{offset:0,limit:5}">
<%= render #here we get html from :controller => news, :action => list, :params => get them from parent div %>
</div>
<div id="last-articles" data-params="{offset:0,limit:10}">
<%= render #here we get html from :controller => articles, :action => list, :params => get them from parent div %>
</div>
But that doesn't look like MVC.
I have an obnoxiously large landing page with a registration form in the middle of it. If I submit the form and validation fails, I want to render the landing page again, but I want it be scrolled down to the registration form so they can see the errors and make edits. Is this possible to jump down to the form with the render method, or do I need to do redirect_to "account/new#theFormID"?
I would rather not do a redirect because you have to save the form information in a session, repopulate the form, et cetera, and I want to stick the conventional
if #resource.save then redirect_to ...
else render "new"
end
Put the anchor directive on the form and you can still rely on :render from the controller...
form_for(#my_model, :url => { :action => "create" , :anchor => "my_anchor" })
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html
redirect_to profile_path(#profile, :anchor => "wall")
That is how you pass anchors.
I scrolled to an anchor with render using a global var and Javascript (as hinted by Ibrahim).
On my controller I had this:
#anchor = "my_anchor"
render :action => "edit"
And on my page, I checked if I had a global #anchor, and if so, roll to it with Javascript:
<% if #anchor %>
<script type="text/javascript">
window.location.hash = "<%= #anchor %>";
</script>
<% end %>
Use javascript?
<script>
window.location.hash="ANCHOR";
</script>
And another thing... if it's a link like I'm actually using, you have to add a unique param so the browser thinks it's submitting something new, otherwise it just refreshes without hitting the server. I'm using:
link_to "REFRESH", refresh_my_model_path(#my_model, :anchor => "my_anchor", :options => {:id => Time.now} )
I intend to use the following code to replace the partial web page called "activitypage", but instead I got a filedownload window with the message "Do you want to save the file or find a program to open".
Why? Thanks,
render :update do |page|
page.replace_html ('activitypage', :partial => 'index')
end
return
EDIT:
Noel, Thanks for your reply. Here is the whole picture, I hope.
In client page there is a submit button as defined like that,
<div class="form_row">
<% form_remote_tag :url => {:controller => '/group', :action => 'add'},
:html => {:action => {:controller => '/group', :action => 'add'}} do %>
<%= submit_tag "Add!", :class => "submit" %>
<% end %>
In the function Add of controller group, I have the code,
def add
//add the member into the group table
//then go back to the /group/index page
//which will replace the content in webPage "activitypage"
render :update do |page|
page.replace_html ('activitypage', :partial => 'index')
end
return
end
In the backend, the controller:action (here /group/add) worked as expected, but in the client browser, a filedownload window was popped up for saving or opening a file?
I am confused!??????
How are you calling this?
It could be a problem in the client side code.
If it's invoked by an Ajax.request then you may need to set the evalJS option to true.
Alternatively try :content_type => 'text/javascript' in your page.replace_html call.
edit --->
Just been looking at the docs for remote_form_for and I think you may get some success by adopting a slightly different approach.
If your controller does a straight
render :partial => 'index'
and you add the following option to the remote form tag
:update => "activitypage"
But that doesn't really answer you original question. I would recomend having a good look at the response header using WireShark or the Tamper Data plugin for FireFox (not sure if Tamper Data shows responses to ajax requests or not). I'ts likely that something is wrong with the content_type or disposition headers. It could have something to do with your server configuration.
(I hate these type of problems where it should "just work".)
I'm using form_remote_tag(:url => {:controller => "home", :action => "search"}, :update => "mydiv"). When I click submit on the form "mydiv" is populated with the error "Template is missing. Missing template home/search.erb in view path app/views". I've tried multiple render options in def search, but they all result in the same error.
It looks like the search method is trying to use it's default render even though I'm specifying what I want.
I've tried:
render 'index'
render :text => 'Return this from my method!'
Is my url incorrect? Is it not submitting back to my home controller's search method?
Try
render :action => 'index'
this will use "index.rhtml" or "index.html.erb".
I will try to explain why it said search.erb is not found, lets take create action for a some model, if there is some error in my create action they it will throw missing template create.html.erb file, since you have some error in your create action rails will try to render the create.html.erb in the page. Hope I explained it clearly.
In an ajax action you can't use redirect_to or render options directly.
try using this in your search action
render :update do |page|
page.replace_html "ur_div_id","partial"
end
The form_remote_tag needs prototype to function. Make sure you are including the :defaults for your javascript libraries namely prototype.
<%= javascript_include_tag :defaults %>
I am trying to display an error message of flash in Ajax using Rails but it doesn't display it, and I have tried several ways to do it but I just can't get it right.
Here is my form to display my errors:
#flash-error.flash-error{:style => "display: none"}
#flash-notice.flash-info{:style => "display: none"}
%h3 New Document
- form_for(:repo_document, :url => {:all_categories => #repo_categories, :action => "create", :format => "js", :query => params[:query]}, :html => { :id => "repo_document_form", :multipart => true, :target => 'upload_frame'}) do |form|
Here is the controller:
if !params[:stands]
respond_to do |format|
format.js do
responds_to_parent do
render :update do |page|
page.show "flash-error"
page.replace_html "flash-error","Please select stands you want to grant permission to view this stand."
end
end
end
return
end
end
What am I doing wrong?
js.rjs to the rescue
def action
#true = params[:stands]
respond_to |format|
format.js
end
end
in action.js.rjs:
if #true
# do true stuff
else
page.replace_html 'error_block_dom_id', :text => 'This is my error'
end
and the original view file that you make the ajax call from:
#nothing here due to no errors - errors will appear if they happen
<div id="error_block_dom_id"></div>
No overarching reason to use the flash - just update a DOM object with the error content.
A possible solution would be to send an ajax call to an action in a controller and set your flash messages in that action
Flash is only going to display on the next time the page is loaded. It doesn't update through AJAX. One of the caveats of AJAX is that it doesn't deal with file uploads...
See this for more details; http://guides.rubyonrails.org/form_helpers.html#uploading-files
I think the problem might be elsewhere: Element's method show (call of which is generated when You call page.show "flash-error") will not remove display: none css style when it is given inside the external Css file. This is a quotation from older version of Prototype's API Documentation.
So try to add display: none as inline style of Your div's. I hope it will help!