I have a Cart/show.html erb with that renders a partial called carts_row.html.erb
<p id="notice"><%= notice %></p>
</br>
</br>
<div class="cart-container">
<%=render 'carts_row'%>
</div>
</p>
In carts_row it's a shopping cart layout with forms to update quantity and destroy/remove item from your shopping cart.
<h1>Shopping Cart</h1>
<div class="shopping-cart">
<div class="column-labels">
<label class="product-image">Image</label>
<label class="product-details">Product</label>
<label class="product-price">Price</label>
<label class="product-quantity">Quantity</label>
<!-- adding update column to labels -->
<label class="product-update">Update</label>
<label class="product-removal">Remove</label>
<label class="product-line-price">Total</label>
</div>
<%if #cart.cart_items.size == 0%>
<div class="text-center">
<p>Looks like you have nothing in your cart! <%=link_to 'Add something to your cart', products_path%></p>
</div>
<%end%>
<br />
<br />
<%if #cart_items != nil%>
<%#cart_items.each do |item|%>
<div class="product">
<div class="product-image">
<%=image_tag(item.product.picture)%>
</div>
<div class="product-details">
<div class="product-title"><%=item.product.name%></div>
<p class="product-description"><%=item.product.description%></p>
</div>
<div class="product-price"><%=number_to_currency(item.product.price)%></div>
<%=form_for item, remote: true do |f|%>
<div class="product-quantity">
<%=f.number_field :quantity, value: item.quantity, min: 1, max: 8%>
<%=f.hidden_field :product_id, value: item.product.id%>
<!-- <input type="number" value="<%=item.quantity%>" min="1" max="8"> -->
</div>
<div class="product-update">
<%=f.submit 'Update', class: "update-product"%>
<!-- <%=f.hidden_field :product_id, value: item.product.id%> -->
<!-- <button class="update-product">
Update
</button> -->
</div>
<div class="product-removal">
<%= link_to "Remove", item, {data: {confirm: "Are you sure you wish to delete the product '#{item.product.name}' from your cart?"}, method: :delete, remote: true, class: "remove-product"}%>
<!-- <button class="remove-product">
Remove
</button> -->
<%end%>
</div>
<div class="product-line-price"><%=number_to_currency(item.product.price*item.quantity)%></div>
</div>
<%end%>
<%end%>
<br />
<br />
<!--Temporary solution until model methods are written -->
<% if #cart_items != nil%>
<!--subtotal variable -->
<%subtotal =#cart_items.collect {|item| item.quantity*item.unit_price}.sum%>
<!--subtotal + shipping cost -->
<%total=subtotal+15%>
<%end%>
<div class="totals">
<div class="totals-item">
<label>Subtotal</label>
<div class="totals-value" id="cart-subtotal"><%=subtotal%></div>
</div>
<div class="totals-item">
<label>Tax (5%)</label>
<div class="totals-value" id="cart-tax">Included!</div>
</div>
<div class="totals-item">
<label>Shipping</label>
<div class="totals-value" id="cart-shipping">15.00</div>
</div>
<div class="totals-item totals-item-total">
<label>Grand Total</label>
<div class="totals-value" id="cart-total">
<%=total%>
</div></div>
</div>
</div>
<div class="checkout-btn">
<button class="checkout">Checkout</button>
</div>
</div>
The update in the form goes to update.js.erb which has this
<% if #cart.errors.any? || #cart_item.errors.any? %>
alert("Not valid.");
<%else%>
$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text')%>")
$(".cart-container").html("<%= escape_javascript(render 'carts/carts_row')%>")
<%end%>
And destroy in the form has a same destroy.js.erb
<% if #cart.errors.any? || #cart_item.errors.any? %>
alert("Not valid.");
<%else%>
$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text')%>")
$(".cart-container").html("<%= escape_javascript(render 'carts/carts_row')%>")
<%end%>
The update renders the carts_row.html.erb form properly.
When I destroy an item it renders the page with empty products and a checkout total at the bottom. When I refresh the page the correct amount of products in the shopping cart is displayed and everything is where it should be!
How is the render of update correct but render of destroy incorrect???
My carts_item controller has these two methods for the forms:
def update
#cart = current_cart
# finding cart_items by cart_id
#cart_item = #cart.cart_items.find(params[:id])
# #cart_items.order(:id)
#cart_item.update_attributes(cart_item_params)
#cart_items = #cart.cart_items.order(:id)
# redirect 'cart_show_path'
end
def destroy
#cart = current_cart
#cart_item = #cart.cart_items.find(params[:id])
#cart_item.destroy
#cart_items = #cart.cart_items
end
You're destroying the item from cart, but not removing it from #cart.cart_items
Try doing this
def destroy
#cart = current_cart
#cart_item = #cart.cart_items.find(params[:id])
#Find the index of #cart_item
item_index = #cart.cart_items.index(#cart_item)
#Remove it from #cart.cart_items when its destroyed successfully
if #cart_item.destroy
#cart.cart_items.delete_at(item_index)
end
#cart_items = #cart.cart_items
end
Let me know if it works!
I figured out the problem. The problem was that I was using a <% if #cart_items != nil %> check in my view.
This always returns false, because ActiveRecord will always return an array!!!!!!!!!! Whether it has product objects in the #cart_items object or not.
After I changed this to test for empty arrays with #cart_items.empty?, then the page worked like I wanted it to.
Thanks kumar for your input.
Related
I am figuring out why it showing duplicate data on the front page:
All I did is to use Rails collection rendering.
Here's my application.html.erb file:
<body>
<%= render 'layouts/navbar' %>
<!-- content -->
<main class="pt-5">
<div class="container">
<div class="row">
<%= render 'layouts/sidebar' %>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</main>
</body>
</html>
Here's my index.html.erb file:
<div class="col-md-9">
<% if #contacts.blank? %>
<div class="alert alert-warning">
<strong>Record is empty!</strong>
</div>
<% else %>
<div class="card">
<div class="card-header"><strong>All Contacts</strong></div>
<table class="table">
<%= render #contacts %>
</table>
</div>
</div>
<% end %>
and here's my _contact.html.erb file:
<% #contacts.each do |contact| %>
<tr>
<td class="middle">
<div class="media">
<div class="media-left">
<a href="#">
<%= image_tag contact.gravatar, class: "media-object" %>
</a>
</div>
<div class="media-body">
<h4 class="media-heading"><%= contact.name %></h4>
<address>
<strong><%= contact.address %>, <%= contact.city %>, <%= contact.state %>, <%= contact.zip %></strong><br>
<%= contact.email %> | <%= contact.phone %> | <%= contact.mobile %>
</address>
</div>
</div>
</td>
<td width="100" class="middle">
<div>
<a href="#" class="btn btn-outline-secondary btn-circle btn-xs" title="Edit">
<i class="fa fa-edit"></i>
</a>
<a href="#" class="btn btn-outline-danger btn-circle btn-xs" title="Delete">
<i class="fa fa-times"></i>
</a>
</div>
</td>
</tr>
<% end %>
BTW, I am using Kaminari Gem for pagination. It works however the data shows twice.
Any idea?
UPDATES:
Here's my contacts controller:
class ContactsController < ApplicationController
def index
#contacts = Contact.page params[:page]
end
end
Here's the kaminari config file:
# frozen_string_literal: true
Kaminari.configure do |config|
config.default_per_page = 2
# config.max_per_page = 4
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
# config.params_on_first_page = false
end
When you do <%= render #contacts %>, Rails will loop results from #contacts and render each one using _contact.html.erb, while embedding local variable contact in each one. You see contacts twice, because you loop twice: remove <% #contacts.each do |contact| %> from _contact.html.erb and it should work.
I'm trying to do an edit object in Ruby on Rails using a modal form, when I try to do the link_to edit_plane_path(plane) in planes.html.erb I get the following error:
undefined local variable or method `plane' for #<#:0xd580e98>
Did you mean? #plane
plane_url
#planes
However, trying any of those doesn't really change the fact that I still get an error on the page and I can't even load it.
planes.html.erb
<table>
<thead>
<tr>
<th>Image</th>
<th>Operating agency</th>
<th>Date</th>
<th>Call sign</th>
<th>Country</th>
<th>Info</th>
<th>Action</th>
</tr>
<thead>
<tbody>
<% #planes.each do |p| %>
<tr class="gradeC">
<td>
<%= image_tag(p.image, size: "150x150")%></td>
<td class="w-25"><%= p.provider%>
</td>
<td><%= p.brand%></td>
<td class="center"><%= p.year%></td>
<td class="center"><%= p.call_sign%></td>
<td><%= p.country%></td>
<td><%= p.info%></td>
<td class="text-right">
<div class="btn-group">
<%= link_to 'Edit', edit_plane_path(plane), remote: true, :class =>'btn white btn btn-xs' %>
<button class="btn-white btn btn-xs">Delete</button>
</div>
</td>
</tr>
</tbody>
<% end %>
</table>
_form.html.erb
<!-- FORM EDIT -->
<div id="edit-plane" class="modal fade" aria-hidden="true">
<div class="modal-dialog modal-md">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div class="col-sm-12"><h3 class="m-t-none m-b">Edit plane</h3>
</div>
</div>
<%= form_for #plane, url: planes_path, remote: true do |f| %>
<div class="form-group row">
<div class="col-sm-6">
<label>Brand</label>
<%= f.text_field :brand, class:"form-control"%>
</div>
<div class="col-sm-5">
<label>Model</label>
<%= f.text_field :model, class:"form-control"%>
</div>
</div>
<div class="form-group row">
<div class="col-sm-5">
<label>Year</label>
<%= select_tag :hyear, options_for_select(["2015","2016","2017","2018","2019"], "2019"), class:"select2_demo_1 form-control" %>
<%= f.hidden_field :year %>
</div>
<div class="col-sm-6">
<label>Country</label>
<%= select_tag :hcountry, nil, class:"select2_demo_1 form-control" %>
<%= f.hidden_field :country %>
</div>
<script language="javascript">
populateCountries("hcountry");
</script>
</div>
<div class="form-group row">
<div class="col-sm-6">
<label>Provider</label>
<%= select_tag :hprovider, options_for_select([ "Test", "Test2"], "Test"), class:"select2_demo_1 form-control"%></select>
<%= f.hidden_field :provider %>
</div>
<div class="col-sm-5">
<label>Tactical call sign</label>
<%= f.text_field :call_sign, class:"form-control"%>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6">
<label>Extra info</label>
<%= f.text_area :info %>
</div>
<div class="col-sm-5">
<label>Image</label>
<%= f.file_field :image %>
</div>
</div>
<!-- SUBMIT -->
<button class="btn btn-primary btn-lg float-right ml-2" id="cancelbtn">Cancel</button>
<%= f.submit "Submit", id:"edpla", class: 'btn btn-primary btn-lg float-right'%>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>
edit.js.erb
// Add the dialog title
$('#edit-plane h3').html("<i class=' glyphicon glyphicon-pencil'></i> Edit Plane");
// Render the edit form
$('.modal-body').html('<%= j render("form") %>');
// Show the dynamic dialog
$('#edit-plane').modal("show");
// Set focus to the first element
$('#edit-plane').on('shown.bs.modal', function () {
$('.first_input').focus()
})
update.js.erb
$('#edit-plane').modal('toggle');
$('#customer_<%= #plane.id %>').replaceWith('<%= j render (#plane) %>')
planes_controller.rb
class PlanesController < ApplicationController
def planes
#plane = Plane.new
#planes = Plane.all
end
def create
#plane = Plane.new(plane_params)
if #plane.save
flash[:success] = "Plane successfully added"
redirect_to :planes => 'post', :action => 'planes'
else
flash[:error] = "Something went wrong"
render 'planes'
end
end
def edit
#plane = Plane.find(params[:id])
end
def update
respond_to do |format|
if #plane.update(plane_params)
format.json { head :no_content }
format.js
else
format.json { render json: #customer.errors.full_messages, status: :unprocessable_entity }
end
end
end
private
def plane_params
params.require(:plane).permit(:brand, :model, :provider, :call_sign, :user, :country, :image, :info, :year)
end
end
My goal is to edit a plane in the table through a modal form, but I can't even show the page at the moment.
Here:
<% #planes.each do |p| %>
...you are passing each plane as p. Therefore, try:
<%= link_to 'Edit', edit_plane_path(p), remote: true, class: 'btn white btn btn-xs' %>
I have hit a brick wall. I've been hacking at this problem for so long now, I'm not even sure how I got to where I am. All I can say is, I've tried all of the below without success:
How to add bootstrap modal with link_to so the link content open in modal ?
How to show twitter bootstrap modal via JS request in rails?
rails link_to :remote
http://apidock.com/rails/ActionView/Helpers/PrototypeHelper/link_to_remote
How do I render "new", "edit" and "delete" views within Bootstrap modals on the "index" view rather than linking to separate pages for each?
Here is my code as it stands now. For now, lets ignore "edit" and "delete" and just focus on "new". When I click the "New" button, a modal with the string "<%= j render "items/new" %>" appears (instead of the form that that ruby statement should render). What am I doing wrong?:
items_controller.rb:
class ItemsController < ApplicationController
def index
#items = Item.all
end
def new
respond_to do |format|
format.js {}
end
end
def create
#item = Item.new(item_params)
if #item.save
flash[:notice] = "'#{#item.name}' saved!"
redirect_to items_path
else
flash[:notice] = "Something went wrong :("
render "index"
end
end
def edit
#item = Item.find(params[:id])
respond_to do |format|
format.js {}
end
end
def update
#item = Item.find(item_params[:id])
if #item.update_attributes(item_params)
flash[:notice] = "Successfully updated #{#item.name}."
redirect_to items_path
else
flash[:notice] = "Oops"
# render "edit"
end
end
private
def item_params
params.require(:item).permit(:name, :bid, :uuid)
end
end
items/index.html.erb
<div class="row">
<div class="col-xs-12">
<%= link_to "New", new_item_path, remote: true, class: "btn btn-success pull-right new", data: { toggle: "modal", target: "#newModal" } %>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<table class="table table-hover items">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>UUID</th>
<th colspan="2">Links</th>
</tr>
</thead>
<tbody>
<% #items.each do |item| %>
<tr>
<td><%= item.id %></td>
<td><%= item.name %>
<!-- edit/remove icons -->
<span class="edit-remove">
<%= link_to edit_item_path(item.id), remote: true, data: { toggle: "modal", target: "#editModal" } do %>
<span class="glyphicon glyphicon-pencil text-muted"></span>
<% end %>
<a href="#">
<span class="glyphicon glyphicon-remove text-muted"></span>
</a>
</span>
</td>
<td><%= item.uuid %></td>
<td><%= link_to "XXX", "http://xxx" %></td>
<td><%= link_to "XXXX", "http://xxx", target: "_blank" %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<!-- newModal skeleton -->
<div class="modal fade" id="newModal">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
<!-- editModal skeleton -->
<div class="modal fade" id="editModal">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
<!-- deleteModal skeleton -->
<div class="modal fade" id="deleteModal">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
items/new.html.erb
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
<h4 class="modal-title">New Item</h4>
</div>
<div class="modal-body">
<%= form_for :item, url: { action: "create" } do |f| %>
<div class="form-group">
<%= f.label :name, "Name" %>
<%= f.text_field :name, { class: "form-control" } %>
</div>
<div class="form-group">
<%= f.label :bid, "BID" %>
<%= f.text_field :bid, { class: "form-control" } %>
</div>
<div class="form-group">
<%= f.label :uuid, "UUID" %>
<%= f.text_field :uuid, { class: "form-control" } %>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<%= submit_tag "Save", class: "btn btn-primary" %>
<% end %>
</div>
javascripts/items.js
$(document).on("page:change", function() {
$("#newModal .modal-content").html('<%= j render "items/new" %>');
});
In the case of new for instance, you want to render a javascript file. For this, you'll need to create items/new.js.erb.
Also, remove ", data: { toggle: "modal", target: "#newModal" }" from your link, we will do that in the javascript.
# new.js.erb
$("#newModal .modal-content").html('<%= j render "items/form" %>');
$("#newModal").modal(); // Or whatever the Bootstrap function is to render the modal
# items/_form.html.slim
# Here you'll put your form
You cannot use "render" on views directly, you should render partials and not views (this is why I asked you to put your form into a partial).
I threw this together and it puts a big '3' in my document 3 seconds after loading it:
<script>
setTimeout(function() {
$("#holder").html("<%= j render(:file => 'things/test.html.erb') %>");
}, 3000);
</script>
<div id="holder></div>
app/views/things/test.html.erb:
<h1><%= 1 + 2 %></h1>
That should get you going.
so I've created a web app that has user profiles, where users can search for fellow users based on interests etc.. How might I add a feature where users can favorite a persons profile? I.e. User A finds User B and likes what they see, and can click a 'Favorite this profile' button and perhaps it's starred, and stored? What would the code look like for this? Just an idea, but I'm open to all ideas.
user_profile.html.erb
<%= render "shared/header" %>
<div id="landing_welcome_page">
<div class="container">
<div class="row">
<%#= Profile image upload %>
<div class="span4">
<%= user_avatar(current_user) %>
<%#= Space w line %>
<div class="name"></div><br>
<%#= Please bare in mind these are strickly temporary placeholders i.e whitespace %>
<%= render 'social' %>
</div>
<div class="span8">
<%# User name %>
<span class="name1">
<% if current_user.first_name.blank? %>
<%= current_user.first_name.present? ? current_user.first_name : link_to('Finish your profile', edit_account_path)%>
<% else %>
<%= current_user.first_name %> <%= current_user.last_name %>
<% end %>
</span>
<span class="side-buttons">
<div class="name"></div>
</span>
</span>
</div>
<div class="row">
<br />
<div class="span6">
<%# User occupation %>
<i class="fa fa-usd"></i>:
<%= best_in_place current_user, :occupation, nil: 'Add occupation' %>
</div>
<div class="addy">
<div class="span2">
<%# User address %>
<i class="fa fa-home"></i>:
<%= current_user.address.present? ? current_user.address : link_to('Add Address', edit_account_path) %>
</div>
</div>
<div class="span6">
<%# User gender %>
<br />
<% if current_user.gender == "M" || "male" %>
<i class="fa fa-male"></i> Male
<% else %>
<i class="fa fa-female"></i> Female
<% end %>
</div>
<div class="span2">
<!-- Code to calculate age by user birthday -->
<br />
Age: <%= user_birthday %>
</div>
<div class="span8"></div>
<div class="span8"><div class="name"></div></div>
<div class="span8">
<div class="tabbable"> <!-- Only required for left/right tabs -->
<ul class="nav nav-tabs">
<li class="active">About me</li>
<li>Photos</li>
<li>Personality</li>
</ul>
<div class="tab-content">
<div class="tab-pane in active" id="tab1">
<% #questions_for_about.each_with_index do |question, index| %>
<div class="question">
<h4 class="user_questions">
<%= index + 1 %>. <%= question.question %>
<%= link_to ("<i class='icon-edit'></i>".html_safe),
edit_user_question_path(current_user, question),
remote: true, class: "edit_link_#{question.id}" %>
</h4>
<div class="answer" id="answer_<%= question.id %>">
<%= answer_for(question) %>
</div>
</div>
<% end %>
</div>
<div class="tab-pane" id="tab2">
<div class="page-header">
<%= form_for Photo.new do |f| %>
<span class="btn btn-success fileinput-button">
<i class="icon-plus icon-white"></i>
<span>Add photos...</span>
<%= f.file_field :file, multiple: true, name: "photo[file]" %>
</span>
<% end %>
<div class="clearfix"></div>
</div>
<div class="photos_cont">
<div class="col-sm-6 col-md-3">
<span class="gallery"><%= render current_user.photos %></span>
</div>
</div>
</div>
<div class="tab-pane" id="tab3">
<% #questions_for_personality.each_with_index do |question, index| %>
<div class="question">
<h4 class="user_questions">
<%= index + 1 %>. <%= question.question %>
<%= link_to ("<i class='icon-edit'></i>".html_safe),
edit_user_question_path(current_user, question),
remote: true, class: "edit_link_#{question.id}" %>
</h4>
<div class="answer" id="answer_<%= question.id %>">
<%= answer_for(question) %>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
<%= render '/shared/footer' %>
</div>
</div>
<script id="template-upload" type="text/x-tmpl">
<div class="upload">
{%=o.name%}
<div class="progress"><div class="bar" style="width: 0%;"></div></div>
</div>
</script>
<script>
var fb_param = {};
fb_param.pixel_id = '6009056882201';
fb_param.value = '0.00';
(function(){
var fpw = document.createElement('script');
fpw.async = true;
fpw.src = '//connect.facebook.net/en_US/fp.js';
var ref = document.getElementsByTagName('script')[0];
ref.parentNode.insertBefore(fpw, ref);
})();
</script>
<noscript>
<img height="1" src="https://www.facebook.com/offsite_event.php?id=6009056882201&value=0" style="display:none;" width="1"/>
</noscript>
<script type="text/javascript">
// remove default datepicker event
jQuery(document).off('best_in_place:datepicker');
jQuery(document).on('best_in_place:datepicker', function(event, bip, element) {
// Display the jQuery UI datepicker popup
jQuery(element).find('input')
.datepicker({
format: element.data('date-format')
})
.on('hide', function(){
bip.update();
})
.on('changeDate', function(){
$(this).datepicker('hide');
})
.datepicker('show');
});
</script>
Create a Favorite model with a has_and_belongs_to_many relationship with User
Once you create the Favorite model and set up the relationship, you can do things like:
#user.favorites = [ user1, user2, user3 ]
#user.favorites << user4
to assign favorites to a user, or display them with something like:
<%= #user.favorites.map(&:name).to_sentence %>
You'll find everything you need to know on how to do this here: http://guides.rubyonrails.org/association_basics.html
I have two models in ruby,
#photos = Photo.all
#comments = Comment.all
#objects = #photos + #comments
I have in my html a button id"only-photo" and a button "only-comments", if i click on the first I want to select only the photos.
how can I do to only select #photos from #objects? in coffeescript
here is what i tried
<div id="list">
<% #objects.each do |l| %>
<% if l.class == "Photo"%>
<div id="photo" class="photo">
<%= render "shared/photo", :photo => l %>
</div>
...
</div>
<div id="filters">
<button id="only-photo">
</button>
...
</div>
then in Coffeescript I just do:
$("#filters").on "click", "#only-photo", ->
$("#list #comment").removeClass "active"
$("#list #photo").addClass "active"
BUT I am sure there is a more elegant way to do these things!
Can't we filter on a scope from coffeescript? or anything like this?
Thank you!
Try this:
<div id="list">
<% #objects.each do |l| %>
<div id="<%= l.class.to_s.downcase %>_<%= l.id %>" class="<%= l.class.to_s.downcase =%>">
<%= render "shared/#{l.class.to_s.downcase}", :photo => l %>
</div>
<% end %>
</div>
<div id="filters">
<button id="only-photo" class="filter" value="photo">
</button>
<button id="only-comment" class="filter" value="comment">
</button>
</button>
</div>
Coffee:
$("button.filter").on "click", ->
class_to_hide = $(this).attr('value')
$("."+class_to_hide).toggleClass('active')