simple_bootstrap_form 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/Guardfile +9 -0
- data/README.md +84 -1
- data/Rakefile +9 -0
- data/circle.yml +5 -0
- data/lib/simple_bootstrap_form/action_view_extensions.rb +5 -5
- data/lib/simple_bootstrap_form/css_class_list.rb +1 -1
- data/lib/simple_bootstrap_form/field_factory.rb +58 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/base_field.rb +118 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/boolean_field.rb +16 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/datetime_field.rb +55 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/email_field.rb +10 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/password_field.rb +10 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/text_field.rb +10 -0
- data/lib/simple_bootstrap_form/horizontal_form/fields/textarea_field.rb +14 -0
- data/lib/simple_bootstrap_form/horizontal_form/form_builder.rb +59 -0
- data/lib/simple_bootstrap_form/version.rb +1 -1
- data/lib/simple_bootstrap_form.rb +9 -8
- data/simple_bootstrap_form.gemspec +1 -1
- data/spec/field_factory_spec.rb +65 -0
- data/spec/simple_bootstrap_form_spec.rb +360 -83
- data/spec/spec_helper.rb +3 -0
- data/spec/support/have_element.rb +109 -0
- metadata +19 -13
- data/lib/simple_bootstrap_form/fields/base_field.rb +0 -103
- data/lib/simple_bootstrap_form/fields/boolean_field.rb +0 -14
- data/lib/simple_bootstrap_form/fields/datetime_field.rb +0 -53
- data/lib/simple_bootstrap_form/fields/email_field.rb +0 -8
- data/lib/simple_bootstrap_form/fields/password_field.rb +0 -8
- data/lib/simple_bootstrap_form/fields/text_field.rb +0 -8
- data/lib/simple_bootstrap_form/fields/textarea_field.rb +0 -12
- data/lib/simple_bootstrap_form/form_builder.rb +0 -51
- data/spec/support/input_matchers.rb +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49612ff415db9c67ef7d7fddec5ce1628a89bd56
|
4
|
+
data.tar.gz: f44b2d057f9fb6c315271314a119245dab29f9d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d98ef3d428ad7ced926485824bc37ba490d531d2d7adbae27ea7b3b7a065566155fa1aff84a68dc366e0129e8f203a13541f97c8a74030ad26ae9f4d47bf402
|
7
|
+
data.tar.gz: 70730348cf4eb5997e8de562623fc2cb76e44d48de10d412cbac84e77ec06ca38e7cc86be8785fa6dfffddbee28b8cdcb477e149d486f79a86951036c2469e42
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
CHANGED
@@ -2,3 +2,12 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in my_gem.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
# Gems required to run guard-rspec and send notifications to OS Notification
|
8
|
+
# System
|
9
|
+
gem 'guard-rspec', require: false
|
10
|
+
gem 'terminal-notifier-guard'
|
11
|
+
|
12
|
+
gem 'byebug'
|
13
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', all_on_start: false, all_after_pass: false , failed_mode: :keep do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
#watch(%r{^lib/(.+)\.rb$}) { |m| "spec#{m[1]}_spec.rb" }
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/simple_bootstrap_form_spec.rb" }
|
8
|
+
watch('spec/spec_helper.rb') { "spec" }
|
9
|
+
end
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Bootstrap 3 Form Builder
|
2
2
|
|
3
|
+

|
4
|
+
|
3
5
|
* I'm a fan of [Boootstrap](http://getbootstrap.com/)
|
4
6
|
* I'm a fan of [Simple Form](https://github.com/plataformatec/simple_form)
|
5
7
|
* Bootstrap 3 was released in August 2013, but as of February 2014 Simple Form
|
@@ -18,7 +20,7 @@ is going to require a new feature in the base Simple Form framework.
|
|
18
20
|
SimpleForm is a featurefull generic framework that will layout forms for
|
19
21
|
multiple different CSS frameworks (right now Bootstrap 2.3 and Zurb Foundation).
|
20
22
|
The challenge with this is that greater flexibility incurs greater complexity in
|
21
|
-
|
23
|
+
implementation. I believe the continued non-appearance of Simple Form Bootstrap
|
22
24
|
3 support reflects the difficulty people have in working in this more complex
|
23
25
|
framework, and getting the results integrated and released.
|
24
26
|
|
@@ -52,6 +54,87 @@ with
|
|
52
54
|
|
53
55
|
bootstrap_form_for ...
|
54
56
|
|
57
|
+
For example:
|
58
|
+
|
59
|
+
```haml
|
60
|
+
= bootstrap_form_for @article_form do |f|
|
61
|
+
= f.input :title
|
62
|
+
= f.input :published_at
|
63
|
+
= f.input :visible
|
64
|
+
= f.input :body, rows: 20
|
65
|
+
= f.input :topic_names, label: 'Tags'
|
66
|
+
```
|
67
|
+
|
68
|
+
Generates (spaces added for clarity):
|
69
|
+
|
70
|
+
```html
|
71
|
+
<form accept-charset="UTF-8" action="/articles" class="form-horizontal"
|
72
|
+
id="new_article" method="post" role="form">
|
73
|
+
<div style="display:none"><input name="utf8" type="hidden" value="✓"><input
|
74
|
+
name="authenticity_token" type="hidden"
|
75
|
+
value="NYiknMBfTGqphSHozhG8NMCGQeWbRY6hzs2a0+gaxJw="></div>
|
76
|
+
|
77
|
+
<div class="form-group article_title_group"><label
|
78
|
+
class="control-label col-sm-3" for="article_title"><abbr
|
79
|
+
title="required">*</abbr> Title</label>
|
80
|
+
|
81
|
+
<div class="col-sm-6"><input class="form-control" id="article_title"
|
82
|
+
name="article[title]" placeholder="Title"
|
83
|
+
required="required" type="text"></div>
|
84
|
+
</div>
|
85
|
+
|
86
|
+
<div class="form-group article_published_at_group"><label
|
87
|
+
class="control-label col-sm-3" for="article_published_at">Published
|
88
|
+
at</label>
|
89
|
+
<div class="col-sm-6">
|
90
|
+
<div class="input-group"><input class="form-control"
|
91
|
+
id="article_published_at"
|
92
|
+
name="article[published_at]"
|
93
|
+
placeholder="Published at"
|
94
|
+
type="datetime">
|
95
|
+
|
96
|
+
<div class="input-group-addon"><span
|
97
|
+
class="glyphicon glyphicon-calendar"
|
98
|
+
data-activate-datepicker="#article_published_at"></span></div>
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
</div>
|
102
|
+
|
103
|
+
<div class="form-group article_visible_group"><label
|
104
|
+
class="control-label col-sm-3" for="article_visible">Visible</label>
|
105
|
+
|
106
|
+
<div class="col-sm-6"><input name="article[visible]" type="hidden"
|
107
|
+
value="0"><input id="article_visible"
|
108
|
+
name="article[visible]"
|
109
|
+
type="checkbox" value="1">
|
110
|
+
</div>
|
111
|
+
</div>
|
112
|
+
|
113
|
+
<div class="form-group article_body_group"><label
|
114
|
+
class="control-label col-sm-3" for="article_body">Body</label>
|
115
|
+
|
116
|
+
<div class="col-sm-6"><textarea class="form-control" id="article_body"
|
117
|
+
name="article[body]" placeholder="Body"
|
118
|
+
rows="20"></textarea></div>
|
119
|
+
</div>
|
120
|
+
|
121
|
+
<div class="form-group article_topic_names_group"><label
|
122
|
+
class="control-label col-sm-3" for="article_topic_names">Tags</label>
|
123
|
+
|
124
|
+
<div class="col-sm-6"><input class="form-control" id="article_topic_names"
|
125
|
+
label="Tags" name="article[topic_names]"
|
126
|
+
placeholder="Topic names" type="text" value="">
|
127
|
+
</div>
|
128
|
+
</div>
|
129
|
+
|
130
|
+
<div class="form-group">
|
131
|
+
<div class="col-sm-offset-3 col-sm-2">
|
132
|
+
<input class="btn btn-primary" name="commit" type="submit" value="Save">
|
133
|
+
</div>
|
134
|
+
</div>
|
135
|
+
</form>
|
136
|
+
```
|
137
|
+
|
55
138
|
## Support
|
56
139
|
|
57
140
|
#### Bootstrap Support
|
data/Rakefile
CHANGED
data/circle.yml
ADDED
@@ -2,11 +2,7 @@ module SimpleBootstrapForm
|
|
2
2
|
module ActionViewExtensions
|
3
3
|
|
4
4
|
def bootstrap_form_for(record, options={}, &block)
|
5
|
-
options[:builder] ||=
|
6
|
-
options[:html] ||= {}
|
7
|
-
options[:html][:class] = CssClassList.new options[:html][:class]
|
8
|
-
options[:html][:class] << 'form-horizontal'
|
9
|
-
options[:html][:role] ||= 'form'
|
5
|
+
options[:builder] ||= form_builder_class options
|
10
6
|
prevent_action_view_putting_a_div_around_all_fields_with_errors do
|
11
7
|
form_for record, options, &block
|
12
8
|
end
|
@@ -14,6 +10,10 @@ module SimpleBootstrapForm
|
|
14
10
|
|
15
11
|
private
|
16
12
|
|
13
|
+
def form_builder_class(options)
|
14
|
+
SimpleBootstrapForm::HorizontalForm::FormBuilder
|
15
|
+
end
|
16
|
+
|
17
17
|
def prevent_action_view_putting_a_div_around_all_fields_with_errors(&block)
|
18
18
|
orig_field_error_proc = ::ActionView::Base.field_error_proc
|
19
19
|
begin
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SimpleBootstrapForm
|
2
|
+
class FieldFactory
|
3
|
+
|
4
|
+
def initialize(builder, template)
|
5
|
+
@builder = builder
|
6
|
+
@template = template
|
7
|
+
end
|
8
|
+
|
9
|
+
def for_attribute(attr, options)
|
10
|
+
field_class(attr, options).new(@builder, @template, attr, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def field_class(attr, options)
|
16
|
+
field_class_name(attr, options).constantize
|
17
|
+
end
|
18
|
+
|
19
|
+
def field_class_name(attr, options)
|
20
|
+
type_prefix = field_class_type_prefix attr, options
|
21
|
+
class_name = "#{type_prefix}Field"
|
22
|
+
@builder.class.fully_qualified_class_name_for_field class_name
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return first half of a field class name, based on the type of the
|
26
|
+
# field: 'Text', 'Email', 'Password', 'Textarea', 'Boolean', etc.
|
27
|
+
# Appending 'Field' to this gets you a real class, e.g. TextField
|
28
|
+
def field_class_type_prefix(attr, options)
|
29
|
+
if options[:as]
|
30
|
+
options[:as].to_s.capitalize
|
31
|
+
else
|
32
|
+
derive_field_class_prefix attr
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def derive_field_class_prefix(attr)
|
37
|
+
case attr_column_type(attr)
|
38
|
+
when :boolean; 'Boolean'
|
39
|
+
when :datetime; 'Datetime'
|
40
|
+
when :string; string_field_class_prefix_based_on_column_name(attr)
|
41
|
+
when :text ; 'Textarea'
|
42
|
+
else 'Text'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def attr_column_type(attr)
|
47
|
+
@builder.object.try(:column_for_attribute, attr).try(:type) || :string
|
48
|
+
end
|
49
|
+
|
50
|
+
def string_field_class_prefix_based_on_column_name(attr)
|
51
|
+
case
|
52
|
+
when attr.to_s =~ /email/i ; 'Email'
|
53
|
+
when attr.to_s =~ /password/i ; 'Password'
|
54
|
+
else 'Text'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module SimpleBootstrapForm
|
2
|
+
module HorizontalForm
|
3
|
+
module Fields
|
4
|
+
class BaseField
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :type
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(form_builder, template, name, options)
|
11
|
+
@form_builder = form_builder
|
12
|
+
@template = template
|
13
|
+
@name = name
|
14
|
+
process_options(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@template.content_tag :div, group_options do
|
19
|
+
field_label +
|
20
|
+
input_tag +
|
21
|
+
errors_block
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def process_options(options)
|
28
|
+
@options = options.dup
|
29
|
+
@label_size = @options.delete :label_size
|
30
|
+
@input_size = @options.delete :input_size
|
31
|
+
@label_text = @options.delete :label
|
32
|
+
@group_class = @options.delete :group_class
|
33
|
+
end
|
34
|
+
|
35
|
+
def group_options
|
36
|
+
css_classes = CssClassList.new 'form-group', group_class
|
37
|
+
css_classes << 'has-error' if has_error?
|
38
|
+
{ class: css_classes }
|
39
|
+
end
|
40
|
+
|
41
|
+
def group_class # a class for the form group to make it more testable
|
42
|
+
case @group_class
|
43
|
+
when false; nil
|
44
|
+
when nil; "#{@form_builder.object_name.to_s.underscore}_#{@name}_group"
|
45
|
+
else @group_class
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def field_label
|
50
|
+
@form_builder.label @name, @label_text, label_options
|
51
|
+
end
|
52
|
+
|
53
|
+
def label_text
|
54
|
+
text = @options[:label] || @name.to_s.humanize.capitalize
|
55
|
+
required_asterisk + text
|
56
|
+
end
|
57
|
+
|
58
|
+
def required_asterisk
|
59
|
+
if required?
|
60
|
+
@template.content_tag(:abbr, '*', title: 'required') + ' '
|
61
|
+
else
|
62
|
+
''
|
63
|
+
end.html_safe
|
64
|
+
end
|
65
|
+
|
66
|
+
def label_options
|
67
|
+
css_classes = CssClassList.new 'control-label'
|
68
|
+
css_classes << @label_size
|
69
|
+
{ class: css_classes.to_s }
|
70
|
+
end
|
71
|
+
|
72
|
+
def input_tag
|
73
|
+
@template.content_tag(:div, class: @input_size) do
|
74
|
+
@form_builder.text_field @name, input_options
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def input_options
|
79
|
+
@options.merge! class: 'form-control',
|
80
|
+
placeholder: placeholder,
|
81
|
+
type: self.class.type
|
82
|
+
@options.merge! required: 'required' if required?
|
83
|
+
@options
|
84
|
+
end
|
85
|
+
|
86
|
+
def placeholder
|
87
|
+
@options[:placeholder] || @name.to_s.humanize
|
88
|
+
end
|
89
|
+
|
90
|
+
def errors_block
|
91
|
+
return '' unless errors.any?
|
92
|
+
@template.content_tag :span, errors.join(', '),
|
93
|
+
class: 'help-block col-sm-3'
|
94
|
+
end
|
95
|
+
|
96
|
+
def model
|
97
|
+
@form_builder.object
|
98
|
+
end
|
99
|
+
|
100
|
+
def errors
|
101
|
+
return [] unless model
|
102
|
+
@cached_errors ||= model.errors[@name.to_sym]
|
103
|
+
end
|
104
|
+
|
105
|
+
def required?
|
106
|
+
return false unless model
|
107
|
+
model.class.validators_on(@name).any? do |validator|
|
108
|
+
validator.kind_of? ActiveModel::Validations::PresenceValidator
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def has_error?
|
113
|
+
errors.any?
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SimpleBootstrapForm
|
2
|
+
module HorizontalForm
|
3
|
+
module Fields
|
4
|
+
class BooleanField < BaseField
|
5
|
+
|
6
|
+
self.type = 'checkbox'
|
7
|
+
|
8
|
+
def input_tag
|
9
|
+
@template.content_tag(:div, class: 'col-sm-6') do
|
10
|
+
@form_builder.check_box @name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module SimpleBootstrapForm
|
2
|
+
module HorizontalForm
|
3
|
+
module Fields
|
4
|
+
class DatetimeField < BaseField
|
5
|
+
|
6
|
+
self.type = 'datetime'
|
7
|
+
|
8
|
+
def input_tag
|
9
|
+
@template.content_tag(:div, class: 'col-sm-6') do
|
10
|
+
@template.content_tag :div, class: 'input-group' do
|
11
|
+
@form_builder.text_field(@name, input_options) +
|
12
|
+
calendar_icon
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def calendar_icon
|
20
|
+
@template.content_tag(:div, class: 'input-group-addon') do
|
21
|
+
@template.content_tag(:span, '',
|
22
|
+
class: 'glyphicon glyphicon-calendar',
|
23
|
+
data: { 'activate-datepicker' => "##{tag_id}" }
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def input_options
|
29
|
+
super
|
30
|
+
@options.merge! value: value_suitable_for_use_by_jquery_datetimepicker
|
31
|
+
@options
|
32
|
+
end
|
33
|
+
|
34
|
+
def value_suitable_for_use_by_jquery_datetimepicker
|
35
|
+
@form_builder.object.send(@name).try(:strftime, '%Y/%m/%d %H:%M')
|
36
|
+
end
|
37
|
+
|
38
|
+
# Adapted from module ActionView::Helpers::Tags::Base
|
39
|
+
def tag_id
|
40
|
+
"#{sanitized_object_name}_#{sanitized_method_name}"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Adapted from module ActionView::Helpers::Tags::Base
|
44
|
+
def sanitized_object_name
|
45
|
+
@form_builder.object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
46
|
+
end
|
47
|
+
|
48
|
+
# Adapted from module ActionView::Helpers::Tags::Base
|
49
|
+
def sanitized_method_name
|
50
|
+
@name.to_s.sub(/\?$/,"")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SimpleBootstrapForm
|
2
|
+
module HorizontalForm
|
3
|
+
module Fields
|
4
|
+
class TextareaField < BaseField
|
5
|
+
|
6
|
+
def input_tag
|
7
|
+
@template.content_tag(:div, class: 'col-sm-6') do
|
8
|
+
@form_builder.text_area @name, input_options
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SimpleBootstrapForm
|
2
|
+
module HorizontalForm
|
3
|
+
class FormBuilder < ActionView::Helpers::FormBuilder
|
4
|
+
|
5
|
+
def initialize(object_name, object, template, options={}, block=nil)
|
6
|
+
@field_factory = FieldFactory.new self, template
|
7
|
+
process_options options
|
8
|
+
super object_name, object, template, options_for_rails_form_builder, block
|
9
|
+
end
|
10
|
+
|
11
|
+
def input(name, supplied_options = {})
|
12
|
+
options = field_options(supplied_options)
|
13
|
+
@field_factory.for_attribute(name, options).to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.fully_qualified_class_name_for_field(field_class_name)
|
17
|
+
# Better to do this manually than using introspection
|
18
|
+
"SimpleBootstrapForm::HorizontalForm::Fields::#{field_class_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def process_options(options)
|
24
|
+
@options = options.dup
|
25
|
+
@options.delete :layout
|
26
|
+
@group_class = @options.delete :group_class
|
27
|
+
end
|
28
|
+
|
29
|
+
def options_for_rails_form_builder
|
30
|
+
@options[:html] ||= {}
|
31
|
+
@options[:html][:role] ||= 'form'
|
32
|
+
@options[:html][:class] = form_css_classes
|
33
|
+
@options
|
34
|
+
end
|
35
|
+
|
36
|
+
def form_css_classes
|
37
|
+
css_classes = CssClassList.new options[:html][:class]
|
38
|
+
css_classes << 'form-horizontal'
|
39
|
+
css_classes
|
40
|
+
end
|
41
|
+
|
42
|
+
def field_options(supplied_options)
|
43
|
+
options = supplied_options.dup
|
44
|
+
options[:label_size] ||= field_label_size
|
45
|
+
options[:input_size] ||= field_input_size
|
46
|
+
options[:group_class] = @group_class if @group_class == false
|
47
|
+
options
|
48
|
+
end
|
49
|
+
|
50
|
+
def field_label_size
|
51
|
+
@options[:label_size] || 'col-sm-3'
|
52
|
+
end
|
53
|
+
|
54
|
+
def field_input_size
|
55
|
+
@options[:input_size] || 'col-sm-6'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'simple_bootstrap_form'
|
2
2
|
require 'simple_bootstrap_form/css_class_list'
|
3
3
|
require 'simple_bootstrap_form/action_view_extensions'
|
4
|
-
require 'simple_bootstrap_form/
|
5
|
-
require 'simple_bootstrap_form/
|
6
|
-
require 'simple_bootstrap_form/fields/
|
7
|
-
require 'simple_bootstrap_form/fields/
|
8
|
-
require 'simple_bootstrap_form/fields/
|
9
|
-
require 'simple_bootstrap_form/fields/
|
10
|
-
require 'simple_bootstrap_form/fields/
|
11
|
-
require 'simple_bootstrap_form/fields/
|
4
|
+
require 'simple_bootstrap_form/field_factory'
|
5
|
+
require 'simple_bootstrap_form/horizontal_form/form_builder'
|
6
|
+
require 'simple_bootstrap_form/horizontal_form/fields/base_field'
|
7
|
+
require 'simple_bootstrap_form/horizontal_form/fields/boolean_field'
|
8
|
+
require 'simple_bootstrap_form/horizontal_form/fields/datetime_field'
|
9
|
+
require 'simple_bootstrap_form/horizontal_form/fields/email_field'
|
10
|
+
require 'simple_bootstrap_form/horizontal_form/fields/password_field'
|
11
|
+
require 'simple_bootstrap_form/horizontal_form/fields/text_field'
|
12
|
+
require 'simple_bootstrap_form/horizontal_form/fields/textarea_field'
|
12
13
|
|
13
14
|
ActionView::Base.send :include, SimpleBootstrapForm::ActionViewExtensions
|
@@ -22,6 +22,6 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec-rails", ">= 3.0.0.beta1"
|
24
24
|
spec.add_development_dependency "sqlite3"
|
25
|
-
spec.add_development_dependency "
|
25
|
+
spec.add_development_dependency "nokogiri" # used by has_element matcher
|
26
26
|
spec.add_runtime_dependency "rails", ">= 4"
|
27
27
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleBootstrapForm::FieldFactory do
|
4
|
+
let(:model) { double 'model' }
|
5
|
+
let(:field_factory) { SimpleBootstrapForm::FieldFactory.new builder, nil }
|
6
|
+
|
7
|
+
describe "#for_attribute" do
|
8
|
+
let(:column) { double 'column' }
|
9
|
+
let(:attr_name) { 'foo' }
|
10
|
+
let(:options) { {} }
|
11
|
+
|
12
|
+
def setup_stubs
|
13
|
+
allow(builder).to receive(:object).and_return(model)
|
14
|
+
allow(model).to receive(:column_for_attribute).with(attr_name).and_return(column)
|
15
|
+
allow(column).to receive(:type).and_return(column_type)
|
16
|
+
end
|
17
|
+
|
18
|
+
subject { field_factory.for_attribute attr_name, options }
|
19
|
+
|
20
|
+
context "when given a horizontal form builder" do
|
21
|
+
let(:builder) { SimpleBootstrapForm::HorizontalForm::FormBuilder.new 'bogomodel', model, nil, {} }
|
22
|
+
|
23
|
+
context "for a text field" do
|
24
|
+
let(:column_type) { :string }
|
25
|
+
before { setup_stubs }
|
26
|
+
|
27
|
+
it { expect(subject).to be_a SimpleBootstrapForm::HorizontalForm::Fields::TextField }
|
28
|
+
|
29
|
+
context "when given an :as option" do
|
30
|
+
let(:options) { { as: :password } }
|
31
|
+
|
32
|
+
it "should override the default field type with the supplied one" do
|
33
|
+
expect(subject).to be_a SimpleBootstrapForm::HorizontalForm::Fields::PasswordField
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "whose name includes 'email'" do
|
38
|
+
let(:attr_name) { 'email' }
|
39
|
+
|
40
|
+
it { expect(subject).to be_a SimpleBootstrapForm::HorizontalForm::Fields::EmailField }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "whose name includes 'password'" do
|
44
|
+
let(:attr_name) { 'password' }
|
45
|
+
|
46
|
+
it { should be_a SimpleBootstrapForm::HorizontalForm::Fields::PasswordField }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "for a boolean field" do
|
51
|
+
let(:column_type) { :boolean }
|
52
|
+
before { setup_stubs }
|
53
|
+
|
54
|
+
it { expect(subject).to be_a SimpleBootstrapForm::HorizontalForm::Fields::BooleanField }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "for a datetime field" do
|
58
|
+
let(:column_type) { :datetime }
|
59
|
+
before { setup_stubs }
|
60
|
+
|
61
|
+
it { expect(subject).to be_a SimpleBootstrapForm::HorizontalForm::Fields::DatetimeField }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|