This is my first question so I hope I can be as specific as possible, but don't be harsh.
I'm going through Agile Web Development with Rails and am very new to programming.
I want to hide a 'Checkout' button while I am on the order/new page so that it can't do anything nasty to the users purchase.
At the moment, I don't really understand how instance variables work, since it seems like no matter where I declare my instance variable, in a view or in orderscontroller#new, it always validates to true.
This seems to be the case because when I use the instance variable in the view to hide a div ( with hidden_div_if(condition == true) ) the buttons ALWAYS get hidden!
Not only that, but when I do:
<%= hidden_div_if( @hide_checkout_button == false ) do %>
<td><%= button_to 'Empty cart', cart, :method => :delete,
:confirm => 'Are you sure?' %></td>
<% end %>
<%= hidden_div_if( @hide_checkout_button == true ) do %>
<td><%= button_to "Checkout", new_order_path, :method => :get %></td>
<% end %>
BOTH buttons get hidden! How can that be!?!
In this example, I have placed the variable declaration in views\orders_form.html.erb:
<%= @hide_checkout_button = true %>
<%= form_for(@order) do |f| %>
<% if @order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@order.errors.count, "error") %>
prohibited this order from being saved:</h2>
<ul>
<% @order.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
...
Here is a discussion-forum with solutions for this problem, but they don't work for me and I don't know why: http://pragprog.com/wikis/wiki/Pt-G-2/version/35
And here is the question itself:
What happens if you click the Checkout button in the sidebar while the checkout screen is already displayed? Can you find a way to disable the button in this circumstance? (Hint: variables set in the controller are available in layouts and partials as well as in the directly rendered template.)
If you need any more information to help please ask, I'm not quite sure how much detail to provide or what information is important.
Thanks in advance :-)
def new
@cart = current_cart
if @cart.line_items.empty?
redirect_to store_url, :notice => "Your cart is empty"
return
end
puts 34
@hide_checkout_button = true
@order = Order.new
puts 37
respond_to do |format|
format.html # new.html.erb
format.json { render json: @order }
end
end
Started GET "/assets/logo.png" for 127.0.0.1 at 2012-11-13 20:33:40 +0000 Served asset /logo.png - 304 Not Modified (1ms) [2012-11-13 20:33:40] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true * 34 37 * /orders/new
Started GET "/orders/new" for 127.0.0.1 at 2012-11-13 20:33:49 +0000 Processing by OrdersController#new as HTML ←[1m←[36mCart Load (1.0ms)←[0m ←[1mSELECT "carts".* FROM "carts" WHERE "carts "."id" = ? LIMIT 1←[0m [["id", 63]] ←[1m←[35m (1.0ms)←[0m SELECT COUNT(*) FROM "line_items" WHERE "line_items"."c art_id" = 63
The problem is a missing =
. do <%= %>
instead.
<%= hidden_div_if( @hide_checkout_button == true ) do %>
<td><%= button_to "Checkout", new_order_path, :method => :get %></td>
<% end %>
Also, for boolean checks you can just do if(boolean)
which will evaluate the same as if you put ==
true
/false
<%= hidden_div_if( @hide_checkout_button) do %>
#...
<% end %>
You want to set that variable on the method that calls the view. In this case it is the new
method in OrdersController
def new
@hide_checkout_button = true
end
Edit:
add this to the hidden div just to see if it helps finding the element to set the attribute to
<%= hidden_div_if(@hide_checkout_button, id: 'cart') do %>
with (in the application helper)
def hidden_div_if(condition, attributes = {}, &block
if condition
attributes["style"] = "display: none"
end
content_tag("div", attributes, &block)
end
if that doesn't do it, then just do it this way
<% if @hide_checkout_button %>
<td><%= button_to "Checkout", new_order_path, :method => :get %></td>
<% else %>
<td><%= button_to 'Empty cart', cart, :method => :delete, :confirm => 'Are you sure?' %></td>
<% end %>