Skip to content

Instantly share code, notes, and snippets.

@cmaujean
Created September 30, 2011 18:13
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save cmaujean/1254548 to your computer and use it in GitHub Desktop.
Save cmaujean/1254548 to your computer and use it in GitHub Desktop.
Spree Add to Cart AJAX for spree 0.60-stable
<!-- app/views/orders/_add_dialog.html.erb -->
<div id="add_to_cart_dialog">
Your item(s) have been added. You now have <%= order.item_count %>
items valued at <%= number_to_currency order.item_total %> in your cart.<br/>
<div id="buttons" style="margin-top: 10px; width: 100%;">
<button id="continue_shopping_button" style="float: left;" type="button">Continue Shopping (10)</button>
<button id="view_cart_button" style="margin-left: 10px; float: left;clear: right;" type="button">Checkout Now</button>
</div>
</div>
<!-- app/views/products/_cart_form.html.erb -->
<% content_for :head do %>
<link rel="stylesheet" type="text/css" media="all" href="/stylesheets/custom-theme/jquery-ui-1.8.5.custom.css" />
<%= javascript_include_tag "jquery-ui-1.8.5.custom.min.js" %>
<script type="text/javascript">
$(document).ready(function() {
$("#cart-form").find("form").submit(function() {
$.post($(this).attr("action"), $(this).serialize(), null, "script");
return false;
})
});
</script>
<% end %>
<%= form_for :order, :url => populate_orders_url do |f| %>
<%= hook :inside_product_cart_form do %>
<% if product_price(@product) %>
<%= hook :product_price do %>
<p class="prices">
<%= t("price") %>: <span class="price selling"><%= product_price(@product) %></span>
</p>
<% end %>
<% end %>
<% if @product.has_variants? %>
<div id="product-variants">
<h2><%= t('variants') %></h2>
<ul>
<% has_checked = false
@product.variants.active.each_with_index do |v,index|
next if v.option_values.empty? || (!v.in_stock && !Spree::Config[:show_zero_stock_products])
checked = !has_checked && (v.in_stock || Spree::Config[:allow_backorders])
has_checked = true if checked %>
<li>
<label>
<%= radio_button_tag "products[#{@product.id}]", v.id, checked, :disabled => !v.in_stock && !Spree::Config[:allow_backorders] %>
<span class="variant-description">
<%= variant_options v %>
</span>
<% if variant_price_diff v %>
<span class="price diff"><%= variant_price_diff v %></span>
<% end %>
</label>
</li>
<% end%>
</ul>
</div>
<% end%>
<% if @product.has_stock? || Spree::Config[:allow_backorders] %>
<div style="height: 26px;line-height: 26px;">
<table>
<tr>
<td><%= text_field_tag (@product.has_variants? ? :quantity : "variants[#{@product.master.id}]"), 1, :class => "form fblock " + (@product.uom == "LB" ? "decimal" : "integer"), :size => 3 %></td>
<td><input class="prodbutton" type="image" id="add_to_cart_button" src="/images/add_to_cart.png" style="display: block; float: left; margin-left: 20px;" class="form fblock"/></td>
</tr>
</table>
</div>
<% else %>
<%= content_tag('strong', t('out_of_stock')) %>
<% end %>
<% end %>
<% end %>
<% content_for :head do %>
<%= javascript_include_tag 'product' %>
<% end %>
# app/controllers/orders_controller_decorator.rb
OrdersController.class_eval do
respond_to :html, :js
# override populate method to allow for floating point quantities
def populate
@order = current_order(true)
params[:products].each do |product_id,variant_id|
quantity = params[:quantity].to_f if !params[:quantity].is_a?(Hash)
quantity = params[:quantity][variant_id].to_f if params[:quantity].is_a?(Hash)
@order.add_variant(Variant.find(variant_id), quantity) if quantity > 0
end if params[:products]
params[:variants].each do |variant_id, quantity|
quantity = quantity.to_f
@order.add_variant(Variant.find(variant_id), quantity) if quantity > 0
end if params[:variants]
respond_with(@order) do |format|
format.html { redirect_to cart_path }
end
end
end
// app/views/orders/populate.js.erb
// create the dialog
var button_clicked = false;
$('<div id="dialog"></div>')
.html("<%= raw(escape_javascript(render(:partial => 'add_dialog', :locals => {:order => @order}))) %>")
.dialog({
title: "Added to Cart",
modal: true,
hide: {effect: "fadeOut", duration: 500},
autoOpen: false,
minWidth: 400
}).dialog("open")
// Set up callback for click event outside of the dialog
$('div.ui-widget-overlay').click(function() {
$('div#dialog').dialog("close").dialog("destroy").remove();
button_clicked = true;
})
// Set up callback for click event on view cart button in dialog
$("button#view_cart_button").click(function() {
$('div#dialog').dialog("close").dialog("destroy").remove();
button_clicked = true;
window.location = "<%= cart_path(@order) %>";
})
// Set up callback for click event on continue shopping button in dialog
$('button#continue_shopping_button').click(function() {
$('div#dialog').dialog("close").dialog("destroy").remove();
button_clicked = true;
})
// performs the countdown and clicks the continue shopping button when countdown expires
function dotimes(amount) {
if(button_clicked == true) {
button_clicked = false;
return;
}
$('button#continue_shopping_button').html("Continue Shopping (" + amount + ")");
if (amount == 0 ) {
if ( <%= ENV['RAILS_ENV'] == "test" or ENV['RAILS_ENV'] == "cucumber" ? false : true %> ) {
$('button#continue_shopping_button').trigger('click');
}
return;
} else {
amount = amount - 1;
setTimeout("dotimes(" + amount + ")", 1000);
}
}
// updates the cart info display with the new order info
$('a[title="Shopping Cart"] span').replaceWith('<span>Shopping&nbsp;Cart&nbsp;' + "<%= escape_javascript(render(:partial => 'shared/cart_info'))%>" + '&nbsp;<img src="/images/cart.png" alt=" " /></span>');
// Fix the stretchbar length
stretchbar();
// perform the countdown
dotimes(10);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment