case_form 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.
- data/CHANGELOG.rdoc +1 -0
- data/MIT-LICENSE.rdoc +20 -0
- data/Manifest +86 -0
- data/README.rdoc +0 -0
- data/Rakefile +30 -0
- data/TODO.rdoc +7 -0
- data/case_form.gemspec +31 -0
- data/lib/case_form.rb +88 -0
- data/lib/case_form/associations.rb +50 -0
- data/lib/case_form/buttons.rb +175 -0
- data/lib/case_form/core_ext/form_helper.rb +54 -0
- data/lib/case_form/core_ext/layout_helper.rb +16 -0
- data/lib/case_form/core_ext/sentence_error.rb +38 -0
- data/lib/case_form/element.rb +40 -0
- data/lib/case_form/element/base.rb +95 -0
- data/lib/case_form/element/button.rb +64 -0
- data/lib/case_form/element/error.rb +54 -0
- data/lib/case_form/element/errors/complex_error.rb +107 -0
- data/lib/case_form/element/errors/simple_error.rb +76 -0
- data/lib/case_form/element/fieldset.rb +35 -0
- data/lib/case_form/element/hint.rb +54 -0
- data/lib/case_form/element/input.rb +106 -0
- data/lib/case_form/element/inputs/collection/checkbox_input.rb +36 -0
- data/lib/case_form/element/inputs/collection/radio_input.rb +27 -0
- data/lib/case_form/element/inputs/collection/select_input.rb +22 -0
- data/lib/case_form/element/inputs/collection_input.rb +89 -0
- data/lib/case_form/element/inputs/datetime/date_input.rb +45 -0
- data/lib/case_form/element/inputs/datetime/date_time_input.rb +50 -0
- data/lib/case_form/element/inputs/datetime/time_input.rb +34 -0
- data/lib/case_form/element/inputs/datetime/time_zone_input.rb +24 -0
- data/lib/case_form/element/inputs/file_input.rb +13 -0
- data/lib/case_form/element/inputs/hidden_input.rb +17 -0
- data/lib/case_form/element/inputs/number_input.rb +42 -0
- data/lib/case_form/element/inputs/search_input.rb +32 -0
- data/lib/case_form/element/inputs/string_input.rb +18 -0
- data/lib/case_form/element/inputs/text_input.rb +19 -0
- data/lib/case_form/element/label.rb +52 -0
- data/lib/case_form/element/nested_model.rb +105 -0
- data/lib/case_form/element/nested_models/handle.rb +18 -0
- data/lib/case_form/element/nested_models/handles/destructor_handle.rb +47 -0
- data/lib/case_form/element/nested_models/handles/generator_handle.rb +55 -0
- data/lib/case_form/element_ext/associationable.rb +54 -0
- data/lib/case_form/element_ext/columnable.rb +21 -0
- data/lib/case_form/element_ext/naming.rb +17 -0
- data/lib/case_form/element_ext/validationable.rb +13 -0
- data/lib/case_form/errors.rb +189 -0
- data/lib/case_form/form_builder.rb +11 -0
- data/lib/case_form/inputs.rb +1095 -0
- data/lib/case_form/labels.rb +102 -0
- data/lib/case_form/version.rb +6 -0
- data/lib/generators/case_form/install_generator.rb +33 -0
- data/lib/generators/case_form/templates/case_form.rb +63 -0
- data/lib/generators/case_form/templates/javascripts/jquery.case_form.js +10 -0
- data/lib/generators/case_form/templates/javascripts/prototype.case_form.js +0 -0
- data/lib/generators/case_form/templates/locales/en.yml +28 -0
- data/lib/generators/case_form/templates/locales/pl.yml +28 -0
- data/lib/generators/case_form/templates/stylesheets/stylesheet.css +93 -0
- data/lib/generators/case_form/templates/stylesheets/stylesheet_changes.css +1 -0
- data/lib/generators/case_form/uninstall_generator.rb +30 -0
- data/rails/init.rb +1 -0
- data/test/element/button_test.rb +85 -0
- data/test/element/errors/complex_error_test.rb +140 -0
- data/test/element/errors/simple_error_test.rb +92 -0
- data/test/element/fieldset_test.rb +28 -0
- data/test/element/hint_test.rb +81 -0
- data/test/element/input_test.rb +197 -0
- data/test/element/inputs/collection/checkbox_input_test.rb +176 -0
- data/test/element/inputs/collection/radio_input_test.rb +156 -0
- data/test/element/inputs/collection/select_input_test.rb +152 -0
- data/test/element/inputs/datetime/date_input_test.rb +160 -0
- data/test/element/inputs/datetime/datetime_input_test.rb +227 -0
- data/test/element/inputs/datetime/time_input_test.rb +72 -0
- data/test/element/inputs/datetime/time_zone_input_test.rb +42 -0
- data/test/element/inputs/file_input_test.rb +13 -0
- data/test/element/inputs/hidden_input_test.rb +13 -0
- data/test/element/inputs/number_input_test.rb +50 -0
- data/test/element/inputs/search_input_test.rb +13 -0
- data/test/element/inputs/string_input_test.rb +33 -0
- data/test/element/inputs/text_input_test.rb +13 -0
- data/test/element/label_test.rb +62 -0
- data/test/element/nested_model_test.rb +163 -0
- data/test/element/nested_models/handles/destructor_handle_test.rb +35 -0
- data/test/element/nested_models/handles/generator_handle_test.rb +27 -0
- data/test/form_builder_test.rb +25 -0
- data/test/form_helper_test.rb +15 -0
- data/test/lib/models.rb +268 -0
- data/test/test_helper.rb +74 -0
- metadata +235 -0
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class DateInput < Input
         | 
| 5 | 
            +
                  self.allowed_options -= [:id]
         | 
| 6 | 
            +
                  self.allowed_options << [:placeholder, :readonly, :elements, :separator, 
         | 
| 7 | 
            +
                                           :year, :start_year, :end_year, :month, :short_month, :day, 
         | 
| 8 | 
            +
                                           :default, :date, :prompt, :blank, :disabled]
         | 
| 9 | 
            +
                  
         | 
| 10 | 
            +
                  private
         | 
| 11 | 
            +
                    def default_options
         | 
| 12 | 
            +
                      options[:elements]        ||= [:year, :month, :day]
         | 
| 13 | 
            +
                      options[:order]             = options.delete(:elements)
         | 
| 14 | 
            +
                      options[:discard_year]      = discard_element?(:year)
         | 
| 15 | 
            +
                      options[:discard_month]     = discard_element?(:month)
         | 
| 16 | 
            +
                      options[:discard_day]       = discard_element?(:day)
         | 
| 17 | 
            +
                      options[:start_year]      ||= nested_date_options(:year, :start, Time.now.year - 10)
         | 
| 18 | 
            +
                      options[:end_year]        ||= nested_date_options(:year, :end, Time.now.year + 10)
         | 
| 19 | 
            +
                      options[:use_month_names]   = nested_date_options(:month, :names, nil)
         | 
| 20 | 
            +
                      options[:use_short_month]   = nested_date_options(:month, :short, false)
         | 
| 21 | 
            +
                      options[:default]         ||= options.delete(:date) || nil
         | 
| 22 | 
            +
                      options[:date_separator]    = options.delete(:separator) || " - "
         | 
| 23 | 
            +
                      options[:include_blank]     = options.delete(:blank) || false
         | 
| 24 | 
            +
                      super
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                    
         | 
| 27 | 
            +
                    def input
         | 
| 28 | 
            +
                      builder.date_select(specific_method, options, html_options)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                    
         | 
| 31 | 
            +
                    def discard_element?(type)
         | 
| 32 | 
            +
                      case 
         | 
| 33 | 
            +
                      when options.has_key?(type)
         | 
| 34 | 
            +
                        (options[type] == false) ? true : false
         | 
| 35 | 
            +
                      when options[:order].include?(type)
         | 
| 36 | 
            +
                        false
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    def nested_date_options(type, option, default)
         | 
| 41 | 
            +
                      options.delete("#{option}_#{type}".to_sym) || (options[type].delete(option) if options[type].present?) || default
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class DateTimeInput < Input
         | 
| 5 | 
            +
                  self.allowed_options -= [:id]
         | 
| 6 | 
            +
                  self.allowed_options << [:placeholder, :readonly, :elements, :disabled,
         | 
| 7 | 
            +
                                           :separator, :datetime_separator, :date_separator, :time_separator,
         | 
| 8 | 
            +
                                           :year, :start_year, :end_year, :month, :short_month, :day, :hour, :minute, :second, 
         | 
| 9 | 
            +
                                           :minute_step, :default, :datetime, :prompt, :blank]
         | 
