AJAX a form submission with Rails 3.2 - ruby-on-rails-3

This is my form, and it works fine, but now I want to AJAX it.
<%= form_tag variant_path(variant.id), :method => :put, :class => 'update_inv_form' do %>
<%= text_field_tag :inventory_quantity, variant.inventory_quantity %>
<%= submit_tag 'Update' %>
<% end %>
When I add the :remote => true attribute the form successfully submits via AJAX (I can see it happening on the server and I can see the changes when I refresh the page). I want to update the view properly to show the changes without refreshing the page. This is my update action: (Note that I am not working with ActiveRecord Models here.)
def update
variant = ShopifyAPI::Variant.find(params[:id])
variant.inventory_quantity = params[:inventory_quantity]
variant.save
redirect_to root_path
end
UPDATE
Thank you to the answer that helped me figure this out turns out the solution is exactly as he said, however I ran into a small problem. The view I wanted to update lives in app/views/home/index.html.erb and I was dealing with this: Variants#update. (Variants controller, update action)
I was putting my update.js.html in the same directory that my view was: app/views/home and my server was throwing a 500 error: Missing Template. Turns out, I had to create an app/views/variants/ directory and put the update.js.html file in there. Problem solved.

You'll need to change your action to respond to the JS format:
def update
#variant = ShopifyAPI::Variant.find(params[:id])
#variant.inventory_quantity = params[:inventory_quantity]
#variant.save
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
end
You can then create an update.js.erb file with JavaScript that will update the page. Let's say you have a _variant.html.erb partial, you could append the variant to a div like this (assuming you are using jQuery):
$('.variant-list').append('<%= escape_javascript(render(:partial => "variant", :object => #variant)) %>');
update
Here's an example of how you would use the update.js.erb' file (Note: I have not tried this code). Let's say you have the following code in yourindex.html.erb`:
<ul class="variants">
<li id="101">Variant 1</li>
<li id="102">Variant 2</li>
<li id="103">Variant 3</li>
</ul>
Your updated.js.erb could look something like this:
$('.variants #<%= #variant.id %>').text('<%= #variant.title %>');
What this does is find the variant you just updated in the list, and change the variant title to the new one.

Related

How do I update a list of partials rendered with a collection after a form submission of a newly created object in ruby on rails

This is a portion of my groups view. I have a list of partials that I render with a collection of objects:
<div id="container">
<ul>
<li id="form"></li>
<li id="partials">
<%= render :partial => 'groups/partial-list-row', :collection => #allpartials, :as => :f %>
</li>
</ul>
</div>
In the list item with id "form" there is a ruby on rails form that is a form_for #newpartial which is defined in the Partial controller as #newpartial = Partial.new(). I have successfully used jquery to toggle the show and hide of the two list items on a "New Partial" button click, and upon completing a finished form, a new partial object is definitely created. What I'm looking for here is the collection of partials that reappears after the form submission includes the newly created partial object. What is the best way to do this? My form which sits inside the list item with id "form" looks like this:
<%= form_for #newpartial, :html => {:multipart => true, :class => 'custom'}, remote: true do |f| %>
<% if #newpartial.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#newpartial.errors.count, 'error') %> prohibited this partial from being saved:</h2>
<ul>
<% #newpartial.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render :partial => 'partials/form-partial', :locals => { :f => f } %>
<div class="actions">
<%= f.submit 'Launch', :class => 'large success button radius new_browser_tab' %>
<a class="cancel_campaign_new">Cancel</a>
</div>
<% end %>
I also have successfully created a function that is bounded to the "ajax:success" event of this form after the DOM is fully loaded. I just don't know if this is a right approach, and if it is, I don't know what the body of this event handler should consist of. I have created other questions relating to this same issue (I haven't found a solution to this for quite some time now). Here are the questions if you want additional context:
SO question 1
SO question 2
What I was failing to realize is that applying the remote: true on the form indicates that the controller's action method will respond with the models "action".js.erb file. After creating that file and performing the jquery I had always intended, I was able to fix a few kinks and got that part working.
The difference between putting the jquery to render the new partial in your client side javascript and your "action".js.erb file is that the "action".js.erb file is able to make the required request to the server, whereas your client side javascript is not.
Can someone read this and let me know if the above statements are accurate? I'd really like to provide an answer that is accurate as possible for anyone that comes across this...
There are some really good tutorials at CodeSchool.com which has some free courses to take that include video lectures, slides, and exercises that I used to finally give me enough guidance on this. Also worth mentioning that if you intend to learn this stuff quickly and plan on spending a lot of time developing your web development abilities, paying the 20 dollars a month for access to all the courses is well worth it (you can cancel at any time, so learn what you need to learn and move on!).

Create New Rails Record without HTML Redirect

I have a Rails app where I have Article and Like models. I want someone to be able to create a Like record, similar to Facebook, where the database records the new record without redirecting them. The two requirements I have are: create a new Like record without redirecting the user and have a flash or js message that confirms the record was created.
I tried putting this in my view. However, when I do this, it creates two identical records:
<%= form_for #like, :remote=> true do |f| %>
<%= f.hidden_field(:article_id, :value => article.id) %>
<%= f.submit "Like" %>
<% end %>
I also, tried this which resulted in one record creating, but it took me to localhost:3000/likes:
<%= form_for #like do |f| %>
<%= f.hidden_field(:article_id, :value => article.id) %>
<%= f.submit "Like" %>
<% end %>
and then in the Like Controller commenting out the format.html and json:
def create
#like = Like.new(params[:like])
respond_to do |format|
if #like.save
# format.html { redirect_to #like, notice: 'Like was successfully created.' }
# format.json { render json: #like, status: :created, location: #like}
else
format.html { render action: "new" }
format.json { render json: #like.errors, status: :unprocessable_entity }
end
end
end
What's the best way to meet my two requirements? Thank you!
I assume Articles and Likes are related. When you want to 'like' an article you are actually updating that article, right? In other words, you would have to change the redirect within the update action of the articles controller.
P.S. I would use some javascript for submitting a form, for example:
<script type="text/javascript">
$(document).ready(function() {
$('.edit_[here_comes_the_name] input[type=checkbox]').click(function() {
$(this).parent('form').submit();
});
});
</script>
This example submits the input from a particular form (the parent) when clicking on the check_box. Of course you would have to adjust it to fit your needs.

No route matches :action => edit rails 3

I don’t understand why I am getting the above error message when trying to update a recipe
This is my output of rake routes
recipes GET /recipes(.:format) recipes#index
POST /recipes(.:format) recipes#create
new_recipe GET /recipes/new(.:format) recipes#new
edit_recipe GET /recipes/:id/edit(.:format) recipes#edit
recipe GET /recipes/:id(.:format) recipes#show
PUT /recipes/:id(.:format) recipes#update
DELETE /recipes/:id(.:format) recipes#destroy
root / public_pages#index
My controller looks like this
def edit
#recipe = Recipe.find(params[:id])
end
def update
#recipe = Recipe.find(params[:id])
if #recipe.update_attributes(params[:recipe])
redirect_to recipes_path, :notice => "Successfully updated recipe"
else
render :action => 'edit'
end
end
And my link to edit the post
<%= link_to "Edit Recipe", edit_recipe_path(#recipe) %>
the full error is (this is when trying to access the recipes page
Routing Error
No route matches {:action=>"edit", :controller=>"recipes"}
Try running rake routes for more information on available routes.
and finally the form i am using, now the only thing I can think of is that there is an issue with my form, though i thought that you could use the same form for new and edit? though i could be totally wrong
Anyone have any ideas
ok so it seems as if i needed this in my view
<%= link_to "Edit Recipe", edit_recipe_path(r.id) %>
this was because i was passing
<% #recipes.each do |r| %>

Format.js will only render a partial that contains a single line

Rails 3.2.1: I have the following div that calls a partial
<div id="weighin">
<%= render :partial => "my_weight/weighin" %>
</div>
The partial contains a form that posts ajax (ie has :remote => true) to a controller with:
respond_to do |format|
format.js
end
The .js.erb file has a single line:
$("#weighin").html("<%= render :partial => "my_weight/weighin1" %>");
The _weighin1.html.erb partial file has a single line:
<p><%= #my_weight[1].weight %></p>
This works, in that the original div is replaced with the value of the #my_weight field - so the fundamental structure is all working ok
However, Rails will not handle any more code in the partial - if I add so much as a carriage return to the end of that one line, the server log confirms all ok, but no script gets run on the page - ie nothing changes.
The same happens if I try to put more html in the partial, but put it all in a single line - this doesnt run either.
How can I output more than a single short statement in a partial?
OK, I figured this out:
$("#weighin").html("<%= escape_javascript(render :partial => "my_weight/weighin1") %>");
escape_javascript is essential
What is confusing is that, depending on what is in the html() you are sending, this will sometimes work without escape_javascript, leading one to a false conclusion... :-)

Rendered partial not receiving params

I'm trying to implement an 'edit' link that brings up a form to change a displayed attribute on a page.
My layout has:
<div id="company_info">
<%= yield :company_info %>
</div>
<div id="edit_company_info">
</div>
My view has:
<%= content_for :company_info do %>
<%= render 'company_info' %>
<%= link_to "Edit", 'company_info_form', :class => 'btn btn-mini', :method => :get, :remote => true %>
My controller has:
def company_info_form
#company = Company.get(params[:id])
respond_to do |format|
format.js
end
end
My company_info_form.js.erb file has:
$('#edit_company_info').html("<%= escape_javascript(render "company_info_form") %>");
Upon clicking the link, my server shows:
Started GET "/companies/company_info_form" for 127.0.0.1 at 2012-03-12 20:19:13 -0700
Processing by CompaniesController#show as JS
Parameters: {"id"=>"company_info_form"}
Completed 500 Internal Server Error in 1ms
RuntimeError (Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id):
app/controllers/companies_controller.rb:9:in `show'
So I think this is a routing issue-- but I have no idea how to fix it. How do I get the company_id param that is on my current page to be recognized by the partial I'm loading as well?
I'm on /companies/1, but the link is to companies/company_info_form, losing the "company_id = 1" param.
Yes, the issue is with your routes and with your link as you have pointed out.
The first issue can be ascertained as it says Processing by CompaniesController#show as JS. So, its actually going to companies#show where it tries to find a company based on id. But, since no correct id is passed, it errors out.
The second issue is because your link is to companies/company_info_form, as you pointed out, since you have used 'company_info_form' as the path in your link for edit. And you haven't passed current company to the link either.
Since you haven't posted your routes file, which you should have, since you have identified a potential problem with routes , I'll present my own.
In your routes :
resources :companies do
member do
get 'company_info_form'
end
end
That will provide you with
company_info_form_company GET /companies/:id/company_info_form(.:format) companies#company_info_form
Then you can provide the link as :
<%= link_to "Edit", company_info_form_company_path(#company) %>