eac_rails_utils 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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