| 10 | 
            +
                                           
         | 
| 11 | 
            +
                  private
         | 
| 12 | 
            +
                    def default_options
         | 
| 13 | 
            +
                      options[:elements]           ||= [:year, :month, :day, :hour, :minute]
         | 
| 14 | 
            +
                      options[:order]                = options.delete(:elements)
         | 
| 15 | 
            +
                      options[:discard_year]         = discard_element?(:year)
         | 
| 16 | 
            +
                      options[:discard_month]        = discard_element?(:month)
         | 
| 17 | 
            +
                      options[:discard_day]          = discard_element?(:day)
         | 
| 18 | 
            +
                      options[:discard_hour]         = discard_element?(:hour)
         | 
| 19 | 
            +
                      options[:discard_minute]       = discard_element?(:minute)
         | 
| 20 | 
            +
                      options[:include_seconds]      = discard_element?(:second, false, true)
         | 
| 21 | 
            +
                      options[:start_year]         ||= nested_date_options(:year, :start, Time.now.year - 10)
         | 
| 22 | 
            +
                      options[:end_year]           ||= nested_date_options(:year, :end, Time.now.year + 10)
         | 
| 23 | 
            +
                      options[:use_month_names]      = nested_date_options(:month, :names, nil)
         | 
| 24 | 
            +
                      options[:use_short_month]      = nested_date_options(:month, :short, false)
         | 
| 25 | 
            +
                      options[:minute_step]        ||= nested_date_options(:minute, :step, 1)
         | 
| 26 | 
            +
                      options[:datetime_separator] ||= options.delete(:separator) || nil
         | 
| 27 | 
            +
                      options[:default]            ||= options.delete(:datetime) || nil
         | 
| 28 | 
            +
                      options[:include_blank]        = options.delete(:blank) || false
         | 
| 29 | 
            +
                      super
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                    
         | 
| 32 | 
            +
                    def input
         | 
| 33 | 
            +
                      builder.datetime_select(specific_method, options, html_options)
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                    
         | 
| 36 | 
            +
                    def discard_element?(type, t = true, f = false)
         | 
| 37 | 
            +
                      case 
         | 
| 38 | 
            +
                      when options.has_key?(type)
         | 
| 39 | 
            +
                        (options[type] == false) ? t : f
         | 
| 40 | 
            +
                      else 
         | 
| 41 | 
            +
                        options[:order].include?(type) ? f : t
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                    
         | 
| 45 | 
            +
                    def nested_date_options(type, option, default)
         | 
| 46 | 
            +
                      options.delete("#{option}_#{type}".to_sym) || (options[type].delete(option) if options[type].present?) || default
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class TimeInput < Input
         | 
| 5 | 
            +
                  self.allowed_options -= [:id]
         | 
| 6 | 
            +
                  self.allowed_options << [:placeholder, :readonly, :elements, :separator, :time, :default, 
         | 
| 7 | 
            +
                                           :prompt, :minute_step, :date, :blank, :disabled]
         | 
| 8 | 
            +
                  
         | 
| 9 | 
            +
                  private
         | 
| 10 | 
            +
                    def default_options
         | 
| 11 | 
            +
                      options[:elements]        ||= [:hour, :minute]
         | 
| 12 | 
            +
                      options[:time_separator]    = options.delete(:separator) || " : "
         | 
| 13 | 
            +
                      options[:include_blank]     = options.delete(:blank) || false
         | 
| 14 | 
            +
                      options[:include_seconds]   = time_seconds?
         | 
| 15 | 
            +
                      options[:ignore_date]       = with_date?
         | 
| 16 | 
            +
                      options[:default]         ||= options.delete(:time) || nil
         | 
| 17 | 
            +
                      super
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                    
         | 
| 20 | 
            +
                    def input
         | 
| 21 | 
            +
                      builder.time_select(specific_method, options, html_options)
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                    
         | 
| 24 | 
            +
                    def time_seconds?
         | 
| 25 | 
            +
                      options[:elements].include?(:second) || false
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                    
         | 
| 28 | 
            +
                    def with_date?
         | 
| 29 | 
            +
                      @date ||= options.delete(:date) || false
         | 
| 30 | 
            +
                      !@date
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class TimeZoneInput < Input
         | 
| 5 | 
            +
                  self.allowed_options << [:readonly, :blank, :disabled, 
         | 
| 6 | 
            +
                                           :priority_zones, :zones, :default, :time_zone]
         | 
| 7 | 
            +
                  
         | 
| 8 | 
            +
                  private
         | 
| 9 | 
            +
                    def default_options
         | 
| 10 | 
            +
                      options[:default]       = options.delete(:time_zone) || "UTC"
         | 
| 11 | 
            +
                      options[:include_blank] = options.delete(:blank) || false
         | 
| 12 | 
            +
                      super
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                    
         | 
| 15 | 
            +
                    def input
         | 
| 16 | 
            +
                      builder.time_zone_select(specific_method, priority_zones, options, html_options)
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                    
         | 
| 19 | 
            +
                    def priority_zones
         | 
| 20 | 
            +
                      options.delete(:priority_zones) || nil
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class HiddenInput < Input
         | 
| 5 | 
            +
                  self.allowed_options -= [:autofocus, :required, :label, :hint, :error]
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  def generate
         | 
| 8 | 
            +
                    builder.hidden_field(specific_method, html_options)
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  private
         | 
| 12 | 
            +
                    def default_options
         | 
| 13 | 
            +
                      options[:class] ||= [:input, :hidden]
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class NumberInput < Input
         | 
| 5 | 
            +
                  self.allowed_options << [:as, :min, :max, :in, :step, :readonly, :disabled]
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  private
         | 
| 8 | 
            +
                    def default_options
         | 
| 9 | 
            +
                      options[:min]  ||= input_limit(:minimum) 
         | 
| 10 | 
            +
                      options[:max]  ||= input_limit(:maximum)
         | 
| 11 | 
            +
                      options[:step] ||= number_step
         | 
| 12 | 
            +
                      options[:size] ||= CaseForm.input_size
         | 
| 13 | 
            +
                      super
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                    
         | 
| 16 | 
            +
                    def input
         | 
| 17 | 
            +
                      builder.send("#{input_type}_field", specific_method, html_options)
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                    
         | 
| 20 | 
            +
                    def input_limit(type)
         | 
| 21 | 
            +
                      validations = object.class.validators_on(method).select { |v| v.kind == :length }
         | 
| 22 | 
            +
                      if validations.any?
         | 
| 23 | 
            +
                        validations.first.options[type]
         | 
| 24 | 
            +
                      elsif object_column_type?(:decimal)
         | 
| 25 | 
            +
                        value = (10**(object_column.precision - object_column.scale))-number_step
         | 
| 26 | 
            +
                        value = value*(-1) if type == :minimum
         | 
| 27 | 
            +
                        value.to_f
         | 
| 28 | 
            +
                      else
         | 
| 29 | 
            +
                        nil
         | 
| 30 | 
            +
                      end
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                    
         | 
| 33 | 
            +
                    def number_step
         | 
| 34 | 
            +
                      if object_column_type?(:decimal)
         | 
| 35 | 
            +
                        (10**(-object_column.scale)).to_f
         | 
| 36 | 
            +
                      else
         | 
| 37 | 
            +
                        CaseForm.number_step
         | 
| 38 | 
            +
                      end
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class SearchInput < Input
         | 
| 5 | 
            +
                  self.allowed_options -= [:required, :error, :hint]
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  private
         | 
| 8 | 
            +
                    def wrapper_options
         | 
| 9 | 
            +
                      wrapper_options = super
         | 
| 10 | 
            +
                      wrapper_options[:class] << :search
         | 
| 11 | 
            +
                      wrapper_options
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                    
         | 
| 14 | 
            +
                    def contents
         | 
| 15 | 
            +
                      contents = []
         | 
| 16 | 
            +
                      [:label, :input].each do |element| 
         | 
| 17 | 
            +
                        if options[element] == false
         | 
| 18 | 
            +
                          options.delete(element)
         | 
| 19 | 
            +
                          next
         | 
| 20 | 
            +
                        else
         | 
| 21 | 
            +
                          contents << send(element)
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                      contents.join.html_safe
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                    
         | 
| 27 | 
            +
                    def input
         | 
| 28 | 
            +
                      builder.search_field(specific_method, html_options)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class StringInput < Input
         | 
| 5 | 
            +
                  self.allowed_options << [:as, :size, :placeholder, :pattern, :disabled, :readonly, :maxlength]
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  private
         | 
| 8 | 
            +
                    def default_options
         | 
| 9 | 
            +
                      options[:size] ||= input_size
         | 
| 10 | 
            +
                      super
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                    
         | 
| 13 | 
            +
                    def input
         | 
| 14 | 
            +
                      builder.send("#{input_type}_field", specific_method, html_options)
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class TextInput < Input
         | 
| 5 | 
            +
                  self.allowed_options << [:cols, :rows, :readonly, :maxlength, :escape, :disabled, :placeholder]
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  private
         | 
| 8 | 
            +
                    def default_options
         | 
| 9 | 
            +
                      options[:cols] ||= CaseForm.textarea_cols
         | 
| 10 | 
            +
                      options[:rows] ||= CaseForm.textarea_rows
         | 
| 11 | 
            +
                      super
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
                    
         | 
| 14 | 
            +
                    def input
         | 
| 15 | 
            +
                      builder.text_area(specific_method, html_options)
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            module CaseForm
         | 
| 2 | 
            +
              module Element
         | 
| 3 | 
            +
                class Label < Base
         | 
| 4 | 
            +
                  include ElementExt::Validationable
         | 
| 5 | 
            +
                  include ElementExt::Columnable
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  self.allowed_options << [:for, :text, :required]
         | 
| 8 | 
            +
                  
         | 
| 9 | 
            +
                  attr_accessor :method
         | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  # Initialize label object
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  def initialize(builder, method, options={})
         | 
| 14 | 
            +
                    @method = method
         | 
| 15 | 
            +
                    super(builder, options)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                  
         | 
| 18 | 
            +
                  # Generate label with defined text and HTML options
         | 
| 19 | 
            +
                  #
         | 
| 20 | 
            +
                  def generate
         | 
| 21 | 
            +
                    template.label(object_name, method, text, html_options)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                        
         | 
| 24 | 
            +
                  private
         | 
| 25 | 
            +
                    # Distribute default options for label.
         | 
| 26 | 
            +
                    #
         | 
| 27 | 
            +
                    def default_options
         | 
| 28 | 
            +
                      options[:class]    ||= [:label]
         | 
| 29 | 
            +
                      options[:id]       ||= "#{sanitized_object_name}_#{specific_method}_label"
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                    
         | 
| 32 | 
            +
                    # Generate label text with optional required symbol.
         | 
| 33 | 
            +
                    #
         | 
| 34 | 
            +
                    def text
         | 
| 35 | 
            +
                      @text  = options.delete(:text) || translated_text
         | 
| 36 | 
            +
                      @text += CaseForm.require_symbol if required?
         | 
| 37 | 
            +
                      @text
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    # Translate label text with I18n.
         | 
| 41 | 
            +
                    # 
         | 
| 42 | 
            +
                    def translated_text
         | 
| 43 | 
            +
                      lookups = []
         | 
| 44 | 
            +
                      lookups << :"activerecord.attributes.#{object_name}.#{method}"
         | 
| 45 | 
            +
                      lookups << :"activemodel.attributes.#{object_name}.#{method}"
         | 
| 46 | 
            +
                      lookups << :"case_form.attributes.#{object_name}.#{method}"
         | 
| 47 | 
            +
                      lookups << method.to_s.humanize
         | 
| 48 | 
            +
                      I18n.t(lookups.shift, :default => lookups)
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,105 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module CaseForm
         | 
| 3 | 
            +
              module Element
         | 
| 4 | 
            +
                class NestedModel < Base
         | 
| 5 | 
            +
                  include ElementExt::Associationable
         | 
| 6 | 
            +
                  
         | 
| 7 | 
            +
                  self.allowed_options << [:destructor, :generator, :collection, :fields]
         | 
| 8 | 
            +
                  
         | 
| 9 | 
            +
                  attr_accessor :method, :block
         | 
| 10 | 
            +
                  
         | 
| 11 | 
            +
                  def initialize(builder, method, options={}, &block)
         | 
| 12 | 
            +
                    @method = validate_nested_attributes_association(method, builder.object)
         | 
| 13 | 
            +
                    @block  = block
         | 
| 14 | 
            +
                    super(builder, options)
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  
         | 
| 17 | 
            +
                  def generate
         | 
