booter 0.3.1 → 1.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +5 -0
- data/README.md +68 -5
- data/Rakefile +8 -0
- data/app/assets/stylesheets/bootstrap-tweaks.css +1 -0
- data/app/assets/stylesheets/bootstrap.css.scss +3 -0
- data/app/form_builders/bootstrap_form_builder.rb +59 -7
- data/app/helpers/booter_helper.rb +6 -1
- data/app/views/booter/_modal_form.html.erb +19 -0
- data/booter.gemspec +6 -0
- data/config/locales/booter.en.yml +3 -0
- data/config/locales/booter.ru.yml +4 -0
- data/lib/booter/version.rb +1 -1
- data/spec/controllers/home_controller_spec.rb +127 -0
- data/spec/controllers/modal_controller_spec.rb +33 -0
- data/spec/dummy/.gitignore +3 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/home_controller.rb +24 -0
- data/spec/dummy/app/controllers/modal_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/user.rb +6 -0
- data/spec/dummy/app/views/home/buttons.html.haml +6 -0
- data/spec/dummy/app/views/home/default_fields.html.haml +8 -0
- data/spec/dummy/app/views/home/errors_for.html.haml +2 -0
- data/spec/dummy/app/views/home/field_with_hint.html.haml +2 -0
- data/spec/dummy/app/views/home/submit_button.html.haml +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/modal/simple.html.haml +5 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +57 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +6 -0
- data/spec/dummy/db/migrate/20120406045208_create_user.rb +7 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec_helper.rb +24 -0
- metadata +114 -11
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,20 +4,83 @@ One more twitter bootstrap wrapper for Rails.
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
In your Gemfile, add the following dependencies:
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
``` ruby
|
10
|
+
gem 'booter'
|
11
|
+
```
|
12
|
+
|
13
|
+
Run:
|
14
|
+
|
15
|
+
```
|
16
|
+
$ bundle install
|
17
|
+
```
|
18
|
+
|
19
|
+
Add `bootstrap` in your application.css:
|
20
|
+
|
21
|
+
``` css
|
22
|
+
/*
|
23
|
+
*= require bootstrap
|
24
|
+
* ...
|
25
|
+
*/
|
26
|
+
```
|
27
|
+
|
28
|
+
And optionally add 'bootstrap' in your application.js:
|
29
|
+
|
30
|
+
``` javascript
|
31
|
+
//= require jquery
|
32
|
+
//= require jquery_ujs
|
33
|
+
//= require bootstrap
|
34
|
+
//= ...
|
35
|
+
```
|
11
36
|
|
12
37
|
## Usage
|
13
38
|
|
14
39
|
Use <tt>nice_form_for</tt> helper method to draw nice bootstrap forms:
|
15
40
|
|
16
41
|
``` haml
|
17
|
-
|
42
|
+
-# Simple
|
43
|
+
= nice_form_for @user do |f|
|
18
44
|
= f.errors_for
|
19
45
|
= f.email_field :email
|
20
46
|
= f.password_field :password
|
47
|
+
= f.submit 'Sign in'
|
48
|
+
|
49
|
+
-# Complex
|
50
|
+
= nice_form_for @user do |f|
|
51
|
+
= f.errors_for
|
52
|
+
|
53
|
+
= f.email_field :email, class: 'input-medium'
|
54
|
+
= f.password_field :password
|
21
55
|
= f.check_box :remember_me
|
22
|
-
|
56
|
+
|
57
|
+
= f.actions do
|
58
|
+
= f.submit 'Sign in'
|
59
|
+
= f.button 'Cancel'
|
60
|
+
|
61
|
+
= f.button 'Danger button', style: :danger
|
62
|
+
= f.submit 'Submit without the primary class', style: :none
|
63
|
+
|
64
|
+
|
65
|
+
-# Modal
|
66
|
+
= nice_form_for @user, modal: true, id: 'auth' do |f|
|
67
|
+
= f.errors_for
|
68
|
+
= f.email_field :email
|
69
|
+
= f.password_field :password
|
70
|
+
= f.submit 'Sign in'
|
71
|
+
|
72
|
+
%p= link_to 'Open auth form', '#auth-modal', data: { toggle: 'modal' }
|
23
73
|
```
|
74
|
+
|
75
|
+
## Demo
|
76
|
+
|
77
|
+
See [live demo](http://growing-cloud-6915.heroku.com) or browse [source code](https://github.com/boshie/booter-demo)
|
78
|
+
|
79
|
+
## Contributors
|
80
|
+
|
81
|
+
* Alexey Vakhov - [https://github.com/avakhov](https://github.com/avakhov)
|
82
|
+
* Alexey Yurchenko - [https://github.com/alexesDev](https://github.com/alexesDev)
|
83
|
+
|
84
|
+
## Status
|
85
|
+
|
86
|
+
[<img src="https://secure.travis-ci.org/boshie/booter.png"/>](http://travis-ci.org/boshie/booter)
|
data/Rakefile
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
div.modal form {margin-bottom: 0}
|
@@ -1,5 +1,16 @@
|
|
1
1
|
class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
|
2
2
|
delegate :content_tag, :safe_join, to: :@template
|
3
|
+
attr_reader :form_actions_content # only for modal forms
|
4
|
+
|
5
|
+
def modal_title
|
6
|
+
if @options[:modal]
|
7
|
+
if @options[:modal].is_a?(Hash) and @options[:modal].key?(:title)
|
8
|
+
@options[:modal][:title]
|
9
|
+
else
|
10
|
+
I18n.t('booter.modal.title.' + @object.class.model_name, default: @object.class.model_name.human)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
3
14
|
|
4
15
|
def errors_for
|
5
16
|
return "" if @object.errors.empty?
|
@@ -21,17 +32,19 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
|
|
21
32
|
html.html_safe
|
22
33
|
end
|
23
34
|
|
24
|
-
%w[email_field password_field text_field text_area].each do |method_name|
|
35
|
+
%w[email_field file_field password_field text_field text_area].each do |method_name|
|
25
36
|
define_method method_name do |*args|
|
26
37
|
options = args.extract_options!
|
27
38
|
name = args.first
|
28
39
|
|
29
40
|
wrapper name, options.slice(:hint) do
|
30
41
|
options = options.except(:hint)
|
31
|
-
options[:class] = [options[:class], 'input-xxlarge'].compact
|
32
42
|
|
33
43
|
if method_name == 'text_area'
|
34
|
-
|
44
|
+
options[:rows] ||= 7
|
45
|
+
options[:cols] ||= 40
|
46
|
+
|
47
|
+
super(name, options)
|
35
48
|
else
|
36
49
|
super(name, options)
|
37
50
|
end
|
@@ -39,6 +52,16 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
|
|
39
52
|
end
|
40
53
|
end
|
41
54
|
|
55
|
+
def actions &block
|
56
|
+
begin
|
57
|
+
@actions_scope = true
|
58
|
+
content = @template.capture(&block)
|
59
|
+
ensure
|
60
|
+
@actions_scope = false
|
61
|
+
end
|
62
|
+
form_actions_wrapper content
|
63
|
+
end
|
64
|
+
|
42
65
|
def select(name, choices, options = {})
|
43
66
|
wrapper name do
|
44
67
|
super
|
@@ -53,10 +76,12 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
|
|
53
76
|
end
|
54
77
|
end
|
55
78
|
|
56
|
-
def submit
|
57
|
-
|
58
|
-
|
59
|
-
|
79
|
+
def submit value = nil, *args
|
80
|
+
form_actions_wrapper super(value, make_button_options(args, style: :primary))
|
81
|
+
end
|
82
|
+
|
83
|
+
def button value = nil, *args
|
84
|
+
form_actions_wrapper super(value, make_button_options(args))
|
60
85
|
end
|
61
86
|
|
62
87
|
def wrapper(name, options = {}, &block)
|
@@ -72,4 +97,31 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
|
|
72
97
|
]
|
73
98
|
end
|
74
99
|
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def form_actions_wrapper(content)
|
104
|
+
if @actions_scope
|
105
|
+
content
|
106
|
+
else
|
107
|
+
if @options[:modal]
|
108
|
+
@form_actions_content = content
|
109
|
+
''
|
110
|
+
else
|
111
|
+
content_tag :div, content, class: 'form-actions'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def make_button_options args, *default_args
|
117
|
+
options = default_args.extract_options!
|
118
|
+
options.merge! args.extract_options!
|
119
|
+
options[:class] ||= 'btn'
|
120
|
+
|
121
|
+
if options[:style] && options[:style].to_sym != :none
|
122
|
+
options[:class] += " btn-#{options[:style]}"
|
123
|
+
end
|
124
|
+
|
125
|
+
options.except(:style)
|
126
|
+
end
|
75
127
|
end
|
@@ -3,6 +3,11 @@ module BooterHelper
|
|
3
3
|
options[:builder] = BootstrapFormBuilder
|
4
4
|
options[:html] ||= {}
|
5
5
|
options[:html][:class] = 'form-horizontal'
|
6
|
-
|
6
|
+
|
7
|
+
if options[:modal]
|
8
|
+
render 'booter/modal_form', object: object, options: options, block: block
|
9
|
+
else
|
10
|
+
form_for(object, options, &block)
|
11
|
+
end
|
7
12
|
end
|
8
13
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="modal hide fade" id="<%= options[:id] || object.class.name.gsub('::', '').underscore %>-modal">
|
2
|
+
<%= form_for object, options do |f| %>
|
3
|
+
<div class="modal-header">
|
4
|
+
<a class="close" data-dismiss="modal">×</a>
|
5
|
+
<h3><%= f.modal_title %></h3>
|
6
|
+
</div>
|
7
|
+
<div class="modal-body">
|
8
|
+
<%= capture f, &block %>
|
9
|
+
</div>
|
10
|
+
<div class="modal-footer">
|
11
|
+
<div class="pull-left">
|
12
|
+
<a href="#" data-dismiss="modal" class="btn"><%= t('booter.modal.close') %></a>
|
13
|
+
</div>
|
14
|
+
<div class="pull-right">
|
15
|
+
<%= f.form_actions_content %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
19
|
+
</div>
|
data/booter.gemspec
CHANGED
@@ -16,4 +16,10 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = Booter::VERSION
|
17
17
|
|
18
18
|
gem.add_dependency 'rails', '~> 3.2'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'haml'
|
21
|
+
gem.add_development_dependency 'sqlite3'
|
22
|
+
gem.add_development_dependency 'rspec-rails'
|
23
|
+
gem.add_development_dependency 'factory_girl_rails'
|
24
|
+
gem.add_development_dependency 'database_cleaner'
|
19
25
|
end
|
data/lib/booter/version.rb
CHANGED
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HomeController do
|
4
|
+
render_views
|
5
|
+
|
6
|
+
it 'renders default field' do
|
7
|
+
get :default_fields
|
8
|
+
response.should be_success
|
9
|
+
|
10
|
+
assert_select "form[class=?]", /form-horizontal/ do
|
11
|
+
assert_select "div.control-group" do
|
12
|
+
assert_select 'label.control-label', 'Email'
|
13
|
+
assert_select 'div.controls' do
|
14
|
+
assert_select 'input[type=email]'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
assert_select "div.control-group" do
|
19
|
+
assert_select 'label.control-label', 'Avatar'
|
20
|
+
assert_select 'div.controls' do
|
21
|
+
assert_select 'input[type=file]'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
assert_select "div.control-group" do
|
26
|
+
assert_select 'label.control-label', 'Password'
|
27
|
+
assert_select 'div.controls' do
|
28
|
+
assert_select 'input[type=password]'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_select "div.control-group" do
|
33
|
+
assert_select 'label.control-label', 'Motto'
|
34
|
+
assert_select 'div.controls' do
|
35
|
+
assert_select 'input[type=text]'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
assert_select "div.control-group" do
|
40
|
+
assert_select 'label.control-label', 'About'
|
41
|
+
assert_select 'div.controls' do
|
42
|
+
assert_select 'textarea[rows=?][cols=?]', 7, 40
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_select "div.control-group" do
|
47
|
+
assert_select 'label.control-label', 'Role'
|
48
|
+
assert_select 'div.controls' do
|
49
|
+
assert_select 'select'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_select "div.control-group" do
|
54
|
+
assert_select 'label.control-label', 'Remember me'
|
55
|
+
assert_select 'div.controls' do
|
56
|
+
assert_select 'label.checkbox' do
|
57
|
+
assert_select 'input[type=hidden][value=?]', 0
|
58
|
+
assert_select 'input[type=checkbox][value=?]', 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'renders error message' do
|
66
|
+
get :errors_for
|
67
|
+
response.should be_success
|
68
|
+
|
69
|
+
assert_select "form[class=?]", /form-horizontal/ do
|
70
|
+
assert_select 'div.alert.alert-error' do
|
71
|
+
assert_select 'p' do
|
72
|
+
assert_select 'b', 'User: not saved because of 1 error'
|
73
|
+
end
|
74
|
+
assert_select 'ul' do
|
75
|
+
assert_select 'li', 'Email should be email'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'renders field with hint' do
|
82
|
+
get :field_with_hint
|
83
|
+
response.should be_success
|
84
|
+
|
85
|
+
assert_select "form" do
|
86
|
+
assert_select 'div.control-group' do
|
87
|
+
assert_select 'label.control-label', 'Email'
|
88
|
+
assert_select 'div.controls' do
|
89
|
+
assert_select 'input[type=email]'
|
90
|
+
assert_select 'p.help-block', 'Enter proper email address'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'renders different buttons' do
|
97
|
+
get :buttons
|
98
|
+
response.should be_success
|
99
|
+
|
100
|
+
assert_select "form" do
|
101
|
+
assert_select 'div.form-actions' do
|
102
|
+
assert_select 'input.btn.btn-primary[type=?][value=?]', 'submit', 'Sign in'
|
103
|
+
assert_select 'button.btn[type=?]', 'submit', 'Cancel'
|
104
|
+
assert_select 'button.btn.btn-danger[type=?]', 'submit', 'Danger button'
|
105
|
+
assert_select 'input.btn[type=?][value=?]', 'submit', 'Submit without the primary class'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'renders submit buttons wrapped in div.form-actions' do
|
111
|
+
get :submit_button
|
112
|
+
response.should be_success
|
113
|
+
|
114
|
+
assert_select "form" do
|
115
|
+
assert_select "div.control-group" do
|
116
|
+
assert_select 'label.control-label', 'Email'
|
117
|
+
assert_select 'div.controls' do
|
118
|
+
assert_select 'input[type=email]'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
assert_select 'div.form-actions' do
|
123
|
+
assert_select 'input.btn.btn-primary[type=?][value=?]', 'submit', 'Create User'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ModalController do
|
4
|
+
render_views
|
5
|
+
|
6
|
+
it 'renders' do
|
7
|
+
get :simple
|
8
|
+
response.should be_success
|
9
|
+
|
10
|
+
assert_select 'div.modal.hide.fade#auth-modal' do
|
11
|
+
assert_select 'form[class=?]', 'form-horizontal' do
|
12
|
+
assert_select '.modal-header' do
|
13
|
+
assert 'a.close[data-dismiss=?]', 'modal'
|
14
|
+
assert_select 'h3', 'User'
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_select '.modal-body' do
|
18
|
+
assert_select 'input[type=email]'
|
19
|
+
assert_select 'input[type=password]'
|
20
|
+
end
|
21
|
+
|
22
|
+
assert_select '.modal-footer' do
|
23
|
+
assert_select '.pull-left' do
|
24
|
+
assert_select 'a[href=#][data-dismiss=?][class=?]', 'modal', 'btn'
|
25
|
+
end
|
26
|
+
assert_select '.pull-right' do
|
27
|
+
assert_select 'input[type=submit][class=?][value=?]', 'btn btn-primary', 'Sign in'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|