hungryform-rails 0.0.1 → 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/.gitignore +2 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +4 -0
- data/README.md +37 -1
- data/Rakefile +3 -0
- data/app/assets/javascripts/hungryform.js +145 -0
- data/app/assets/stylesheets/hungryform.css +8 -0
- data/app/views/hungryform/_checkbox_field.html.erb +12 -0
- data/app/views/hungryform/_form.html.erb +11 -0
- data/app/views/hungryform/_group.html.erb +7 -0
- data/app/views/hungryform/_html.html.erb +5 -0
- data/app/views/hungryform/_radio_group.html.erb +11 -0
- data/app/views/hungryform/_select_field.html.erb +9 -0
- data/app/views/hungryform/_text_area.html.erb +9 -0
- data/app/views/hungryform/_text_field.html.erb +9 -0
- data/gemfiles/rails3.gemfile +5 -0
- data/gemfiles/rails4.gemfile +5 -0
- data/gemfiles/rails41.gemfile +5 -0
- data/gemfiles/rails42.gemfile +5 -0
- data/hungryform-rails.gemspec +31 -0
- data/lib/hungryform/rails/action_view.rb +90 -0
- data/lib/hungryform/rails/engine.rb +6 -0
- data/lib/hungryform/rails/railtie.rb +24 -0
- data/lib/hungryform/rails/renderable.rb +13 -0
- data/lib/hungryform/rails/version.rb +5 -0
- data/lib/hungryform/rails.rb +11 -0
- data/lib/hungryform-rails.rb +1 -0
- data/spec/action_view_spec.rb +106 -0
- data/spec/dummy/app.rb +96 -0
- data/spec/dummy/vendor/assets/javascripts/jquery-2.1.3.min.js +4 -0
- data/spec/features/field_dependencies_spec.rb +51 -0
- data/spec/features/form_walk_spec.rb +92 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/views/checkbox_field_spec.rb +28 -0
- data/spec/views/form_spec.rb +42 -0
- data/spec/views/group_spec.rb +35 -0
- data/spec/views/html_spec.rb +22 -0
- data/spec/views/select_field_spec.rb +35 -0
- data/spec/views/shared_examples/rendered_active_element.rb +34 -0
- data/spec/views/shared_examples/wrapped.rb +28 -0
- data/spec/views/text_area_spec.rb +28 -0
- data/spec/views/text_field_spec.rb +28 -0
- metadata +69 -18
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 5e1dbc3db77663b5d70ffed6dc331c8567ddb438
         | 
| 4 | 
            +
              data.tar.gz: 68cb11ae8193f7047e1a4cd74b6c2ac0fe481f26
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 61346d2de43d07701d7375cb85f0982e789e90d752060ae205fadfc8a37b84fb947a898d5935bfdb83fd10148d0e2eb950372212222403b86d90c02df6c19337
         | 
| 7 | 
            +
              data.tar.gz: 3b4da5e9334f8d65bf48a78fee4aa2fe873256fb245d1630ed5febe67a9d9709960dc56098e8d136f154fdc9bd47b0d5f1122de2b1ef61520a61553f063144cd
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/.ruby-version
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            2.1.5
         | 
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1 +1,37 @@ | |
| 1 | 
            -
            # hungryform-rails
         | 
| 1 | 
            +
            #Hungryform Rails [](https://travis-ci.org/andrba/hungryform-rails)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            This gem is an adaptor between the HungryForm gem and Rails. 
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ##Installation:
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Add the hungryform gem to your Gemfile:
         | 
| 8 | 
            +
            ```ruby
         | 
| 9 | 
            +
            gem "hungryform-rails"
         | 
| 10 | 
            +
            ```
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            Add the Hungryform require to your application.js:
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
            //= require hungryform
         | 
| 15 | 
            +
            ```
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            Add the Hungryform require to your application.css:
         | 
| 18 | 
            +
            ```
         | 
| 19 | 
            +
            //= require hungryform
         | 
| 20 | 
            +
            ```
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            Use the following helper to generate the form in your views:
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            ```ruby
         | 
| 25 | 
            +
            <%= hungry_form_for(@form) %>
         | 
| 26 | 
            +
            ```
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            ##Configuration
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            This gem extends the configuration options provided by Hungryform. Create initializer in ```config/initializers/hungryform.rb``` and place the configuration code inside:
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ```ruby
         | 
