Skip to content

Instantly share code, notes, and snippets.

@estum
Last active August 29, 2015 13:56
Show Gist options
  • Save estum/8997477 to your computer and use it in GitHub Desktop.
Save estum/8997477 to your computer and use it in GitHub Desktop.
Bootstrap 2 tabs helper method for Ruby on Rails
# helpers/bootstrap_helper/tabbable.rb
# Bootstrap 2 tabs helper method for Ruby on Rails
# http://getbootstrap.com/2.3.2/components.html
#
# == Usage (slim):
#
# = tabbable do |t|
# = t.section :tab_1 do
# / Content for Tab #1
# = render "partial"
# = t.section :tab_2, "Title for tab 2" do
# / Content for Tab #2
# / ...
module BootstrapHelper
module Tabbable
TABBABLE_CLASS_KEY = [:below, :right, :left]
def tabbable(*args, &block)
return unless block_given?
options = args.extract_options!.reverse_merge class: %w(tabbable)
options[:class] << "tabs-#{args.shift.to_s}" if TABBABLE_CLASS_KEY.include?(args.first)
tabbable_block = Wrapper.new(self)
block.call tabbable_block
content_tag(:div, options) { tabbable_block.call }
end
# Wrapper delegator
class Wrapper < SimpleDelegator
attr_accessor :tabs
def tabs
@tabs ||= []
end
def section(*args, &block)
self.tabs << SectionDecorator.new(Section.new(tabs.count, *args, &block), __getobj__)
return
end
def call
safe_join [
content_tag(:ul, show_each_tab(&:as_nav_item), class: %w(nav nav-tabs)).html_safe,
content_tag(:div, show_each_tab(&:as_tab_pane), class: %w(tab-content)).html_safe
]
end
private
def show_each_tab(&block)
safe_join tabs.map(&block)
end
end
# Section model
class Section
attr_reader :key, :title, :block
def initialize(*args, &block)
@position, @key, @title = args
@title ||= I18n.t @key, default: @key.to_s.humanize, scope: "helpers.tabs"
@block = block
end
def first?
@position == 0
end
def to_href
"##{key}"
end
end
# Section decorator
class SectionDecorator < SimpleDelegator
attr_accessor :template
delegate :content_tag, :link_to, to: :template
def initialize(object, template)
super(object)
@template = template
end
def as_nav_item
content_tag(:li, as_link.html_safe, html_attrs).html_safe
end
def as_tab_pane
content_tag(:div, html_attrs(class: %w(tab-pane), id: key), &block).html_safe
end
def as_link
link_to title, to_href, data: { toggle: 'tab' }
end
private
def html_attrs(attrs={})
(attrs[:class] ||= []) << "active" if first?
attrs
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment