Rails 3 AJAX problem - UJS - ruby-on-rails

Ok so here is my setup, I think I have everything set up correctly but for some reason the page isn't displaying the AJAX response.
Basically I have a members list and want to display their "profile" with ajax on the same page.
In views/member/index.html.erb
<table>
<tr>
<th>Name</th>
</tr>
<% #members.each do |member| %>
<tr>
<td><%= member.name %> & <%= member.sname %></td>
<td><%= link_to 'Show', member, :remote => true %></td>
<td><%= link_to 'Edit', edit_member_path(member) %></td>
<td><%= link_to 'Destroy', member, :confirm => 'Are you sure?', :method => :delete %> </td>
</tr>
<% end %>
</table>
<%= link_to 'New Member', new_member_path %>
<div id="memberprofile">
</div>
In my members controller I have this:
def show
#member = Member.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.js
format.xml { render :xml => #member }
end
end
Then in my _show.js.rjs I have this
page.replace_html('memberprofile', render(#member))
Then in my _member.html.erb partial I have this:
<h1><%= #member.name %></h1>
A few questions:
1) From the console it says "Rendered members/show.html.erb" but I thought it would just render the member partial. why is this?
2) Nothing is happening in the index.html.erb page when the ajax call goes out. I thought having the div hook plus the javascript file would do the trick...
Thanks guys

you have to create a new partial that only display the profile of member. Lets say the partial name is _member.html.erb
in your index file do:
<%= javascript_include_tag "jquery-1.4.4.min.js", "jquery.form" %>
<script type="text/javascript"> var $j = jQuery.noConflict();</script>
<table>
<tr>
<th>Name</th>
</tr>
<% #members.each do |member| %>
<tr>
<td><%= member.name %> & <%= member.sname %></td>
<td><%= link_to 'Show', "javascript:", :onclick => "show_member(member.id)" %></td>
<td><%= link_to 'Edit', edit_member_path(member) %></td>
<td><%= link_to 'Destroy', member, :confirm => 'Are you sure?', :method => :delete %> </td>
</tr>
<% end %>
</table>
<%= link_to 'New Member', new_member_path %>
<div id="memberprofile">
</div>
<script type="text/javascript">
function show_member(m_id) {
var container = $j("#memberprofile");
$j.ajax({
url: '/members/get_member?mid=' + m_id, type: 'get', dataType: 'html',
processData: false,
success: function(data) {
container.html(data);
}
});
}
</script>
in your routes do something like:
resources :members do
collection do
get :get_member
end
end
in your controller do:
def get_member
#member = Member.find_by_id(params[:mid])
render :partial => "member", :layout => false, :locals => {:member => #member}
end
in your _member.html.erb partial
<% unless #member.blank? %>
<h1><%= #member.name %></h1>
<% else %>
Record not found :(
<% end %>

Related

Rails 5 edit multiple not showing values in table

I am creating multiple edit on my app. I have followed the revised Rails screencast and this code that adapts it to Rails 5.
In my Categories Controller:
def edit_multiple
#categories = Category.where(ID: params[:category_ids])
redirect_to categories_url
end
In my index:
<table class="table" summary="Category list">
<tr class="header">
<th style="text-align: left"><%= sort_link(#q, :NAME, 'NAME', default_order: :desc) %></th>
<th style="text-align: left">POSITION</th>
<th style="text-align: left">ACTIONS</th>
</tr>
<%= render "list" %>
</table>
<%= submit_tag "Edit Checked" %>
In my list partial:
<% form_tag edit_multiple_categories_path, method: :get do %>
<% #categories.each do |category| %>
<tr class="<%= cycle('odd', 'even') %>">
<td><%= check_box_tag "category_ids[]", category.ID %></td>
<td><%= link_to category.NAME, {:action => 'show', :ID => category.ID} %>
<td><%= category.RANK_POSITION %></td>
<td class="actions">
<%= link_to("Edit", {:action => 'edit', :ID => category.ID}, :class => 'button tiny') %>
<%= link_to("Delete", {:action => 'delete', :ID => category.ID}, :class => 'alert button tiny') %>
</td>
</tr>
<% end %>
<% end %>
When I open the categories page, it doesn't show anything from _list partial. There's only table headers and Edit Checked button.
Before adding the code relative to multiple edits the table was showing values from partial.
Note that db column names are capital as I'm building the app on existing db.
How can I fix it?
The problem was simply that
<% form_tag edit_multiple_categories_path, method: :get do %>
should be:
<%= form_tag edit_multiple_categories_path, method: :get do %>
I copied that from the railscast #165
Perhaps someone will find same issue and will find this useful.

How to render partial on the same page after clicking on link_to with AJAX

I have a list of customers. Every customer has a link, which links to the customers page and displays his data.
I want to link to partial rendered on the same page below the table of customers. On initializing the "page" with the table, a blank page with something like "select a customer" should be loaded.
My code for the Customers list:
<h1>Listing Customers</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th colspan="3">Actions</th>
</tr>
</thead>
<tbody>
<% #customers.each do |customer| %>
<tr>
<td><%= customer.name %></td>
<td><%= link_to 'Show', customer %></td>
<td><%= link_to 'Edit', edit_customer_path(customer) %></td>
<td><%= link_to 'Destroy', customer, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Customer', new_customer_path, class: "button", id: "new_customer" %>
My partial for displaying the customer:
<p>
<strong>Name:</strong>
<%= #customer.name %>
<%= #customer.id %>
</p>
<%= link_to 'Edit Customer', edit_customer_path(#customer) %> |
<%= link_to 'Back', customers_path %>
Can you help me with some ideas?
You basically want to use AJAX to display a customer's details. For this you can use the remote: true option provided by rails for the link_to helper. What we are going to do next :
Create a div that will contain the loaded data. In this case div#current_customer
Add remote: true to your link :
<td><%= link_to 'Show', customer, remote: true %></td>
Name your partial customers/_show.html.erb (don't forget the _so it can be called as a partial) :
<p>
<strong>Name:</strong>
<%= #customer.name %>
<%= #customer.id %>
</p>
<%= link_to 'Edit Customer', edit_customer_path(#customer) %> |
<%= link_to 'Back', customers_path %> # You should remove this link
Respond to Javascript in the show method in CustomersController :
respond_to do |format|
format.js {render layout: false} # Add this line to you respond_to block
end
Create your show.js.erb view, which is going to handle the front-end changes when respond_to :jsis gonna be called (In this case triggered by remote: true)
Tell show.js.erb what it must do (Replace #current_customer content with your partial, using the right #customer) :
customers/show.js.erb
$("#current_customer").html("<%= escape_javascript(render partial: 'customers/show', locals: { customer: #customer } ) %>");
customers/index.html.erb
Name
Actions
<div id="current_customer"> # This will will contain the partial
</div>

Render table in partial Rails 4.0

Could someone help me render a table view partial? Basically, I have a Link model with two attributes: Description and URL. My Link model is a nested resource of my Opportunity model. Therefore when I click "show" on an opportunity, I want it to show the Opportunity then show all the links that belong to that opportunity. I want the links to be rendered into a table with columns labeled "Description" and "URL". My current code looks like this:
views/opportunities:
<%= render #opportunity %>
<h3>Links</h3>
<div id = "links">
<%= render #opportunity.links %>
</div>
views/links/_link
<%= div_for link do %>
<p>Description:<%= link.description %></p>
<p>URL: <%= link.link_url %></p>
<span class='actions'>
<%= link_to 'Delete', [#opportunity, link], :confirm => 'Are you sure?',
:method => :delete %>
</span>
<% end %>
You're going to want...
<%= render #opportunity %>
<h3>Links</h3>
<table id = "links">
<thead><tr>
<th>Description</th>
<th>URL</th>
</tr></thead>
<tbody>
<%= render #opportunity.links %>
</tbody>
</table>
And then...
<tr>
<td><%= link.description %></td>
<td><%= link.link_url %></td>
<td><span class='actions'>
<%= link_to 'Delete', [#opportunity, link], :confirm => 'Are you sure?',
:method => :delete %>
</span></td>
</tr>
I'm a little unclear on how you're using the span in the partial, so I left it as a separate column in the table.
I hope that helps.

Why my form won't submit correctly?

I have User model and Comment model using acts_as_commentable_with_threading
I'm trying to put the comment function on each User's show page with partial.
But When I try to submit a form, it shows routing error.
Why is this?
Error
Routing Error
No route matches [POST] "/user/john/add_comment"
models/user.rb
acts_as_commentable
views/users/show.html.erb
<%= render 'comment', :user => #user %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #user.comment_threads.each do |comment| %>
<tr>
<td><%= comment.id %></td>
<td><%= comment.title %></td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td><%= button_to 'destroy', comment, confirm: 'Are you sure?', :disable_with => 'deleting...', method: :delete %></td>
</tr>
<% end %>
</table>
<%= form_for #user, :html => { :class => 'form-horizontal' } do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
routes.rb
get "user/:id/add_comment" => 'users#add_comment', :as => :add_comment_user
get "user/:id/delete_comment" => 'users#delete_comment', :as => :delete_comment_user
users_controller.rb
def add_comment
#user = User.find_by_username(params[:id])
#user_who_commented = current_user
#comment = Comment.build_from( #user, #user_who_commented.id, params[:users][:body] )
#comment.save
redirect_to :controller => 'users', :action => 'show', :id => params[:users][:id]
flash[:notice] = "comment added!"
end
Because your route is for a GET, and the form is a POST.
It needs to be a post route. Also you are posting to user/:name/add_comment, you should post the the user id. You can use the name but this would need to be unique across all users.
This line is also wrong.
#user = User.find_by_username(params[:id])
You can either pass in the params[:username] of find_by_id

How to properly render collection in a partial layout from inside another partial layout?

I have a Cart that I want to render in 3 different ways in my app.
In the sidebar. Displays only item count in cart and their total price.
In Cart main view. Displays line items with links to products, quantity and total price for each item. Also displays buttons to increase/decrease item quantity and a button to remove item from cart.
In Order view, shows cart content the same way as main cart view, except links to products, buttons to change quantities and 'remove' button.
So far I render cart like this:
carts/_cart.html.erb
<%= yield %>
Cart sidebar layout carts/_sidebar.html.erb
<ul>
<li class="nav-header">Your Cart (<%= pluralize(#cart.total_items, "Item") %>)</li>
<li>Total Due: <%= number_to_euro(#cart.total_price) %></li>
<% unless #cart.line_items.empty? %>
<li><%= link_to "View Cart & Checkout", cart_path(#cart) %></li>
<li><%= link_to "Empty Cart", #cart, :method => :delete %></li>
<% end %>
</ul>
Which is rendered from layouts/_sidebar.html.erb by <%= render :partial => 'carts/cart', :layout => 'carts/sidebar' %>
Cart main layout carts/_main.html.erb
<table>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Subtotal</th>
<th></th>
</tr>
<%= render #line_items %>
<tr id="total_line">
<td colspan="3">Total:</td>
<td><%= number_to_euro(#cart.total_price) %></td>
<td></td>
</tr>
</table>
Which is rendered from carts/show.html.erb
<h1><%= pluralize(#cart.total_items, "Item") %> in Your Cart</h1>
<%= render :partial => 'cart/cart', :layout => 'carts/main' %>
<%= link_to "Empty Cart", #cart, :method => :delete %>
<%= link_to "Checkout", new_order_path %>
And there is also carts/_order.html.erb which is currently rendered from orders/new.html.erb the same way as in cart main view.
What I want to do is to create 2 different layouts to render line items from carts/show.html.erb and orders/new.html.erb. And to do so, I have <%= yield %> in line_items/_line_item.html.erb
Line items layout for cart main layout line_items/_main.html.erb
<tr>
<td><%= link_to "#{line_item.product.brand.name} #{line_item.product.title}", product_path(line_item.product) %></td>
<td>
<%= link_to "-", decrement_line_item_path(line_item), :method => :post %>
<%= line_item.quantity %>
<%= link_to "+", increment_line_item_path(line_item), :method => :post %>
</td>
<td><%= number_to_euro(line_item.product.price) %></td>
<td><%= number_to_euro(line_item.total_price) %></td>
<td><%= link_to "Remove"), line_item, :method => :delete %></td>
</tr>
And similar line items layout for new order view line_items/_order.html.erb
<tr>
<td><%= "#{line_item.product.brand.name} #{line_item.product.title}" %></td>
<td><%= line_item.quantity %></td>
<td><%= number_to_euro(line_item.product.price) %></td>
<td><%= number_to_euro(line_item.total_price) %></td>
</tr>
This is where the problem starts. I don't understand how to render collection. I tried rendering line items from carts/_main.html.erb like this
<%= render :partial => 'line_items/line_item', :layout => 'line_items/main', :collection => #line_items %>
And from carts/_order.html.erb like this
<%= render :partial => 'line_items/line_item', :layout => 'line_items/order', :collection => #line_items %>
But I get LocalJumpError in Carts#show
Showing app/views/line_items/_line_item.html.erb where line #1 raised:
no block given (yield)
Any other :collection name simply renders nothing. What am I doing wrong?
Okay, I understand what I've done wrong. First of all, the error message no block given (yield) means there is nothing to yield. And second, there is no need to use :layout when rendering partials in this case.
To render a cart from layouts/_sidebar.html.erb simply call <%= render :partial => 'carts/sidebar' %>.
There is one thing I didn't know about. When rendering partial with collection, the second part of :partial name becomes local variable name inside that collection.
This is the partial for main cart view (carts/_cart.html.erb):
<table>
<tr>
<td>Product</th>
<td>Price</th>
<td>Quantity</th>
<td>Subtotal</th>
<td></th>
</tr>
<%= render :partial => 'line_items/cart_item', :collection => #line_items %>
<tr>
<td colspan="3">Total:</td>
<td><%= number_to_euro(#cart.total_price) %></td>
<td></td>
</tr>
</table>
Which can be rendered by <%= render #cart %>. Notice the /cart_item part in :partial name. That's how we refer to collection items in line_items/_cart_item.html.erb:
<tr>
<td><%= link_to "#{cart_item.product.brand.name} #{cart_item.product.title}", product_path(cart_item.product) %></td>
<td><%= number_to_euro(cart_item.product.price) %></td>
<td>
<%= link_to "-"), decrement_line_item_path(cart_item), :method => :post %>
<%= cart_item.quantity %>
<%= link_to "+"), increment_line_item_path(cart_item), :method => :post %>
</td>
<td><%= number_to_euro(cart_item.total_price) %></td>
<td><%= link_to "Remove"), cart_item, :method => :delete %></td>
</tr>
And the same way with cart shown in Orders controller. carts/_order.html.erb:
...
<%= render :partial => 'line_items/order_item', :collection => #line_items %>
...
line_items/_order_item.html.erb:
<tr>
<td><%= "#{order_item.product.brand.name} #{order_item.product.title}"%></td>
<td><%= number_to_euro(order_item.product.price) %></td>
<td>× <%= order_item.quantity %></td>
<td><%= number_to_euro(order_item.total_price) %></td>
<td></td>
</tr>
Hope it all makes sense.

Resources