Skip to content

Instantly share code, notes, and snippets.

@backpackerhh
Last active August 29, 2015 14:00
Show Gist options
  • Save backpackerhh/11333441 to your computer and use it in GitHub Desktop.
Save backpackerhh/11333441 to your computer and use it in GitHub Desktop.
Modals in Rails with jQuery, Haml, SASS & Twitter Bootstrap 2.3+
// Some basic styles
.modal {
width: 660px;
.modal-header {
.close {
margin: 0;
padding: 0;
&:hover { opacity: 1; }
}
h3 { font-size: 20px; }
}
.modal-body {
padding: 10px;
position: relative;
}
}
def link_to_modal(*args, &block)
if block_given?
name = capture(&block)
options = args[0] || {}
html_options = args[1] || {}
else
name = args[0]
options = args[1] || {}
html_options = args[2] || {}
end
link_to name, options, html_options.merge('data-toggle' => 'modal', role: 'button')
end
def modal(id, label_id = "#{id}Label", label:, &block)
raise ArgumentError.new 'No block given with modal content' unless block_given?
capture_haml do
haml_tag :div, {
id: id,
class: 'modal hide fade',
tabindex: -1,
role: 'dialog',
'aria-labelledby' => label_id,
'aria-hidden' => true
} do
haml_tag :div, class: 'modal-header' do
haml_tag :button, {
type: 'button',
class: 'btn btn-link close',
'data-dismiss' => 'modal',
'aria-hidden' => true
} do
haml_tag :img, src: '<path/to/image>', alt: '<Alternative text>'
end
haml_tag :h3, label, id: label_id
end
haml_tag :div, capture(&block), class: 'modal-body'
end
end
end
# Use 'nokogiri' gem to check HTML nodes.
# Note: I prefer to skip the "single expectation test" in this kind of test.
describe "link_to_modal(*args, &block)" do
let(:block) { ->{ content_tag(:strong, 'myText') } }
context "with a block" do
it "creates a link with given block and target to open related modal" do
link = Nokogiri::HTML(helper.link_to_modal('#target', &block)).css('a')[0]
expect(link.attributes['href'].value).to eq('#target')
expect(link.attributes['data-toggle'].value).to eq('modal')
expect(link.attributes['role'].value).to eq('button')
expect(link.css('strong')[0].text).to eq('myText')
end
it "creates a link with given block, target, and attributes to open related modal" do
link = Nokogiri::HTML(helper.link_to_modal('#target', id: 'myLink', &block)).css('a')[0]
expect(link.attributes['id'].value).to eq('myLink')
end
end
context "with no block" do
it "creates a link with given text and target to open related modal" do
link = Nokogiri::HTML(helper.link_to_modal('myText', '#target')).css('a')[0]
expect(link.text).to eq('myText')
expect(link.attributes['href'].value).to eq('#target')
expect(link.attributes['data-toggle'].value).to eq('modal')
expect(link.attributes['role'].value).to eq('button')
end
it "creates a link with given text, target, and attributes to open related modal" do
link = Nokogiri::HTML(helper.link_to_modal('myText', '#target', id: 'myLink')).css('a')[0]
expect(link.attributes['id'].value).to eq('myLink')
end
end
end
describe "modal(id, label_id, label:, &block)" do
let(:content) { ->{ content_tag(:div, nil, id: 'myBlockId') } }
let(:modal) { Nokogiri::HTML(helper.modal('myId', label: 'myLabelText', &content)).css('div')[0] }
let(:modal_header) { modal.css('div')[0] }
let(:close_button) { modal_header.css('button')[0] }
let(:label) { modal_header.css('h3')[0] }
let(:modal_body) { modal.css('div')[1] }
it "render given content to show it after clicking a specified link" do
expect(modal.attributes['id'].value).to eq('myId')
expect(modal.attributes['aria-labelledby'].value).to eq('myIdLabel')
expect(modal.attributes['aria-hidden'].value).to be_true
expect(modal.attributes['role'].value).to eq('dialog')
expect(modal.attributes['tabindex'].value).to eq('-1')
expect(close_button.attributes['type'].value).to eq('button')
expect(close_button.attributes['aria-hidden'].value).to be_true
expect(close_button.attributes['data-dismiss'].value).to eq('modal')
expect(close_button.attributes['class'].value).to include('close')
expect(label.attributes['id'].value).to eq('myIdLabel')
expect(label.text).to eq('myLabelText')
expect(modal_body).to have_selector 'div#myBlockId'
end
it "raises error when no block is given" do
expect { helper.modal('myId', label: 'myLabelText') }.to raise_error ArgumentError
end
end
= link_to_modal 'Text', '#<id>'
= modal '<id>', label: 'Your label' do
-# any content to display
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment