effective_bootstrap 0.0.1 → 0.0.2
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/app/assets/javascripts/effective_bootstrap.js +2 -0
- data/app/assets/javascripts/effective_bootstrap/base.js.coffee +2 -0
- data/app/assets/javascripts/effective_file/initialize.js.coffee +17 -0
- data/app/assets/javascripts/effective_file/input.js +1 -0
- data/app/assets/stylesheets/effective_bootstrap.scss +2 -1
- data/app/assets/stylesheets/effective_bootstrap/base.scss +2 -10
- data/app/assets/stylesheets/effective_bootstrap/forms.scss +33 -0
- data/app/assets/stylesheets/effective_file/input.scss +40 -0
- data/app/assets/stylesheets/effective_radio/input.scss +4 -0
- data/app/assets/stylesheets/effective_select/overrides.scss +15 -1
- data/app/helpers/effective_form_builder_helper.rb +10 -1
- data/app/helpers/effective_icons_helper.rb +1 -1
- data/app/models/effective/form_builder.rb +8 -0
- data/app/models/effective/form_input.rb +9 -6
- data/app/models/effective/form_inputs/check_box.rb +4 -8
- data/app/models/effective/form_inputs/checks.rb +2 -1
- data/app/models/effective/form_inputs/collection_input.rb +6 -6
- data/app/models/effective/form_inputs/file_field.rb +62 -0
- data/app/models/effective/form_inputs/price_field.rb +2 -2
- data/app/models/effective/form_inputs/radios.rb +61 -10
- data/app/models/effective/form_inputs/save.rb +15 -0
- data/app/views/effective/style_guide/__fields.html.haml +8 -7
- data/lib/effective_bootstrap/version.rb +1 -1
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45cba1fb03f24d07e64c2d042661ff15fbd05b12
|
4
|
+
data.tar.gz: ce40e7151a4b92853b547d2e799dd4cc9f95a365
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06a31a9005d368b42d51185e8bf6fa66f5807fdeacfe7264eef6369dd9fb33111600d228f1f3ee0ee19c881936538572a6a8405b20e8f6aa1e785093da771f7c
|
7
|
+
data.tar.gz: e1571762f4706f6618c70e1e53a2c55b49da87d3b09092e86a96e1320d7e49876436b23e20bfd188c98b8af4172154d25f079db86e5a8f06020607a9e4dcf622
|
@@ -25,6 +25,7 @@ this.EffectiveBootstrap ||= new class
|
|
25
25
|
|
26
26
|
if valid
|
27
27
|
$form.addClass('form-is-valid').removeClass('form-is-invalid')
|
28
|
+
setTimeout((-> $('button[type=submit],input[type=submit]').prop('disabled', true)), 0)
|
28
29
|
else
|
29
30
|
$form.addClass('was-validated').addClass('form-is-invalid').removeClass('form-is-valid')
|
30
31
|
|
@@ -35,3 +36,4 @@ $(document).on 'turbolinks:load', -> EffectiveBootstrap.initialize()
|
|
35
36
|
$(document).on 'cocoon:after-insert', -> EffectiveBootstrap.initialize()
|
36
37
|
$(document).on 'effective-bootstrap:initialize', (event) -> EffectiveBootstrap.initialize(event.currentTarget)
|
37
38
|
|
39
|
+
$(document).on 'ajax:beforeSend', 'form[data-remote]', -> this.checkValidity()
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$(document).on 'direct-upload:initialize', (event) ->
|
2
|
+
$target = $(event.target)
|
3
|
+
template = $target.data('progress-template').replace('$ID$', event.detail.id).replace('$FILENAME$', event.detail.file.name)
|
4
|
+
$target.siblings('.uploads').append(template)
|
5
|
+
|
6
|
+
$(document).on 'direct-upload:start', (event) ->
|
7
|
+
$("[data-direct-upload-id=#{event.detail.id}]").removeClass('direct-upload--pending')
|
8
|
+
|
9
|
+
$(document).on 'direct-upload:progress', (event) ->
|
10
|
+
$("[data-direct-upload-id=#{event.detail.id}]").children('.direct-upload__progress').css('width', "#{event.detail.progress}%")
|
11
|
+
|
12
|
+
$(document).on 'direct-upload:error', (event) ->
|
13
|
+
$("[data-direct-upload-id=#{event.detail.id}]").addClass('direct-upload--error').attr('title', event.detail.error)
|
14
|
+
|
15
|
+
$(document).on 'direct-upload:end', (event) ->
|
16
|
+
$("[data-direct-upload-id=#{event.detail.id}]").addClass('direct-upload--complete')
|
17
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require ./initialize
|
@@ -1,8 +1,9 @@
|
|
1
1
|
@import 'effective_bootstrap/base';
|
2
|
-
@import 'effective_bootstrap/icons';
|
3
2
|
|
4
3
|
@import 'effective_datetime/input';
|
5
4
|
@import 'effective_date/input';
|
6
5
|
@import 'effective_time/input';
|
7
6
|
|
7
|
+
@import 'effective_file/input';
|
8
8
|
@import 'effective_select/input';
|
9
|
+
@import 'effective_radio/input';
|
@@ -1,11 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
}
|
1
|
+
@import './forms';
|
2
|
+
@import './icons';
|
4
3
|
|
5
|
-
.was-validated.form-is-invalid .form-actions {
|
6
|
-
.invalid-feedback { display: block; }
|
7
|
-
}
|
8
|
-
|
9
|
-
fieldset.form-group > label {
|
10
|
-
display: block;
|
11
|
-
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
// Submit buttons
|
2
|
+
.form-actions {
|
3
|
+
border-top: solid 1px #eee;
|
4
|
+
margin-top: 1rem;
|
5
|
+
|
6
|
+
display: flex;
|
7
|
+
align-items: center;
|
8
|
+
justify-content: flex-end;
|
9
|
+
|
10
|
+
> * { margin-top: 1rem; }
|
11
|
+
}
|
12
|
+
|
13
|
+
// Spinner
|
14
|
+
.form-actions .eb-icon-spinner { display: none; }
|
15
|
+
.form-is-valid .form-actions .eb-icon-spinner { display: inline; }
|
16
|
+
|
17
|
+
// Custom submit button feedback
|
18
|
+
.was-validated.form-is-valid .form-actions {
|
19
|
+
.valid-feedback { display: block; }
|
20
|
+
}
|
21
|
+
|
22
|
+
.was-validated.form-is-invalid .form-actions {
|
23
|
+
.invalid-feedback { display: block; }
|
24
|
+
}
|
25
|
+
|
26
|
+
// Radio and Checkbox fieldsets
|
27
|
+
fieldset.form-group > label {
|
28
|
+
display: block;
|
29
|
+
}
|
30
|
+
|
31
|
+
div.form-group > label + .btn-group {
|
32
|
+
display: block;
|
33
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
.direct-uploads {
|
2
|
+
}
|
3
|
+
|
4
|
+
.direct-upload {
|
5
|
+
display: inline-block;
|
6
|
+
position: relative;
|
7
|
+
padding: 2px 4px;
|
8
|
+
margin: 0 3px 3px 0;
|
9
|
+
border: 1px solid rgba(0, 0, 0, 0.3);
|
10
|
+
border-radius: 3px;
|
11
|
+
font-size: 11px;
|
12
|
+
line-height: 13px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.direct-upload--pending {
|
16
|
+
opacity: 0.6;
|
17
|
+
}
|
18
|
+
|
19
|
+
.direct-upload__progress {
|
20
|
+
position: absolute;
|
21
|
+
top: 0;
|
22
|
+
left: 0;
|
23
|
+
bottom: 0;
|
24
|
+
opacity: 0.2;
|
25
|
+
background: #0076ff;
|
26
|
+
transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
|
27
|
+
transform: translate3d(0, 0, 0);
|
28
|
+
}
|
29
|
+
|
30
|
+
.direct-upload--complete .direct-upload__progress {
|
31
|
+
opacity: 0.4;
|
32
|
+
}
|
33
|
+
|
34
|
+
.direct-upload--error {
|
35
|
+
border-color: red;
|
36
|
+
}
|
37
|
+
|
38
|
+
input[type=file][data-direct-upload-url][disabled] {
|
39
|
+
display: none;
|
40
|
+
}
|
@@ -1,7 +1,21 @@
|
|
1
1
|
// These are overrides from the bootstrap-theme
|
2
2
|
|
3
|
+
.select2-container--bootstrap .select2-selection--single {
|
4
|
+
line-height: 1.5;
|
5
|
+
height: 38px;
|
6
|
+
}
|
7
|
+
|
8
|
+
.select2-container--bootstrap .select2-selection--multiple {
|
9
|
+
line-height: 1.5;
|
10
|
+
min-height: 38px;
|
11
|
+
}
|
12
|
+
|
13
|
+
.select2-container--bootstrap .select2-selection {
|
14
|
+
font-size: 1rem;
|
15
|
+
}
|
16
|
+
|
3
17
|
.select2-container .select2-selection--single .select2-selection__rendered {
|
4
|
-
margin: 0 0 0
|
18
|
+
margin: 0 0 0 0.5rem;
|
5
19
|
}
|
6
20
|
|
7
21
|
.select2-container--bootstrap .select2-selection--single .select2-selection__clear {
|
@@ -1,9 +1,18 @@
|
|
1
1
|
module EffectiveFormBuilderHelper
|
2
2
|
def effective_form_with(**options, &block)
|
3
3
|
options[:class] = [options[:class], 'needs-validation', ('form-inline' if options[:layout] == :inline)].compact.join(' ')
|
4
|
+
options[:html] = (options[:html] || {}).merge(novalidate: true, onsubmit: 'return EffectiveBootstrap.validate(this);')
|
5
|
+
|
6
|
+
if options.delete(:remote) == true
|
7
|
+
if options[:html][:data].kind_of?(Hash)
|
8
|
+
options[:html][:data][:remote] = true
|
9
|
+
else
|
10
|
+
options[:html]['data-remote'] = true
|
11
|
+
end
|
12
|
+
end
|
4
13
|
|
5
14
|
without_error_proc do
|
6
|
-
form_with(**options.merge(builder: Effective::FormBuilder
|
15
|
+
form_with(**options.merge(builder: Effective::FormBuilder), &block)
|
7
16
|
end
|
8
17
|
end
|
9
18
|
|
@@ -39,6 +39,10 @@ module Effective
|
|
39
39
|
end
|
40
40
|
alias_method :errors, :error
|
41
41
|
|
42
|
+
def file_field(name, options = {})
|
43
|
+
Effective::FormInputs::FileField.new(name, options, builder: self).to_html { super(name, options) }
|
44
|
+
end
|
45
|
+
|
42
46
|
def form_group(name = nil, options = {}, &block)
|
43
47
|
Effective::FormInputs::FormGroup.new(name, options, builder: self).to_html(&block)
|
44
48
|
end
|
@@ -61,6 +65,10 @@ module Effective
|
|
61
65
|
Effective::FormInputs::PriceField.new(name, options, builder: self).to_html { super(name, options) }
|
62
66
|
end
|
63
67
|
|
68
|
+
def save(name = 'Save', options = {})
|
69
|
+
Effective::FormInputs::Save.new(name, options, builder: self).to_html { super(name, options) }
|
70
|
+
end
|
71
|
+
|
64
72
|
def select(name, choices = nil, *args)
|
65
73
|
options = args.extract_options!.merge!(collection: choices)
|
66
74
|
Effective::FormInputs::Select.new(name, options, builder: self).to_html
|
@@ -197,6 +197,14 @@ module Effective
|
|
197
197
|
object.public_send(name) if object.respond_to?(name)
|
198
198
|
end
|
199
199
|
|
200
|
+
def unique_id(item = nil)
|
201
|
+
if item && item.respond_to?(value_method)
|
202
|
+
item_value = (item.send(value_method).to_s.parameterize.presence rescue nil)
|
203
|
+
end
|
204
|
+
|
205
|
+
[tag_id, item_value, object_id].compact.join('_')
|
206
|
+
end
|
207
|
+
|
200
208
|
private
|
201
209
|
|
202
210
|
# Here we split them into { wrapper: {}, label: {}, hint: {}, input: {} }
|
@@ -228,11 +236,7 @@ module Effective
|
|
228
236
|
label = merge_defaults!(label, label_options)
|
229
237
|
hint = merge_defaults!(hint, hint_options)
|
230
238
|
|
231
|
-
|
232
|
-
input.merge!(input_html.except(:class))
|
233
|
-
merge_defaults!(input, input_html_options.except(:class))
|
234
|
-
input[:class] = [input[:class], input_html[:class], input_html_options[:class]].compact.join(' ')
|
235
|
-
|
239
|
+
merge_defaults!(input.merge!(input_html), input_html_options)
|
236
240
|
merge_defaults!(input_js, input_js_options)
|
237
241
|
|
238
242
|
if input_js.present?
|
@@ -291,7 +295,6 @@ module Effective
|
|
291
295
|
end
|
292
296
|
|
293
297
|
# https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/tags/base.rb#L120
|
294
|
-
# Not 100% sure best way to generate this
|
295
298
|
def tag_id(index = nil)
|
296
299
|
case
|
297
300
|
when @builder.object_name.empty?
|
@@ -6,9 +6,7 @@ module Effective
|
|
6
6
|
case layout
|
7
7
|
when :horizontal
|
8
8
|
build_wrapper do
|
9
|
-
content_tag(:div, '', class: 'col-sm-2') + content_tag(:div, class: 'col-sm-10')
|
10
|
-
build_content(&block)
|
11
|
-
end
|
9
|
+
content_tag(:div, '', class: 'col-sm-2') + content_tag(:div, build_content(&block), class: 'col-sm-10')
|
12
10
|
end
|
13
11
|
else
|
14
12
|
build_content(&block)
|
@@ -16,9 +14,7 @@ module Effective
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def build_content(&block)
|
19
|
-
build_check_box_wrap {
|
20
|
-
build_input(&block) + build_label + build_feedback + build_hint
|
21
|
-
}
|
17
|
+
build_check_box_wrap { build_input(&block) + build_label + build_feedback + build_hint }
|
22
18
|
end
|
23
19
|
|
24
20
|
def build_check_box_wrap(&block)
|
@@ -39,9 +35,9 @@ module Effective
|
|
39
35
|
|
40
36
|
def input_html_options
|
41
37
|
if custom?
|
42
|
-
{ class: 'custom-control-input' }
|
38
|
+
{ class: 'custom-control-input', id: unique_id }
|
43
39
|
else
|
44
|
-
{ class: 'form-check-input' }
|
40
|
+
{ class: 'form-check-input', id: unique_id }
|
45
41
|
end
|
46
42
|
end
|
47
43
|
|
@@ -45,7 +45,8 @@ module Effective
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def build_item(builder)
|
48
|
-
|
48
|
+
item_id = unique_id(builder.object)
|
49
|
+
build_item_wrap { builder.check_box(id: item_id) + builder.label(item_label_options.merge(for: item_id)) }
|
49
50
|
end
|
50
51
|
|
51
52
|
def build_item_wrap(&block)
|
@@ -17,16 +17,16 @@ module Effective
|
|
17
17
|
@grouped = (options.delete(:grouped) || false)
|
18
18
|
end
|
19
19
|
|
20
|
-
def inline? # default false
|
21
|
-
return @inline unless @inline.nil?
|
22
|
-
@inline = (options[:input].delete(:inline) == true)
|
23
|
-
end
|
24
|
-
|
25
20
|
def custom? # default true
|
26
21
|
return @custom unless @custom.nil?
|
27
22
|
@custom = (options.delete(:custom) != false)
|
28
23
|
end
|
29
24
|
|
25
|
+
def inline? # default false
|
26
|
+
return @inline unless @inline.nil?
|
27
|
+
@inline = (options[:input].delete(:inline) == true)
|
28
|
+
end
|
29
|
+
|
30
30
|
def collection_options
|
31
31
|
return @collection_options unless @collection_options.nil?
|
32
32
|
|
@@ -127,7 +127,7 @@ module Effective
|
|
127
127
|
name.to_s.sub('_id', '') + '_id'
|
128
128
|
end
|
129
129
|
|
130
|
-
def polymorphic_value
|
130
|
+
def polymorphic_value
|
131
131
|
"#{object.class.model_name}_#{object.id}" if object
|
132
132
|
end
|
133
133
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Effective
|
2
|
+
module FormInputs
|
3
|
+
class FileField < Effective::FormInput
|
4
|
+
|
5
|
+
def build_input(&block)
|
6
|
+
build_attachments + build_uploads + super
|
7
|
+
end
|
8
|
+
|
9
|
+
def input_html_options
|
10
|
+
{ class: 'form-control-file', multiple: multiple?, direct_upload: true, 'data-progress-template': progress_template }
|
11
|
+
end
|
12
|
+
|
13
|
+
def multiple?
|
14
|
+
name.to_s.pluralize == name.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_attachments
|
18
|
+
return ''.html_safe unless object.respond_to?(name) && object.send(name).respond_to?(:attached?) && object.send(name).attached?
|
19
|
+
|
20
|
+
attachments = object.send(name).respond_to?(:length) ? object.send(name) : [object.send(name)]
|
21
|
+
|
22
|
+
content_tag(:div, attachments.map { |attachment| build_attachment(attachment) }.join.html_safe, class: 'attachments row')
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_attachment(attachment)
|
26
|
+
url = @template.url_for(attachment)
|
27
|
+
|
28
|
+
content_tag(:div, class: 'col-3') do
|
29
|
+
content_tag(:div, class: 'card mb-3') do
|
30
|
+
if attachment.image?
|
31
|
+
content_tag(:img, '', class: 'card-img-top', src: url, alt: attachment.filename.to_s) +
|
32
|
+
content_tag(:div, class: 'card-body') do
|
33
|
+
link_to(attachment.filename, url, class: 'card-link')
|
34
|
+
end
|
35
|
+
else
|
36
|
+
content_tag(:div, class: 'card-body') do
|
37
|
+
content_tag(:p, link_to(attachment.filename, url, class: 'card-link'), class: 'card-text') +
|
38
|
+
content_tag(:p, class: 'card-text') do
|
39
|
+
(attachment.content_type + '<br>' + @template.number_to_human_size(attachment.byte_size)).html_safe
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end.html_safe
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_uploads
|
50
|
+
content_tag(:div, '', class: 'uploads')
|
51
|
+
end
|
52
|
+
|
53
|
+
def progress_template
|
54
|
+
content_tag(:div, class: 'direct-upload direct-upload--pending', 'data-direct-upload-id': '$ID$') do
|
55
|
+
content_tag(:div, '', class: 'direct-upload__progress', style: 'width: 0%') +
|
56
|
+
content_tag(:span, '$FILENAME$', class: 'direct-upload__filename')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -19,12 +19,12 @@ module Effective
|
|
19
19
|
|
20
20
|
def price
|
21
21
|
return (include_blank? ? 0 : nil) unless value
|
22
|
-
value.kind_of?(Integer) ? value : ('%.2f' % (
|
22
|
+
value.kind_of?(Integer) ? value : ('%.2f' % (value / 100.0))
|
23
23
|
end
|
24
24
|
|
25
25
|
def currency
|
26
26
|
return (include_blank? ? 0.00 : nil) unless value
|
27
|
-
value.kind_of?(Integer) ? ('%.2f' % (
|
27
|
+
value.kind_of?(Integer) ? ('%.2f' % (value / 100.0)) : value
|
28
28
|
end
|
29
29
|
|
30
30
|
def include_blank? # default false
|
@@ -3,15 +3,27 @@ module Effective
|
|
3
3
|
module FormInputs
|
4
4
|
class Radios < CollectionInput
|
5
5
|
|
6
|
+
def build_wrapper(&block)
|
7
|
+
tag = buttons? ? :div : :fieldset
|
8
|
+
|
9
|
+
if layout == :horizontal
|
10
|
+
content_tag(tag, content_tag(:div, yield, class: 'row'), options[:wrapper])
|
11
|
+
else
|
12
|
+
content_tag(tag, yield, options[:wrapper])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
6
16
|
def build_input(&block)
|
7
|
-
|
17
|
+
build_button_group do
|
18
|
+
@builder.collection_radio_buttons(name, options_collection, value_method, label_method, collection_options, item_input_options) { |builder| build_item(builder) }
|
19
|
+
end
|
8
20
|
end
|
9
21
|
|
10
|
-
def
|
11
|
-
if
|
12
|
-
content_tag(:
|
22
|
+
def build_button_group(&block)
|
23
|
+
if buttons?
|
24
|
+
content_tag(:div, yield, id: button_group_id, class: 'btn-group btn-group-toggle', 'data-toggle': 'buttons')
|
13
25
|
else
|
14
|
-
|
26
|
+
yield
|
15
27
|
end
|
16
28
|
end
|
17
29
|
|
@@ -29,7 +41,9 @@ module Effective
|
|
29
41
|
end
|
30
42
|
|
31
43
|
def input_html_options
|
32
|
-
if
|
44
|
+
if buttons?
|
45
|
+
{ autocomplete: 'off' }
|
46
|
+
elsif custom?
|
33
47
|
{ class: 'custom-control-input' }
|
34
48
|
else
|
35
49
|
{ class: 'form-check-input' }
|
@@ -40,13 +54,29 @@ module Effective
|
|
40
54
|
return BLANK if options[:label] == false
|
41
55
|
return BLANK if name.kind_of?(NilClass)
|
42
56
|
|
57
|
+
tag = (buttons? || inline?) ? :label : :legend
|
43
58
|
text = (options[:label].delete(:text) || (object.class.human_attribute_name(name) if object) || BLANK).html_safe
|
44
59
|
|
45
|
-
|
60
|
+
if buttons?
|
61
|
+
content_tag(:label, text, options[:label].merge(for: button_group_id))
|
62
|
+
elsif inline?
|
63
|
+
content_tag(:label, text, options[:label])
|
64
|
+
else
|
65
|
+
content_tag(:legend, text, options[:label])
|
66
|
+
end
|
46
67
|
end
|
47
68
|
|
48
69
|
def build_item(builder)
|
49
|
-
|
70
|
+
item_id = unique_id(builder.object)
|
71
|
+
|
72
|
+
if buttons?
|
73
|
+
opts = item_label_options.merge(for: item_id)
|
74
|
+
opts[:class] = [opts[:class], ('active' if active_item?(builder)), ('first-button' if first_item?) ].compact.join(' ')
|
75
|
+
|
76
|
+
builder.label(opts) { builder.radio_button(id: item_id) + builder.text }
|
77
|
+
else
|
78
|
+
build_item_wrap { builder.radio_button(id: item_id) + builder.label(item_label_options.merge(for: item_id)) }
|
79
|
+
end
|
50
80
|
end
|
51
81
|
|
52
82
|
def build_item_wrap(&block)
|
@@ -58,17 +88,38 @@ module Effective
|
|
58
88
|
end
|
59
89
|
|
60
90
|
def item_input_options
|
61
|
-
options[:input].except(:inline, :custom)
|
91
|
+
options[:input].except(:inline, :custom, :buttons)
|
62
92
|
end
|
63
93
|
|
64
94
|
def item_label_options
|
65
|
-
if
|
95
|
+
if buttons?
|
96
|
+
{ class: 'btn btn-secondary' }
|
97
|
+
elsif custom?
|
66
98
|
{ class: 'custom-control-label' }
|
67
99
|
else
|
68
100
|
{ class: 'form-check-label' }
|
69
101
|
end
|
70
102
|
end
|
71
103
|
|
104
|
+
def buttons? # default false
|
105
|
+
return @buttons unless @buttons.nil?
|
106
|
+
@buttons = (options.delete(:buttons) || false)
|
107
|
+
end
|
108
|
+
|
109
|
+
def button_group_id
|
110
|
+
"#{tag_id}_btn_group"
|
111
|
+
end
|
112
|
+
|
113
|
+
def first_item?
|
114
|
+
return false unless @first_item.nil?
|
115
|
+
@first_item = true
|
116
|
+
end
|
117
|
+
|
118
|
+
def active_item?(builder)
|
119
|
+
value = self.value || collection_options[:checked]
|
120
|
+
value == builder.value || Array(value).map(&:to_s) == Array(builder.value).map(&:to_s)
|
121
|
+
end
|
122
|
+
|
72
123
|
end
|
73
124
|
end
|
74
125
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Effective
|
2
|
+
module FormInputs
|
3
|
+
class Save < Effective::FormInput
|
4
|
+
|
5
|
+
def to_html(&block)
|
6
|
+
content_tag(:button, name, options[:input])
|
7
|
+
end
|
8
|
+
|
9
|
+
def input_html_options
|
10
|
+
{ class: 'btn btn-primary', type: 'submit', name: 'commit', value: name }
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
= f.text_field :title, hint: 'This is a text_field'
|
2
2
|
= f.email_field :email, hint: 'This is an email_field'
|
3
|
-
= f.check_box :archived, hint: 'This is a check_box'
|
3
|
+
= f.check_box :archived, hint: 'This is a check_box'
|
4
4
|
|
5
5
|
= f.datetime_field :start_at, hint: 'This is a linked datetime_field'
|
6
6
|
= f.datetime_field :end_at, hint: 'This is a linked datetime_field'
|
7
7
|
= f.date_field :date, hint: 'This is a date_field'
|
8
8
|
= f.time_field :time, hint: 'This is a time_field'
|
9
9
|
|
10
|
-
= f.check_box :option1, inline: true
|
11
|
-
= f.check_box :option2, inline: true
|
12
|
-
= f.check_box :option3, inline: true
|
10
|
+
= f.check_box :option1, inline: true
|
11
|
+
= f.check_box :option2, inline: true
|
12
|
+
= f.check_box :option3, inline: true
|
13
13
|
|
14
14
|
= f.number_field :number, hint: 'This is a number_field'
|
15
15
|
= f.password_field :password, hint: 'This is a password_field'
|
@@ -35,8 +35,9 @@
|
|
35
35
|
= f.checks :drink, EffectiveStyleGuide.drinks, custom: false, hint: 'This is a checks with custom: false'
|
36
36
|
= f.checks :color, EffectiveStyleGuide.colors, inline: true, hint: 'This is a checks with inline: true'
|
37
37
|
|
38
|
-
= f.radios
|
39
|
-
= f.radios
|
40
|
-
= f.radios
|
38
|
+
= f.radios :food, EffectiveStyleGuide.foods, hint: 'This is a radios'
|
39
|
+
= f.radios :drink, EffectiveStyleGuide.drinks, custom: false, hint: 'This is a radios with custom: false'
|
40
|
+
= f.radios :color, EffectiveStyleGuide.colors, inline: true, hint: 'This is a radios with inline: true'
|
41
|
+
= f.radios :food, EffectiveStyleGuide.foods, buttons: true, hint: 'This is a radios with buttons: true'
|
41
42
|
|
42
43
|
= f.submit
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_bootstrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coffee-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Everything you need to get set up with bootstrap 4.
|
56
70
|
email:
|
57
71
|
- info@codeandeffect.com
|
@@ -335,6 +349,8 @@ files:
|
|
335
349
|
- app/assets/javascripts/effective_datetime/moment.js
|
336
350
|
- app/assets/javascripts/effective_datetime/overrides.js.coffee
|
337
351
|
- app/assets/javascripts/effective_datetime/turbolinks.js.coffee
|
352
|
+
- app/assets/javascripts/effective_file/initialize.js.coffee
|
353
|
+
- app/assets/javascripts/effective_file/input.js
|
338
354
|
- app/assets/javascripts/effective_phone/initialize.js.coffee
|
339
355
|
- app/assets/javascripts/effective_phone/input.js
|
340
356
|
- app/assets/javascripts/effective_phone/jquery.maskedInput.js
|
@@ -347,11 +363,14 @@ files:
|
|
347
363
|
- app/assets/javascripts/effective_time/input.js
|
348
364
|
- app/assets/stylesheets/effective_bootstrap.scss
|
349
365
|
- app/assets/stylesheets/effective_bootstrap/base.scss
|
366
|
+
- app/assets/stylesheets/effective_bootstrap/forms.scss
|
350
367
|
- app/assets/stylesheets/effective_bootstrap/icons.scss
|
351
368
|
- app/assets/stylesheets/effective_date/input.scss
|
352
369
|
- app/assets/stylesheets/effective_datetime/bootstrap-datetimepicker.scss
|
353
370
|
- app/assets/stylesheets/effective_datetime/input.scss
|
354
371
|
- app/assets/stylesheets/effective_datetime/overrides.scss
|
372
|
+
- app/assets/stylesheets/effective_file/input.scss
|
373
|
+
- app/assets/stylesheets/effective_radio/input.scss
|
355
374
|
- app/assets/stylesheets/effective_select/bootstrap-theme.css
|
356
375
|
- app/assets/stylesheets/effective_select/input.scss
|
357
376
|
- app/assets/stylesheets/effective_select/overrides.scss
|
@@ -370,12 +389,14 @@ files:
|
|
370
389
|
- app/models/effective/form_inputs/datetime_field.rb
|
371
390
|
- app/models/effective/form_inputs/email_field.rb
|
372
391
|
- app/models/effective/form_inputs/error_field.rb
|
392
|
+
- app/models/effective/form_inputs/file_field.rb
|
373
393
|
- app/models/effective/form_inputs/form_group.rb
|
374
394
|
- app/models/effective/form_inputs/number_field.rb
|
375
395
|
- app/models/effective/form_inputs/password_field.rb
|
376
396
|
- app/models/effective/form_inputs/phone_field.rb
|
377
397
|
- app/models/effective/form_inputs/price_field.rb
|
378
398
|
- app/models/effective/form_inputs/radios.rb
|
399
|
+
- app/models/effective/form_inputs/save.rb
|
379
400
|
- app/models/effective/form_inputs/select.rb
|
380
401
|
- app/models/effective/form_inputs/static_field.rb
|
381
402
|
- app/models/effective/form_inputs/submit.rb
|