Skip to content

Instantly share code, notes, and snippets.

@universal
Created March 20, 2012 10:18
Show Gist options
  • Save universal/2133861 to your computer and use it in GitHub Desktop.
Save universal/2133861 to your computer and use it in GitHub Desktop.
Improve Spree's checkout step indicator
# At this checkout step indicator, all the checkout steps are turned into links. But how to
# turn *only* my completed steps into links?
#
# <jammanbo> state_machine has no memory. if you need to determine whether you have been
# in a state you need to design your machine so that that can be determined from the
# current state.
#
# ----------
#
# Expected result:
#
# <ol id="progress-bar">
# <li class="active">Address</li>
# <li>Delivery</li>
# <li>Payment</li>
# <li>Complete</li>
# </ol>
#
# <ol id="progress-bar">
# <li><a href="/checkout/address">Address</a></li>
# <li><a href="/checkout/delivery">Delivery</a></li>
# <li class="active">Payment</li>
# <li>Complete</a></li>
# </ol>
#
# Current result:
#
# <ol id="progress-bar">
# <li class="active">Address</li>
# <li><a href="/checkout/delivery">Delivery</a></li>
# <li><a href="/checkout/payment">Payment</a></li>
# <li><a href="/checkout/complete">Complete</a></li>
# </ol>
#
# ----------
#
# App available for testing: https://github.com/mikkelb/tootie
#
def checkout_progress(order)
states = checkout_states
current_index = states.index(order.state)
items = states.map do |state|
text = t("order_state.#{state}").titleize
state_index = states.index(state)
if state == order.state
options = { :class => "active" }
end
if state_index <= current_index
text = link_to text, checkout_state_path(state)
end
content_tag "li", text, options
end
content_tag("ol", items.join.html_safe, :class => "progress-bar")
end
<%= checkout_progress(@order) %>
# Result:
#
# <ol class="progress-steps" id="checkout-step-address">
# <li class="current-first"><span>Address</span></li>
# <li class="next"><span>Delivery</span></li>
# <li class=""><span>Payment</span></li>
# <li class="last"><span>Complete</span></li>
# </ol>
#
def checkout_progress
states = checkout_states
items = states.map do |state|
text = t("order_state.#{state}").titleize
css_classes = []
current_index = states.index(@order.state)
state_index = states.index(state)
if state_index < current_index
css_classes << 'completed'
text = link_to text, checkout_state_path(state)
end
css_classes << 'next' if state_index == current_index + 1
css_classes << 'current' if state == @order.state
css_classes << 'first' if state_index == 0
css_classes << 'last' if state_index == states.length - 1
# It'd be nice to have separate classes but combining them with a dash helps out for IE6 which only sees the last class
content_tag('li', content_tag('span', text), :class => css_classes.join('-'))
end
content_tag('ol', raw(items.join("\n")), :class => 'progress-steps', :id => "checkout-step-#{@order.state}")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment