eac_rails_utils 0.0.1
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 +7 -0
- data/Rakefile +18 -0
- data/lib/assets/javascripts/currency_field.js +21 -0
- data/lib/assets/javascripts/eac_rails_utils.js +6 -0
- data/lib/assets/javascripts/input_searchable.js +78 -0
- data/lib/assets/javascripts/jMenu.jquery.min.js +12 -0
- data/lib/assets/javascripts/jquery.maskMoney.js +409 -0
- data/lib/assets/stylesheets/autocomplete.scss +33 -0
- data/lib/assets/stylesheets/bootstrap3-dropdown.scss +47 -0
- data/lib/assets/stylesheets/eac_rails_utils.scss +44 -0
- data/lib/assets/stylesheets/jmenu.scss +78 -0
- data/lib/eac/common_form_helper.rb +37 -0
- data/lib/eac/common_form_helper/form_builder.rb +88 -0
- data/lib/eac/common_form_helper/form_builder/association_select_field.rb +40 -0
- data/lib/eac/common_form_helper/form_builder/common_text_fields.rb +18 -0
- data/lib/eac/common_form_helper/form_builder/currency_field.rb +39 -0
- data/lib/eac/common_form_helper/form_builder/date_field.rb +20 -0
- data/lib/eac/common_form_helper/form_builder/fields_for.rb +44 -0
- data/lib/eac/common_form_helper/form_builder/radio_select_field.rb +44 -0
- data/lib/eac/common_form_helper/form_builder/searchable_association_field.rb +77 -0
- data/lib/eac/cpf_validator.rb +60 -0
- data/lib/eac/formatter_helper.rb +27 -0
- data/lib/eac/htmlbeautifier.rb +25 -0
- data/lib/eac/menus_helper.rb +17 -0
- data/lib/eac/menus_helper/bootstrap_gui_builder.rb +90 -0
- data/lib/eac/menus_helper/data_builder.rb +57 -0
- data/lib/eac/menus_helper/gui_builder.rb +51 -0
- data/lib/eac/model.rb +87 -0
- data/lib/eac/simple_cache.rb +29 -0
- data/lib/eac/source_target_fixtures.rb +51 -0
- data/lib/eac_rails_utils.rb +29 -0
- data/lib/eac_rails_utils/patches/model_attribute_required.rb +31 -0
- data/lib/eac_rails_utils/rails/engine.rb +5 -0
- data/lib/eac_rails_utils/version.rb +3 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/models/job.rb +4 -0
- data/test/dummy/app/models/user.rb +7 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +12 -0
- data/test/dummy/config/boot.rb +4 -0
- data/test/dummy/config/database.yml +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/routes.rb +8 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/migrate/20160415125333_create_users.rb +9 -0
- data/test/dummy/db/migrate/20160415143123_create_jobs.rb +7 -0
- data/test/dummy/db/migrate/20160415143229_add_job_to_users.rb +5 -0
- data/test/dummy/db/schema.rb +25 -0
- data/test/lib/eac/common_form_helper_test.rb +31 -0
- data/test/lib/eac/cpf_validator_test.rb +33 -0
- data/test/lib/eac/formatter_helper_test.rb +19 -0
- data/test/lib/eac/model_test.rb +76 -0
- data/test/lib/eac/simple_cache_test.rb +56 -0
- data/test/lib/eac_rails_utils/patches/model_attribute_required_test.rb +39 -0
- data/test/test_helper.rb +11 -0
- metadata +189 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
$jquery-autocomplete-bg-color: #ffffff !default;
|
2
|
+
$jquery-autocomplete-bg-highlight-color: #ccc !default;
|
3
|
+
$jquery-autocomplete-border-color: #DDD !default;
|
4
|
+
|
5
|
+
.ui-autocomplete {
|
6
|
+
position: absolute;
|
7
|
+
z-index: 5000;
|
8
|
+
cursor: default;
|
9
|
+
padding: 0;
|
10
|
+
margin-top: 2px;
|
11
|
+
list-style: none;
|
12
|
+
background-color: $jquery-autocomplete-bg-color;
|
13
|
+
border: 1px solid $jquery-autocomplete-border-color;
|
14
|
+
-webkit-border-radius: 5px;
|
15
|
+
-moz-border-radius: 5px;
|
16
|
+
border-radius: 5px;
|
17
|
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
18
|
+
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
19
|
+
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
|
20
|
+
|
21
|
+
> li {
|
22
|
+
padding: 3px 20px;
|
23
|
+
background-color: $jquery-autocomplete-bg-color;
|
24
|
+
}
|
25
|
+
|
26
|
+
> li.ui-state-focus {
|
27
|
+
background-color: $jquery-autocomplete-bg-highlight-color;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
.ui-helper-hidden-accessible {
|
32
|
+
display: none;
|
33
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
.dropdown-submenu {
|
2
|
+
position: relative;
|
3
|
+
}
|
4
|
+
|
5
|
+
.dropdown-submenu>.dropdown-menu {
|
6
|
+
top: 0;
|
7
|
+
left: 100%;
|
8
|
+
margin-top: -6px;
|
9
|
+
margin-left: -1px;
|
10
|
+
-webkit-border-radius: 0 6px 6px 6px;
|
11
|
+
-moz-border-radius: 0 6px 6px;
|
12
|
+
border-radius: 0 6px 6px 6px;
|
13
|
+
}
|
14
|
+
|
15
|
+
.dropdown-submenu:hover>.dropdown-menu {
|
16
|
+
display: block;
|
17
|
+
}
|
18
|
+
|
19
|
+
.dropdown-submenu>a:after {
|
20
|
+
display: block;
|
21
|
+
content: " ";
|
22
|
+
float: right;
|
23
|
+
width: 0;
|
24
|
+
height: 0;
|
25
|
+
border-color: transparent;
|
26
|
+
border-style: solid;
|
27
|
+
border-width: 5px 0 5px 5px;
|
28
|
+
border-left-color: #ccc;
|
29
|
+
margin-top: 5px;
|
30
|
+
margin-right: -10px;
|
31
|
+
}
|
32
|
+
|
33
|
+
.dropdown-submenu:hover>a:after {
|
34
|
+
border-left-color: #fff;
|
35
|
+
}
|
36
|
+
|
37
|
+
.dropdown-submenu.pull-left {
|
38
|
+
float: none;
|
39
|
+
}
|
40
|
+
|
41
|
+
.dropdown-submenu.pull-left>.dropdown-menu {
|
42
|
+
left: -100%;
|
43
|
+
margin-left: 10px;
|
44
|
+
-webkit-border-radius: 6px 0 6px 6px;
|
45
|
+
-moz-border-radius: 6px 0 6px 6px;
|
46
|
+
border-radius: 6px 0 6px 6px;
|
47
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
@import "bootstrap-sprockets";
|
2
|
+
@import "bootstrap";
|
3
|
+
@import "jmenu";
|
4
|
+
@import "bootstrap3-dropdown";
|
5
|
+
@import 'autocomplete';
|
6
|
+
|
7
|
+
.form-control-complex {
|
8
|
+
display: block;
|
9
|
+
width: 100%;
|
10
|
+
|
11
|
+
select {
|
12
|
+
@extend .form-control;
|
13
|
+
display: inline;
|
14
|
+
width: auto;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
.nested_form {
|
19
|
+
margin-bottom: 1.0em;
|
20
|
+
padding-bottom: 1.0em;
|
21
|
+
border-bottom: 1px solid #e5e5e5;
|
22
|
+
}
|
23
|
+
|
24
|
+
.nested_form_row {
|
25
|
+
margin-left: 1.0em;
|
26
|
+
padding-bottom: 1.0em;
|
27
|
+
margin-bottom: 1.0em;
|
28
|
+
border-bottom: 1px solid #e5e5e5;
|
29
|
+
}
|
30
|
+
|
31
|
+
form.CommonFormHelper {
|
32
|
+
div.form-group {
|
33
|
+
label.required {
|
34
|
+
font-weight: bold;
|
35
|
+
}
|
36
|
+
|
37
|
+
label.optional {
|
38
|
+
font-weight: normal;
|
39
|
+
&:after {
|
40
|
+
content: ' (Opcional)'
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
$menu-entry-background-color: #322f32;
|
2
|
+
$menu-entry-hover-background-color: #3a3a3a;
|
3
|
+
$menu-entry-color: white;
|
4
|
+
$submenu-entry-border-color: #484548;
|
5
|
+
$submenu-entry-hover-background-color: #514c52;
|
6
|
+
|
7
|
+
.jMenu {
|
8
|
+
display: table;
|
9
|
+
margin: 0;
|
10
|
+
padding: 0;
|
11
|
+
list-style: none;
|
12
|
+
float: left;
|
13
|
+
|
14
|
+
/* First level */
|
15
|
+
li {
|
16
|
+
display: table-cell;
|
17
|
+
background-color: $menu-entry-background-color;
|
18
|
+
margin: 0;
|
19
|
+
list-style: none;
|
20
|
+
margin-right: 0.3em;
|
21
|
+
float: left;
|
22
|
+
|
23
|
+
a {
|
24
|
+
display: block;
|
25
|
+
background-color: transparent;
|
26
|
+
color: $menu-entry-color;
|
27
|
+
cursor: pointer;
|
28
|
+
|
29
|
+
&:hover {
|
30
|
+
background-color: $menu-entry-hover-background-color;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
&:hover>a {
|
35
|
+
background-color: $menu-entry-hover-background-color;
|
36
|
+
};
|
37
|
+
|
38
|
+
// Sub-menus
|
39
|
+
ul {
|
40
|
+
display: none;
|
41
|
+
position: absolute;
|
42
|
+
z-index: 9999;
|
43
|
+
padding: 0;
|
44
|
+
margin: 0;
|
45
|
+
list-style: none;
|
46
|
+
|
47
|
+
li {
|
48
|
+
background-color: $menu-entry-background-color;
|
49
|
+
display: block;
|
50
|
+
border-bottom: 1px solid $submenu-entry-border-color;
|
51
|
+
padding: 0;
|
52
|
+
list-style: none;
|
53
|
+
position: relative;
|
54
|
+
float: none;
|
55
|
+
margin: 0;
|
56
|
+
|
57
|
+
a {
|
58
|
+
font-size: 80%;
|
59
|
+
text-transform: none;
|
60
|
+
display: block;
|
61
|
+
padding: 7px;
|
62
|
+
border-top: 1px solid transparent;
|
63
|
+
border-bottom: 1px solid transparent;
|
64
|
+
|
65
|
+
&.isParent {
|
66
|
+
background-color: $menu-entry-hover-background-color;
|
67
|
+
}
|
68
|
+
|
69
|
+
&:hover {
|
70
|
+
background-color: $submenu-entry-hover-background-color;
|
71
|
+
border-top: 1px solid $menu-entry-background-color;
|
72
|
+
border-bottom: 1px solid $menu-entry-background-color;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Eac
|
2
|
+
module CommonFormHelper
|
3
|
+
def common_form(model_instance, options = {}, &block)
|
4
|
+
submit_label = options.delete(:submit_label)
|
5
|
+
options[:html] ||= {}
|
6
|
+
options[:html][:class] = 'CommonFormHelper'
|
7
|
+
form_for(model_instance, options) do |form|
|
8
|
+
fb = FormBuilder.new(form, self)
|
9
|
+
errors(model_instance) <<
|
10
|
+
capture(fb, &block) <<
|
11
|
+
errors_not_showed(model_instance, fb.field_errors_showed) <<
|
12
|
+
form.submit(submit_label, class: 'btn btn-primary')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def errors(model_instance)
|
19
|
+
if model_instance.errors.any?
|
20
|
+
content_tag(:div, class: 'alert alert-danger', id: 'flash_alert') do
|
21
|
+
'Há pendências no preenchimento do formulário.'
|
22
|
+
end
|
23
|
+
else
|
24
|
+
ActiveSupport::SafeBuffer.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def errors_not_showed(model_instance, field_errors_showed)
|
29
|
+
s = ActiveSupport::SafeBuffer.new
|
30
|
+
model_instance.errors.each do |k, v|
|
31
|
+
next if field_errors_showed.include?(k)
|
32
|
+
s << content_tag(:div, "#{k}: #{v}", class: 'error')
|
33
|
+
end
|
34
|
+
s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Eac
|
2
|
+
module CommonFormHelper
|
3
|
+
class FormBuilder
|
4
|
+
include AssociationSelectField
|
5
|
+
include CommonTextFields
|
6
|
+
include CurrencyField
|
7
|
+
include DateField
|
8
|
+
include RadioSelectField
|
9
|
+
include FieldsFor
|
10
|
+
|
11
|
+
attr_reader :form, :helper, :field_errors_showed
|
12
|
+
|
13
|
+
def initialize(form, helper)
|
14
|
+
@form = form
|
15
|
+
@helper = helper
|
16
|
+
@field_errors_showed = Set.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def model_instance
|
20
|
+
form.object
|
21
|
+
end
|
22
|
+
|
23
|
+
def hidden_field(field_name, options = {})
|
24
|
+
@form.hidden_field(field_name, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def check_box_field(field_name, options = {})
|
28
|
+
field(field_name, options) { @form.check_box(field_name, options) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def file_field(field_name, options = {})
|
32
|
+
field(field_name, options) { @form.file_field(field_name, options) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def searchable_association_field(field_name, options = {})
|
36
|
+
saf = SearchableAssociationField.new(self, field_name, options)
|
37
|
+
saf.hidden_input <<
|
38
|
+
field(field_name, options) { saf.visible_input } <<
|
39
|
+
saf.javascript_tag
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def field(field_name, options)
|
45
|
+
@helper.content_tag(:div, class: 'form-group') do
|
46
|
+
s = field_label(field_name, options[:label], options[:required])
|
47
|
+
s << ' '
|
48
|
+
s << yield()
|
49
|
+
s << ' '
|
50
|
+
s << field_errors(field_name)
|
51
|
+
s
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def field_errors(field_name)
|
56
|
+
s = ActiveSupport::SafeBuffer.new
|
57
|
+
field_errors_fields(field_name).each do |frf|
|
58
|
+
s << field_errors_errors(frf)
|
59
|
+
end
|
60
|
+
s
|
61
|
+
end
|
62
|
+
|
63
|
+
def field_errors_errors(field_name)
|
64
|
+
return nil unless model_instance.errors.messages[field_name]
|
65
|
+
s = ActiveSupport::SafeBuffer.new
|
66
|
+
model_instance.errors.messages[field_name].each { |error| s << field_error(error) }
|
67
|
+
@field_errors_showed.add(field_name)
|
68
|
+
s
|
69
|
+
end
|
70
|
+
|
71
|
+
def field_errors_fields(field_name)
|
72
|
+
m = /^(.+)_id$/.match(field_name)
|
73
|
+
(m ? [m[1], field_name] : [field_name, "#{field_name}_id"]).map(&:to_sym)
|
74
|
+
end
|
75
|
+
|
76
|
+
def field_error(error_message)
|
77
|
+
@helper.content_tag(:div, class: 'error') do
|
78
|
+
error_message
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def field_label(field_name, label, required)
|
83
|
+
required = model_instance.attribute_required?(field_name) if required.nil?
|
84
|
+
@form.label(field_name, label, class: required ? 'required' : 'optional')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Eac
|
2
|
+
module CommonFormHelper
|
3
|
+
class FormBuilder
|
4
|
+
module AssociationSelectField
|
5
|
+
def association_select_field(field_name, options = {})
|
6
|
+
options = options.dup
|
7
|
+
methods = extract_methods(options)
|
8
|
+
select_options = extract_select_options(options)
|
9
|
+
collection = extract_association_key(field_name, options, :collection, :all)
|
10
|
+
foreign_key = extract_association_key(field_name, options, :foreign_key,
|
11
|
+
:association_foreign_key)
|
12
|
+
field(field_name, options) do
|
13
|
+
form.collection_select(foreign_key, collection, methods[:value], methods[:text],
|
14
|
+
select_options, class: 'form-control')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def extract_methods(options)
|
21
|
+
{ value: options.delete(:value_method) || :id, text:
|
22
|
+
options.delete(:text_method) || :to_s }
|
23
|
+
end
|
24
|
+
|
25
|
+
def extract_select_options(options)
|
26
|
+
options.extract!(:prompt, :include_blank)
|
27
|
+
end
|
28
|
+
|
29
|
+
def extract_association_key(field_name, options, key, method)
|
30
|
+
return options.delete(key) if options.key?(key)
|
31
|
+
if model_instance.class.respond_to?(:reflect_on_association)
|
32
|
+
return model_instance.class.reflect_on_association(field_name).send(method)
|
33
|
+
end
|
34
|
+
fail "#{model_instance.class} não possui um método \"reflect_on_association\". " \
|
35
|
+
"Defina explicitamente a opção :#{key}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Eac
|
2
|
+
module CommonFormHelper
|
3
|
+
class FormBuilder
|
4
|
+
module CommonTextFields
|
5
|
+
%w(email password text).each do |t|
|
6
|
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
7
|
+
def #{t}_field(field_name, options = {}) # def text_field(field_name, options = {})
|
8
|
+
field(field_name, options) do # field(field_name, options) do
|
9
|
+
@form.#{t}_field(field_name, # @form.text_field(field_name,
|
10
|
+
class: 'form-control') # class: 'form-control')
|
11
|
+
end # end
|
12
|
+
end # end
|
13
|
+
RUBY_EVAL
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Eac
|
2
|
+
module CommonFormHelper
|
3
|
+
class FormBuilder
|
4
|
+
module CurrencyField
|
5
|
+
def currency_field(field_name, options = {})
|
6
|
+
hidden_id = SecureRandom.hex(5)
|
7
|
+
visible_id = SecureRandom.hex(5)
|
8
|
+
cf = field(field_name, options) do
|
9
|
+
form.hidden_field(field_name, id: hidden_id) <<
|
10
|
+
helper.text_field_tag("#{field_name}_visible", '',
|
11
|
+
id: visible_id, class: 'form-control')
|
12
|
+
end
|
13
|
+
cf << javascript_currency_mask(hidden_id, visible_id)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def javascript_currency_mask(hidden_id, visible_id)
|
19
|
+
helper.content_tag :script do
|
20
|
+
helper.raw("new CurrencyField('#{hidden_id}', '#{visible_id}', " \
|
21
|
+
"#{mask_money_options});")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def mask_money_options
|
26
|
+
<<-eos
|
27
|
+
{
|
28
|
+
prefix: '#{I18n.t('number.currency.format.unit')} ',
|
29
|
+
allowNegative: true,
|
30
|
+
thousands: '#{I18n.t('number.currency.format.delimiter')}',
|
31
|
+
decimal: '#{I18n.t('number.currency.format.separator')}',
|
32
|
+
affixesStay: false
|
33
|
+
}
|
34
|
+
eos
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Eac
|
2
|
+
module CommonFormHelper
|
3
|
+
class FormBuilder
|
4
|
+
module DateField
|
5
|
+
def date_field(field_name, options = {})
|
6
|
+
field_options = options.extract!(:use_month_numbers, :use_two_digit_numbers,
|
7
|
+
:use_short_month, :add_month_numbers, :use_month_names,
|
8
|
+
:month_format_string, :date_separator, :start_year,
|
9
|
+
:end_year, :discard_day, :discard_month, :discard_year,
|
10
|
+
:order, :include_blank, :default, :selected, :disabled,
|
11
|
+
:prompt, :with_css_classes)
|
12
|
+
field(field_name, options) do
|
13
|
+
@helper.content_tag(:div, @form.date_select(field_name, field_options),
|
14
|
+
class: 'form-control-complex')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|