| 18 | 
            +
                    contents = []
         | 
| 19 | 
            +
                    contents << nested_model_contents
         | 
| 20 | 
            +
                    contents << builder.new_object(method, :fields => (block.nil? ? options[:fields] : block)) if allow_create?
         | 
| 21 | 
            +
                    contents.join.html_safe
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                  
         | 
| 24 | 
            +
                  private
         | 
| 25 | 
            +
                    def default_options
         | 
| 26 | 
            +
                      super
         | 
| 27 | 
            +
                      options[:custom]               = {}
         | 
| 28 | 
            +
                      options[:custom][:association] = method
         | 
| 29 | 
            +
                      options[:collection]         ||= default_collection
         | 
| 30 | 
            +
                      options[:fields]             ||= default_fields
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                    
         | 
| 33 | 
            +
                    def nested_attributes_method_defined?
         | 
| 34 | 
            +
                      object.respond_to?(:"#{method}_attributes=")
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                    
         | 
| 37 | 
            +
                    def nested_model_contents
         | 
| 38 | 
            +
                      contents = []
         | 
| 39 | 
            +
                      nested_models = [collection].flatten.compact
         | 
| 40 | 
            +
                      nested_models.each do |object|
         | 
| 41 | 
            +
                        contents << nested_model(object)
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                      Element::Fieldset.new(builder, :class => "#{method}_association").generate(contents.join.html_safe) unless contents.blank?
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    
         | 
| 46 | 
            +
                    def nested_model(object)
         | 
| 47 | 
            +
                      template.content_tag(:div, nil, :class => "#{method}_association_inputs") do
         | 
| 48 | 
            +
                        builder.case_fields_for(method, object) do |b|
         | 
| 49 | 
            +
                          unless block.nil?
         | 
| 50 | 
            +
                            block.call(b) << (b.destroy_object if allow_destroy?)
         | 
| 51 | 
            +
                          else
         | 
| 52 | 
            +
                            fields = [options[:fields]].flatten 
         | 
| 53 | 
            +
                            fields << :_destroy if allow_destroy?
         | 
| 54 | 
            +
                            template.concat(b.attributes(*fields))
         | 
| 55 | 
            +
                          end
         | 
| 56 | 
            +
                        end
         | 
| 57 | 
            +
                      end
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                    
         | 
| 60 | 
            +
                    def allow_create?
         | 
| 61 | 
            +
                      if collection_association?
         | 
| 62 | 
            +
                        if options.has_key?(:generator)
         | 
| 63 | 
            +
                          options[:generator] != false
         | 
| 64 | 
            +
                        elsif block.is_a?(Proc)
         | 
| 65 | 
            +
                          false
         | 
| 66 | 
            +
                        else
         | 
| 67 | 
            +
                          true
         | 
| 68 | 
            +
                        end
         | 
| 69 | 
            +
                      else
         | 
| 70 | 
            +
                        false
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
                    
         | 
| 74 | 
            +
                    def allow_destroy?
         | 
| 75 | 
            +
                      if collection_association?
         | 
| 76 | 
            +
                        if options.has_key?(:desctructor)
         | 
| 77 | 
            +
                          options[:destructor] != false
         | 
| 78 | 
            +
                        elsif block.is_a?(Proc)
         | 
| 79 | 
            +
                          false
         | 
| 80 | 
            +
                        else 
         | 
| 81 | 
            +
                          object.class.nested_attributes_options[method.to_sym][:allow_destroy]
         | 
| 82 | 
            +
                        end
         | 
| 83 | 
            +
                      else
         | 
| 84 | 
            +
                        false
         | 
| 85 | 
            +
                      end
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
                    
         | 
| 88 | 
            +
                    def default_collection
         | 
| 89 | 
            +
                      object.send(method) || (new_nested_model unless collection_association?)
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
                    
         | 
| 92 | 
            +
                    def default_fields
         | 
| 93 | 
            +
                      association_class.content_columns.map(&:name).map(&:to_sym) - CaseForm.locked_columns
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                    
         | 
| 96 | 
            +
                    def new_nested_model
         | 
| 97 | 
            +
                      collection_association? ? association_class.new : object.send(:"build_#{method}")
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                    
         | 
| 100 | 
            +
                    def collection
         | 
| 101 | 
            +
                      options[:collection]
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
            end
         |