| 33 | 
            +
            Hungryform.configure do |config|
         | 
| 34 | 
            +
              config.rails.elements_templates = 'hungryform'
         | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
            ```
         | 
| 37 | 
            +
             | 
    
        data/Rakefile
    ADDED
    
    
| @@ -0,0 +1,145 @@ | |
| 1 | 
            +
            // Module to handle form interactions such as
         | 
| 2 | 
            +
            // prev, next links and dependency resolution
         | 
| 3 | 
            +
            (function($) {
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              function HungryForm(form) {
         | 
| 6 | 
            +
                this.form = form;
         | 
| 7 | 
            +
                this.$form = $(form);
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                this.init();
         | 
| 10 | 
            +
              }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              HungryForm.prototype = {
         | 
| 13 | 
            +
                init: function() {
         | 
| 14 | 
            +
                  this.bindEvents();
         | 
| 15 | 
            +
                },
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                bindEvents: function() {
         | 
| 18 | 
            +
                  var form_action = this.$form.find("input[name='form_action']"),
         | 
| 19 | 
            +
                      that = this;
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  this.$form.find(':input').on('change select', function() {
         | 
| 22 | 
            +
                    that.updateVisibility();
         | 
| 23 | 
            +
                  });
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  this.$form.find('input, select').keypress(function(event) { 
         | 
| 26 | 
            +
                    return event.keyCode !== 13; 
         | 
| 27 | 
            +
                  });
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  $("a[data-rel='" + this.$form.data('rel') + "'][data-form-action]").on('click', function(event) {
         | 
| 30 | 
            +
                    if ($(this).data('form-method') === 'get') {
         | 
| 31 | 
            +
                      return true;
         | 
| 32 | 
            +
                    }
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    event.preventDefault();
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    var action = $(this).data('form-action');
         | 
| 37 | 
            +
                    form_action.val(action);
         | 
| 38 | 
            +
                    that.$form.attr('action', $(this).attr('href'));
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    that.$form.submit();
         | 
| 41 | 
            +
                  });
         | 
| 42 | 
            +
                },
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                updateVisibility: function() {
         | 
| 45 | 
            +
                  var that = this;
         | 
| 46 | 
            +
                  this.$form.find('div[data-dependency], fieldset[data-dependency]').each(function() {
         | 
| 47 | 
            +
                    var obj = $(this);
         | 
| 48 | 
            +
                    var dependency = obj.data('dependency');
         | 
| 49 | 
            +
                    
         | 
| 50 | 
            +
                    if (that.resolveDependency(dependency)) {
         | 
| 51 | 
            +
                      that._setObjectVisibility(obj, true);
         | 
| 52 | 
            +
                    } else {
         | 
| 53 | 
            +
                      that._setObjectVisibility(obj, false);
         | 
| 54 | 
            +
                    }
         | 
| 55 | 
            +
                  });
         | 
| 56 | 
            +
                },
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                resolveDependency: function(dependency) {
         | 
| 59 | 
            +
                  var isDependent = false;
         | 
| 60 | 
            +
                  var that = this;
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  $.each(dependency, function(operator, args) {
         | 
| 63 | 
            +
                    if (operator === 'eq') {
         | 
| 64 | 
            +
                      isDependent = that._isEqual(args);
         | 
| 65 | 
            +
                      return false;
         | 
| 66 | 
            +
                    } else if (operator === 'lt') {
         | 
| 67 | 
            +
                      isDependent = that._isLessThan(args);
         | 
| 68 | 
            +
                      return false;
         | 
| 69 | 
            +
                    } else if (operator === 'gt') {
         | 
| 70 | 
            +
                      isDependent = that._isGreaterThan(args);
         | 
| 71 | 
            +
                      return false;
         | 
| 72 | 
            +
                    } else if (operator === 'not') {
         | 
| 73 | 
            +
                      isDependent = !that.resolveDependency(args);
         | 
| 74 | 
            +
                      return false;
         | 
| 75 | 
            +
                    } else if (operator === 'is') {
         | 
| 76 | 
            +
                      isDependent = that._isSet(args);
         | 
| 77 | 
            +
                      return false;
         | 
| 78 | 
            +
                    } else if (operator === 'and') {
         | 
| 79 | 
            +
                      isDependent = true;
         | 
| 80 | 
            +
                      $.each(args, function(index, argument) {
         | 
| 81 | 
            +
                          isDependent = that.resolveDependency(argument) && isDependent;
         | 
| 82 | 
            +
                          if (isDependent === false) {
         | 
| 83 | 
            +
                              //No need to check the rest of the dependencies
         | 
| 84 | 
            +
                              return false;
         | 
| 85 | 
            +
                          }
         | 
| 86 | 
            +
                      });
         | 
| 87 | 
            +
                      return false;
         | 
| 88 | 
            +
                    } else if (operator === 'or') {
         | 
| 89 | 
            +
                      $.each(args, function(index, argument) {
         | 
| 90 | 
            +
                          isDependent = that.resolveDependency(argument) || isDependent;
         | 
| 91 | 
            +
                          if (isDependent === true) {
         | 
| 92 | 
            +
                              //No need to check the rest of the dependencies
         | 
| 93 | 
            +
                              return false;
         | 
| 94 | 
            +
                          }
         | 
| 95 | 
            +
                      });
         | 
| 96 | 
            +
                      return false;
         | 
| 97 | 
            +
                    }
         | 
| 98 | 
            +
                  });
         | 
| 99 | 
            +
                  
         | 
| 100 | 
            +
                  return isDependent;
         | 
| 101 | 
            +
                },
         | 
| 102 | 
            +
                _isEqual: function(args) {
         | 
| 103 | 
            +
                  return args.length > 1 && this._getArgument(args[0]).toString() === this._getArgument(args[1]).toString();
         | 
| 104 | 
            +
                },
         | 
| 105 | 
            +
                _isLessThan: function(args) {
         | 
| 106 | 
            +
                  return args.length > 1 && parseFloat(this._getArgument(args[0])) < parseFloat(this._getArgument(args[1]));
         | 
| 107 | 
            +
                },
         | 
| 108 | 
            +
                _isGreaterThan: function(args) {
         | 
| 109 | 
            +
                  return args.length > 1 && parseFloat(this._getArgument(args[0])) > parseFloat(this._getArgument(args[1]));
         | 
| 110 | 
            +
                },
         | 
| 111 | 
            +
                _isSet: function(args) {
         | 
| 112 | 
            +
                  return typeof(args[0]) !== 'undefined' && this._getArgument(args[0]).length > 0;
         | 
| 113 | 
            +
                },
         | 
| 114 | 
            +
                _getArgument: function(argument) {
         | 
| 115 | 
            +
                  var input = this.$form.find("input[name='" + argument + "'], textarea[name='" + argument + "'], select[name='" + argument + "']");
         | 
| 116 | 
            +
                  
         | 
| 117 | 
            +
                  if (input.length > 0) {
         | 
| 118 | 
            +
                    if (input.filter(':radio').length > 0) {
         | 
| 119 | 
            +
                      return input.filter(':radio:checked').length > 0? input.filter(':radio:checked').val() : '';
         | 
| 120 | 
            +
                    } else if (input.filter(':checkbox').length > 0) {
         | 
| 121 | 
            +
                      return input.filter(':checkbox:checked').length > 0? input.filter(':checkbox:checked').val() : '';
         | 
| 122 | 
            +
                    } else {
         | 
| 123 | 
            +
                      return input.val();
         | 
| 124 | 
            +
                    }
         | 
| 125 | 
            +
                  }
         | 
| 126 | 
            +
                  else {
         | 
| 127 | 
            +
                    return argument;
         | 
| 128 | 
            +
                  }
         | 
| 129 | 
            +
                },
         | 
| 130 | 
            +
                _setObjectVisibility: function(obj, visible) {
         | 
| 131 | 
            +
                  if (visible) {
         | 
| 132 | 
            +
                    obj.removeClass('hidden');
         | 
| 133 | 
            +
                  }
         | 
| 134 | 
            +
                  else {
         | 
| 135 | 
            +
                    obj.addClass('hidden');
         | 
| 136 | 
            +
                  }
         | 
| 137 | 
            +
                }
         | 
| 138 | 
            +
              };
         | 
| 139 | 
            +
             | 
| 140 | 
            +
              $(function() {
         | 
| 141 | 
            +
                $('form.hungryform').each(function() {
         | 
| 142 | 
            +
                  new HungryForm(this);
         | 
| 143 | 
            +
                });
         | 
| 144 | 
            +
              });
         | 
| 145 | 
            +
            }(jQuery));
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            <%= content_tag :div, id: "#{field.name}_wrapper", class: field.html_class, 'data-dependency' => field.dependency_json do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              concat label_tag field.name, field.label << ("*" if field.required?).to_s
         | 
| 4 | 
            +
              concat hidden_field_tag field.name, 0
         | 
| 5 | 
            +
              concat check_box_tag field.name, 1, field.checked?, field.attributes.except(:class, :checked)
         | 
| 6 | 
            +
              unless field.error.empty?
         | 
| 7 | 
            +
                concat content_tag :span, field.error, class: 'error' 
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
            end %>
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            <%= field.attributes.inspect %>
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            <%= hidden_field_tag :form_action %>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <h1><%= form.current_page.label %></h1>
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            <% form.current_page.elements.each do |el| %>
         | 
| 6 | 
            +
              <%= render partial: "#{views_prefix}/#{el.class.name.demodulize.underscore}", locals: { field: el, views_prefix: views_prefix } %>
         | 
| 7 | 
            +
            <% end %>
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            <%= hungry_link_to_prev_page(form, "Prev", method: :post) if form.prev_page %>
         | 
| 10 | 
            +
            <%= hungry_link_to_next_page(form, "Next", method: :post) if form.next_page %>
         | 
| 11 | 
            +
            <%= hungry_link_to_submit(form, "Submit") if form.current_page == form.pages.last %>
         | 
| @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            <%= content_tag :div, id: "#{field.name}_wrapper", class: field.html_class, 'data-dependency' => field.dependency_json do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              field.elements.each do |el|
         | 
| 4 | 
            +
                concat render partial: "#{views_prefix}/#{el.class.name.demodulize.underscore}", locals: { field: el, views_prefix: views_prefix }
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
            end %>
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            <%= content_tag :div, id: "#{field.name}_wrapper", class: field.html_class, 'data-dependency' => field.dependency_json do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              concat label_tag field.name, field.label << ("*" if field.required?).to_s
         | 
| 4 | 
            +
              field.options.each do |key, value|
         | 
| 5 | 
            +
                concat radio_button_tag key, value, field.value == value, field.attributes.except(:class)
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
              unless field.error.empty?
         | 
| 8 | 
            +
                concat content_tag :span, field.error, class: 'error' 
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            end %>
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            <%= content_tag :div, id: "#{field.name}_wrapper", class: field.html_class, 'data-dependency' => field.dependency_json do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              concat label_tag field.name, field.label << ("*" if field.required?).to_s
         | 
| 4 | 
            +
              concat select_tag field.name, options_for_select(field.options.invert, field.value), field.attributes.except(:class)
         | 
| 5 | 
            +
              unless field.error.empty?
         | 
| 6 | 
            +
                concat content_tag :span, field.error, class: 'error' 
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            end %>
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            <%= content_tag :div, id: "#{field.name}_wrapper", class: field.html_class, 'data-dependency' => field.dependency_json do
         | 
| 2 | 
            +
                
         | 
| 3 | 
            +
              concat label_tag field.name, field.label << ("*" if field.required?).to_s
         | 
| 4 | 
            +
              concat text_area_tag field.name, field.value, field.attributes.except(:class)
         | 
| 5 | 
            +
              unless field.error.empty?
         | 
| 6 | 
            +
                concat content_tag :span, field.error, class: 'error' 
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
            end %>
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            <%= content_tag :div, id: "#{field.name}_wrapper", class: field.html_class, 'data-dependency' => field.dependency_json do
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              concat label_tag field.name, field.label << ("*" if field.required?).to_s
         | 
| 4 | 
            +
              concat text_field_tag field.name, field.value, field.attributes.except(:class)
         | 
| 5 | 
            +
              unless field.error.empty?
         | 
| 6 | 
            +
                concat content_tag :span, field.error, class: 'error' 
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
            end %>
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'hungryform/rails/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "hungryform-rails"
         | 
| 8 | 
            +
              spec.version       = HungryForm::Rails::VERSION
         | 
| 9 | 
            +
              spec.platform      = Gem::Platform::RUBY
         | 
| 10 | 
            +
              spec.authors       = ["Andrey Bazhutkin"]
         | 
| 11 | 
            +
              spec.email         = ["andrey.bazhutkin@gmail.com"]
         | 
| 12 | 
            +
              spec.summary       = "Use HungryForm with Rails"
         | 
| 13 | 
            +
              spec.description   = "A gem to automate using HungryForm with Rails"
         | 
| 14 | 
            +
              spec.homepage      = "https://github.com/andrba/hungryform-rails"
         | 
| 15 | 
            +
              spec.license       = "MIT"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              spec.files         = `git ls-files -z`.split("\x0")
         | 
| 18 | 
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 19 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 20 | 
            +
              spec.require_paths = ["lib"]
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              spec.required_ruby_version = '>= 2.0.0'
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
              spec.add_dependency 'hungryform',   '~> 0.0', '>= 0.0.9'
         | 
| 25 | 
            +
              spec.add_dependency 'rails',        '>= 3.2.1'
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              spec.add_development_dependency "rspec",       '~> 3.0'
         | 
| 28 | 
            +
              spec.add_development_dependency "rspec-rails", '~> 3.0'
         | 
| 29 | 
            +
              spec.add_development_dependency "capybara",    '~> 2.4'
         | 
| 30 | 
            +
              spec.add_development_dependency "poltergeist", '~> 1.6'
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,90 @@ | |
| 1 | 
            +
            module HungryForm
         | 
| 2 | 
            +
              module Rails
         | 
| 3 | 
            +
                module ActionView
         | 
| 4 | 
            +
                  # Render a form
         | 
| 5 | 
            +
                  def hungry_form_for(form, options = {})
         | 
| 6 | 
            +
                    options[:data] ||= {}
         | 
| 7 | 
            +
                    options[:data][:rel] ||= form_rel(form)
         | 
| 8 | 
            +
                    options[:class] = [options[:class], "hungryform"].compact.join(' ')
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    views_prefix = options.delete(:views_prefix) || HungryForm.configuration.rails.elements_templates
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    form_tag('', options) do
         | 
| 13 | 
            +
                      render partial: "#{views_prefix}/form", locals: {
         | 
| 14 | 
            +
                        form: form,
         | 
| 15 | 
            +
                        views_prefix: views_prefix
         | 
| 16 | 
            +
                      }
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  # Render a link to the next page
         | 
| 21 | 
            +
                  def hungry_link_to_next_page(form, name, options = {}, &block)
         | 
| 22 | 
            +
                    link_to name, *link_params(form, options, action: :next), &block
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  # Render a link to the previous page
         | 
| 26 | 
            +
                  def hungry_link_to_prev_page(form, name, options = {}, &block)
         | 
| 27 | 
            +
                    link_to name, *link_params(form, options, action: :prev), &block
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  # Render a link to a provided page
         | 
| 31 | 
            +
                  def hungry_link_to_page(form, page, options = {}, &block)
         | 
| 32 | 
            +
                    link_to page.label, *link_params(form, options, action: :page, page: page), &block
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  # Render a link that submits the form
         | 
| 36 | 
            +
                  def hungry_link_to_submit(form, name, options = {}, &block)
         | 
| 37 | 
            +
                    params = clean_params(form, options.delete(:params))
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    link_to name, url_for(params), options.reverse_merge(
         | 
| 40 | 
            +
                      data: { form_method: :post, form_action: :submit, rel: form_rel(form) }
         | 
| 41 | 
            +
                    ), &block
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  private
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  # Form ralation attribute is used to streamline js selection of a form
         | 
| 47 | 
            +
                  # and its navigational elements like next/prev buttons and pages lists
         | 
| 48 | 
            +
                  def form_rel(form)
         | 
| 49 | 
            +
                    "hungry-form-#{form.__id__}"
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                   # Builds link_to params except for the link's name
         | 
| 53 | 
            +
                  def link_params(form, options, action_options = {})
         | 
| 54 | 
            +
                    method = options.delete(:method) || 'get'
         | 
| 55 | 
            +
                    params = clean_params(form, options.delete(:params))
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    params[:page] = method.to_s == 'get' ? get_page(form, action_options) : form.current_page.name
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    options.reverse_merge!(
         | 
| 60 | 
            +
                      data: {
         | 
| 61 | 
            +
                        form_method: method,
         | 
| 62 | 
            +
                        form_action: action_options[:action],
         | 
| 63 | 
            +
                        rel: form_rel(form)
         | 
| 64 | 
            +
                      }
         | 
| 65 | 
            +
                    )
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    [url_for(params), options]
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  # Find the name of the page to go to when the 'get' method is used in a
         | 
| 71 | 
            +
                  # form navigation
         | 
| 72 | 
            +
                  def get_page(form, action_options)
         | 
| 73 | 
            +
                    case action_options[:action]
         | 
| 74 | 
            +
                    when :page
         | 
| 75 | 
            +
                      action_options[:page].name
         | 
| 76 | 
            +
                    when :next, :prev
         | 
| 77 | 
            +
                      form.send("#{action_options[:action]}_page").try(:name) || ''
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  # Remove Rails specific params from the params hash as well as
         | 
| 82 | 
            +
                  # all the form params
         | 
| 83 | 
            +
                  def clean_params(form, params)
         | 
| 84 | 
            +
                    rails_params = [:authenticity_token, :commit, :utf8, :_method]
         | 
| 85 | 
            +
                    form_params = form.elements.keys + [:form_action, :errors]
         | 
| 86 | 
            +
                    self.params.except(*(rails_params + form_params)).merge(params || {})
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            module HungryForm
         | 
| 2 | 
            +
              module Rails
         | 
| 3 | 
            +
                class Railtie < ::Rails::Railtie
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  module Configuration
         | 
| 6 | 
            +
                    attr_accessor :rails
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  initializer 'hungryform', before: :load_config_initializers do
         | 
| 10 | 
            +
                    HungryForm::Elements::Base::Element.send :include, Renderable
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    HungryForm.configuration.extend Configuration
         | 
| 13 | 
            +
                    HungryForm.configuration.rails = ActiveSupport::OrderedOptions.new
         | 
| 14 | 
            +
                    HungryForm.configuration.rails.elements_templates = 'hungryform'
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  initializer 'active_support' do
         | 
| 18 | 
            +
                    ActiveSupport.on_load(:action_view) do
         | 
| 19 | 
            +
                      ::ActionView::Base.send :include, ActionView
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            module HungryForm
         | 
| 2 | 
            +
              module Rails
         | 
| 3 | 
            +
                module Renderable
         | 
| 4 | 
            +
                  def html_class
         | 
| 5 | 
            +
                    classes = []
         | 
| 6 | 
            +
                    classes << attributes[:class] if attributes[:class]
         | 
| 7 | 
            +
                    classes << 'hidden' unless visible?
         | 
| 8 | 
            +
                    classes << 'invalid' if self.is_a?(HungryForm::Elements::Base::ActiveElement) && self.error.present?
         | 
| 9 | 
            +
                    classes.join(' ') if classes.any?
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            module HungryForm
         | 
| 2 | 
            +
              module Rails
         | 
| 3 | 
            +
              end
         | 
| 4 | 
            +
            end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require 'hungryform'
         | 
| 7 | 
            +
            require 'hungryform/rails/version'
         | 
| 8 | 
            +
            require 'hungryform/rails/railtie'
         | 
| 9 | 
            +
            require 'hungryform/rails/engine'
         | 
| 10 | 
            +
            require 'hungryform/rails/action_view'
         | 
| 11 | 
            +
            require 'hungryform/rails/renderable'
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            require 'hungryform/rails'
         | 
| @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe HungryForm::Rails::ActionView, :type => :helper do
         | 
| 4 | 
            +
              let(:form_params) { {} }
         | 
| 5 | 
            +
              let(:form) do 
         | 
| 6 | 
            +
                HungryForm::Form.new params: form_params do
         | 
| 7 | 
            +
                  page :first do
         | 
| 8 | 
            +
                    text_field :first_name
         | 
| 9 | 
            +
                    text_field :last_name
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  page :second do
         | 
| 13 | 
            +
                    text_field :email
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              before { helper.params.merge!(controller: 'hungry_form', action: 'show') }
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              describe '#hungry_link_to_next_page' do
         | 
| 21 | 
            +
                let(:params) { {} }
         | 
| 22 | 
            +
                subject { helper.hungry_link_to_next_page(form, "Next", params) }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                it { is_expected.to include("data-rel=\"hungry-form-#{form.__id__}\"") }
         | 
| 25 | 
            +
                it { is_expected.to include('data-form-action="next"') }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                context 'when method is GET' do
         | 
| 28 | 
            +
                  it { is_expected.to include('/hungryform/second') }
         | 
| 29 | 
            +
                  it { is_expected.to include('data-form-method="get"') }
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                context 'when method is POST' do
         | 
| 33 | 
            +
                  before { params[:method] = :post }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  it { is_expected.to include('/hungryform/first') }
         | 
| 36 | 
            +
                  it { is_expected.to include('data-form-method="post"') }
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              describe '#hungry_link_to_prev_page' do
         | 
| 41 | 
            +
                let(:form_params) { { page: 'second' } }
         | 
| 42 | 
            +
                let(:params) { {} }
         | 
| 43 | 
            +
                subject { helper.hungry_link_to_prev_page(form, "Prev", params) }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                it { is_expected.to include("data-rel=\"hungry-form-#{form.__id__}\"") }
         | 
| 46 | 
            +
                it { is_expected.to include('data-form-action="prev"') }
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                context 'when method is GET' do
         | 
| 49 | 
            +
                  it { is_expected.to include('/hungryform/first') }
         | 
| 50 | 
            +
                  it { is_expected.to include('data-form-method="get"') }
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                context 'when method is POST' do
         | 
| 54 | 
            +
                  before { params[:method] = :post }
         | 
| 55 | 
            +
                  
         | 
| 56 | 
            +
                  it { is_expected.to include('/hungryform/second') }
         | 
| 57 | 
            +
                  it { is_expected.to include('data-form-method="post"') }
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              describe '#hungry_link_to_page' do
         | 
| 62 | 
            +
                let(:params) { {} }
         | 
| 63 | 
            +
                subject { helper.hungry_link_to_page(form, form.pages.last, params) }
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                it { is_expected.to include("data-rel=\"hungry-form-#{form.__id__}\"") }
         | 
| 66 | 
            +
                it { is_expected.to include('data-form-action="page"') }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                context 'when method is GET' do
         | 
| 69 | 
            +
                  it { is_expected.to include('/hungryform/second') }
         | 
| 70 | 
            +
                  it { is_expected.to include('data-form-method="get"') }
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                context 'when method is POST' do
         | 
| 74 | 
            +
                  before { params[:method] = :post }
         | 
| 75 | 
            +
                  
         | 
| 76 | 
            +
                  it { is_expected.to include('/hungryform/first') }
         | 
| 77 | 
            +
                  it { is_expected.to include('data-form-method="post"') }
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              describe '#hungry_form_for' do
         | 
| 82 | 
            +
                subject { helper.hungry_form_for(form) }
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                it 'renders a form' do
         | 
| 85 | 
            +
                  expect(subject).to include('<form')
         | 
| 86 | 
            +
                  expect(subject).to include("data-rel=\"hungry-form-#{form.__id__}\"")
         | 
| 87 | 
            +
                  expect(subject).to match /<input(?=.*name="form_action")(?=.*id="form_action")/ #Mandatory hidden action field
         | 
| 88 | 
            +
                  expect(subject).to include('First name')
         | 
| 89 | 
            +
                  expect(subject).to include('Last name')
         | 
| 90 | 
            +
                  expect(subject).to include('Next')
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                it 'renders only a current page' do
         | 
| 94 | 
            +
                  expect(subject).to include('<h1>First</h1>')
         | 
| 95 | 
            +
                  expect(subject).not_to include('<h1>Second</h1>')
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              describe '#hungry_link_to_submit' do
         | 
| 100 | 
            +
                let(:params) { {} }
         | 
| 101 | 
            +
                subject { helper.hungry_link_to_submit(form, "Submit", params) }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                it { is_expected.to include("data-rel=\"hungry-form-#{form.__id__}\"") }
         | 
| 104 | 
            +
                it { is_expected.to include('data-form-action="submit"') }
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
            end
         |