How to make Rails render a view and automatically scroll down? - ruby-on-rails

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} )

Related

render :new not going to the right place after a validation

I have a 'new' form that gets validated in a post model. When the validator kicks in, it renders incorrectly.
The new post page path is at '/posts/new'
On validation, the new post page path is at '/posts' .. I need it to go back to '/posts/new'.
This is my controller:
def create
#post = current_user.posts.build(params[:post])
if #post.save
redirect_to public_post_page_path(#post.public_url)
else
render :action => :new
end
end
I have a feeling it might have to do with my form. So here is the formtastic first line:
<%= semantic_form_for [:student, post], :html => {:id => "post_form"} do |form| %>
This is the correct behavior from rails.
In the create action it simply renders the "new" view file. As such the url will be /posts but the view will correctly display the form. There is nothing wrong with this behavior; and in general rails convention is good form. Also the built in rails errors work if you just render new; however if you redirect they won't display.
If you really feel like you want to go back to that url you need to use:
redirect_to
instead of render.
If validation fails, user should see the form with the errors and stay at /posts/new. That's what you want, right?
There's a simple way to achieve this.
Set remote: true on the form to prevent the url from advancing. Handle ajax:success to replace the form on the page with the newly rendered one.
$('form[data-remote=true]').on 'ajax:success', (e, data, status, xhr) ->
if isHTML(data)
thisForm = "form[id=#{#getAttribute('id')}]"
$(thisForm).replaceWith $(data).find(thisForm)
isHtml() function is from this question.

A dry way to build page with multiple blocks (from different controllers) and ajax in rails

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.

Reload page or div using RJS

I have a 'like'-counter in a rails project. Whenever one clicks this 'like'-link I want to add one to the like_counter in the database. The logic works well and the database is updated, but I cannot figure out how to set up the Ajax Request correctly so it refreshes the page or the div when completed.
In my view this looks as follows:
<%= link_to_remote 'like', :url => {
:controller => 'projects',
:action => 'like_it',
:id=> #project.id }%>
The controller:
def like_it
#project = Project.find(params[:id])
#project.update_like
render :update do |page|
page.reload
end
end
the update_like method is in the model and just adds one to the counter and saves the project (this part works).
As for the page.reload I Firefox throws an RJS-Error: ReferenceError: Reload is not defined. And the page is not reloaded
What do I do wrong? Is there a more distinguished way to just reload the div containing the counter? Any help is much appreciated!
Try:
render :update do |page|
page << "window.location.reload()"
end

updating a rails partial with AJAX

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".

Ruby on Rails form_remote_tag missing template

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 %>

Resources