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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +18 -0
  3. data/lib/assets/javascripts/currency_field.js +21 -0
  4. data/lib/assets/javascripts/eac_rails_utils.js +6 -0
  5. data/lib/assets/javascripts/input_searchable.js +78 -0
  6. data/lib/assets/javascripts/jMenu.jquery.min.js +12 -0
  7. data/lib/assets/javascripts/jquery.maskMoney.js +409 -0
  8. data/lib/assets/stylesheets/autocomplete.scss +33 -0
  9. data/lib/assets/stylesheets/bootstrap3-dropdown.scss +47 -0
  10. data/lib/assets/stylesheets/eac_rails_utils.scss +44 -0
  11. data/lib/assets/stylesheets/jmenu.scss +78 -0
  12. data/lib/eac/common_form_helper.rb +37 -0
  13. data/lib/eac/common_form_helper/form_builder.rb +88 -0
  14. data/lib/eac/common_form_helper/form_builder/association_select_field.rb +40 -0
  15. data/lib/eac/common_form_helper/form_builder/common_text_fields.rb +18 -0
  16. data/lib/eac/common_form_helper/form_builder/currency_field.rb +39 -0
  17. data/lib/eac/common_form_helper/form_builder/date_field.rb +20 -0
  18. data/lib/eac/common_form_helper/form_builder/fields_for.rb +44 -0
  19. data/lib/eac/common_form_helper/form_builder/radio_select_field.rb +44 -0
  20. data/lib/eac/common_form_helper/form_builder/searchable_association_field.rb +77 -0
  21. data/lib/eac/cpf_validator.rb +60 -0
  22. data/lib/eac/formatter_helper.rb +27 -0
  23. data/lib/eac/htmlbeautifier.rb +25 -0
  24. data/lib/eac/menus_helper.rb +17 -0
  25. data/lib/eac/menus_helper/bootstrap_gui_builder.rb +90 -0
  26. data/lib/eac/menus_helper/data_builder.rb +57 -0
  27. data/lib/eac/menus_helper/gui_builder.rb +51 -0
  28. data/lib/eac/model.rb +87 -0
  29. data/lib/eac/simple_cache.rb +29 -0
  30. data/lib/eac/source_target_fixtures.rb +51 -0
  31. data/lib/eac_rails_utils.rb +29 -0
  32. data/lib/eac_rails_utils/patches/model_attribute_required.rb +31 -0
  33. data/lib/eac_rails_utils/rails/engine.rb +5 -0
  34. data/lib/eac_rails_utils/version.rb +3 -0
  35. data/test/dummy/Rakefile +6 -0
  36. data/test/dummy/app/models/job.rb +4 -0
  37. data/test/dummy/app/models/user.rb +7 -0
  38. data/test/dummy/config.ru +4 -0
  39. data/test/dummy/config/application.rb +12 -0
  40. data/test/dummy/config/boot.rb +4 -0
  41. data/test/dummy/config/database.yml +5 -0
  42. data/test/dummy/config/environment.rb +5 -0
  43. data/test/dummy/config/environments/test.rb +42 -0
  44. data/test/dummy/config/routes.rb +8 -0
  45. data/test/dummy/config/secrets.yml +22 -0
  46. data/test/dummy/db/migrate/20160415125333_create_users.rb +9 -0
  47. data/test/dummy/db/migrate/20160415143123_create_jobs.rb +7 -0
  48. data/test/dummy/db/migrate/20160415143229_add_job_to_users.rb +5 -0
  49. data/test/dummy/db/schema.rb +25 -0
  50. data/test/lib/eac/common_form_helper_test.rb +31 -0
  51. data/test/lib/eac/cpf_validator_test.rb +33 -0
  52. data/test/lib/eac/formatter_helper_test.rb +19 -0
  53. data/test/lib/eac/model_test.rb +76 -0
  54. data/test/lib/eac/simple_cache_test.rb +56 -0
  55. data/test/lib/eac_rails_utils/patches/model_attribute_required_test.rb +39 -0
  56. data/test/test_helper.rb +11 -0
  57. 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