formize 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -4,21 +4,37 @@ Simple form DSL with dynamic interactions for Rails.
4
4
 
5
5
  == Installation
6
6
 
7
- Add it to your Gemfile:
7
+ Add to your Gemfile these fllowing lines:
8
8
  gem "jquery-rails" # Need to be explicitly specified
9
9
  gem "formize"
10
10
 
11
+ == Assets incorporation (JavaScripts and Stylesheets)
12
+ Formize comes with basic scripts and stylesheets which must be included in the layout (at least at the start).
13
+
14
+ === In Rails 3.0.x
11
15
  Formize requires the gem +jquery-rails+, so if you don't already use it:
12
16
  rails generate jquery:install
13
17
 
14
18
  Then install +formize+ in your app like +jquery-rails+:
15
19
  rails generate formize:install
16
20
 
17
- It's not necessary, but I recommend to use HAML with it for cleaner views:
18
- gem "haml"
21
+ These previous commands install all the needed files in your +public/+ directory.
22
+ Then the files can be included with an helper:
23
+ # app/views/layouts/application.html.erb
24
+ <%= formize_include_tag -%>
25
+
26
+ === In Rails ≥ 3.1
27
+ With the asset pipeline, there is no need to run generators or copy files. So for stylesheets:
28
+ # app/assets/stylesheets/application.css
29
+ *= require formize
30
+
31
+ And for javascripts:
32
+ # app/assets/javascripts/application.js
33
+ *= require formize
19
34
 
20
35
  == Usage
21
36
 
37
+
22
38
  In controller:
23
39
 
24
40
  class OrdersController < ApplicationController
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.10
1
+ 0.0.11
@@ -103,6 +103,7 @@ Formize.Dialog = {
103
103
  },
104
104
 
105
105
  submitForm: function(form) {
106
+ var form = $(this);
106
107
  var dialog_id = form.attr('data-dialog');
107
108
  var dialog = $('#'+dialog_id);
108
109
 
@@ -121,7 +122,7 @@ Formize.Dialog = {
121
122
  $(document).trigger("dom:update", dialog.attr('id'));
122
123
  } else {
123
124
  // Refresh element with its refresh URL
124
- var updated = $('#'+dialog.attr('data-dialog-update'));
125
+ var updated_id = '#'+dialog.attr('data-dialog-update'), updated = $(updated_id);
125
126
  if (updated[0] !== undefined) {
126
127
  var url = updated.attr('data-refresh');
127
128
  $.ajax(url, {
@@ -129,6 +130,7 @@ Formize.Dialog = {
129
130
  success: function(data2, textStatus2, request2) {
130
131
  updated.replaceWith(request2.responseText);
131
132
  $(document).trigger("dom:update");
133
+ $(updated_id+' input').trigger("emulated:change");
132
134
  }
133
135
  });
134
136
  }
@@ -171,6 +173,20 @@ Formize.refreshDependents = function (event) {
171
173
  return false;
172
174
  }
173
175
 
176
+ Formize.Toggles = {
177
+
178
+ ifChecked: function () {
179
+ if (this.checked) {
180
+ $($(this).attr('data-show')).slideDown();
181
+ $($(this).attr('data-hide')).slideUp();
182
+ } else {
183
+ $($(this).attr('data-show')).slideUp();
184
+ $($(this).attr('data-hide')).slideDown();
185
+ }
186
+ }
187
+
188
+ }
189
+
174
190
 
175
191
  /**
176
192
  * Special method which is a sharthand to bind every element
@@ -279,14 +295,16 @@ behave("a[data-close-dialog]", "click", function() {
279
295
  });
280
296
 
281
297
  // Submits dialog forms
282
- behave("form[data-dialog]", "submit", function() {
283
- return Formize.Dialog.submitForm($(this));
284
- });
298
+ behave("form[data-dialog]", "submit", Formize.Dialog.submitForm);
285
299
 
300
+ // Refresh dependents on changes
286
301
  behave("*[data-dependents]", "change", Formize.refreshDependents);
302
+ behave("*[data-dependents]", "emulated:change", Formize.refreshDependents);
287
303
  // Compensate for changes made with keyboard
288
304
  behave("select[data-dependents]", "keypress", Formize.refreshDependents);
289
- behave("*[data-dependents]", "emulated:change", Formize.refreshDependents);
305
+
306
+ behave("input[data-show], input[data-hide]", "load", Formize.Toggles.ifChecked);
307
+ behave("input[data-show], input[data-hide]", "change", Formize.Toggles.ifChecked);
290
308
 
291
309
  // Resizes the overlay automatically
292
310
  $(window).resize(function() {
@@ -1,10 +1,14 @@
1
- require 'rubygems'
2
- require "bundler/setup"
3
- require 'active_support'
4
- # Formize provides controller's side defined forms.
1
+ # require 'rubygems'
2
+ # require 'bundler/setup'
3
+ # require 'active_support'
4
+ require 'formize/railtie' if defined?(::Rails)
5
+ require 'formize/engine' if defined?(::Rails)
6
+
7
+ # :include: ../README.rdoc
5
8
  module Formize
9
+ extend ActiveSupport::Autoload
6
10
 
7
- def self.configure(name, value = nil)
11
+ def self.configure(name, value = nil) # :nodoc:
8
12
  unless self.respond_to?("#{name}=")
9
13
  # mattr_accessor(name)
10
14
  code = "unless defined?(@@#{name})\n"
@@ -37,11 +41,11 @@ module Formize
37
41
  # How many select options can be displayed before to become a +unroll+
38
42
  configure :select_count_max, 7
39
43
 
44
+ autoload :Definition
45
+ autoload :Helpers
46
+ autoload :ActionController
47
+ autoload :Generator
40
48
  end
41
49
 
42
- require 'action_view'
43
- require 'formize/definition'
44
- require 'formize/generator'
45
- require 'formize/form_helper'
46
- require 'formize/action_pack'
50
+ # require 'action_view'
47
51
 
@@ -21,13 +21,14 @@ module Formize
21
21
  options[:view_form_method_name] = "_#{self.controller_name}_formize_form_#{name}_tag"
22
22
  options[:view_fields_method_name] = "_#{self.controller_name}_formize_fields_#{name}_tag"
23
23
  options[:method_name] = options[:view_fields_method_name]
24
- form = Formize::Form.new(name, model, options)
24
+ options[:best_name] = "#{self.controller_name}#{'_'+name.to_s if name != self.controller_name.to_sym}"
25
+ form = Formize::Definition::Form.new(name, model, options)
25
26
  if block_given?
26
27
  yield form
27
28
  else
28
29
  formize_by_default(form)
29
30
  end
30
- generator = Formize::Generator.new(form, self)
31
+ generator = Formize::Generator::Base.new(form, self)
31
32
  class_eval(generator.controller_code, "#{__FILE__}:#{__LINE__}")
32
33
  ActionView::Base.send(:class_eval, generator.view_code, "#{__FILE__}:#{__LINE__}")
33
34
  end
@@ -40,7 +41,7 @@ module Formize
40
41
  for column in form.model.columns
41
42
  next if column.name =~ /_count$/ or [:id, :created_at, :updated_at, :lock_version, :type, :creator_id, :updater_id].include?(column.name.to_sym)
42
43
  if column.name =~ /_id$/
43
- reflections = form.model.reflections.select{|k, x| x.primary_key_name.to_s == column.name.to_s }
44
+ reflections = form.model.reflections.select{ |k, x| x.primary_key_name.to_s == column.name.to_s }
44
45
  if reflections.size == 1
45
46
  f.field(column.name.gsub(/_id$/, ''), :choices=>:all, :source=>:foreign_class, :new=>true)
46
47
  # elsif reflections.size > 1 # AMBIGUITY
@@ -60,5 +61,5 @@ module Formize
60
61
 
61
62
  end
62
63
 
63
- require 'action_controller'
64
- ActionController::Base.send(:include, Formize::ActionController)
64
+ # require 'action_controller'
65
+ # ActionController::Base.send(:include, Formize::ActionController)
@@ -1,5 +1,9 @@
1
- # require 'formize/definition/element'
2
- require 'formize/definition/form'
3
- require 'formize/definition/form_element'
4
- require 'formize/definition/field_set'
5
- require 'formize/definition/field'
1
+ module Formize
2
+ # @private
3
+ module Definition
4
+ autoload :Form, 'formize/definition/form'
5
+ autoload :FormElement, 'formize/definition/form_element'
6
+ autoload :FieldSet, 'formize/definition/field_set'
7
+ autoload :Field, 'formize/definition/field'
8
+ end
9
+ end
@@ -1,65 +1,67 @@
1
1
  module Formize
2
2
 
3
+ module Definition
3
4
 
4
- # Represents the field element
5
- class Field < FormElement
6
- attr_reader :name, :options, :column, :record_name, :method, :type, :required, :choices, :input_id, :source, :item_label, :field_id, :reflection, :html_options, :default, :search_attributes
5
+ # Represents the field element
6
+ class Field < FormElement
7
+ attr_reader :name, :column, :record_name, :method, :type, :required, :choices, :input_id, :source, :item_label, :field_id, :reflection, :html_options, :default, :search_attributes
7
8
 
8
- TYPES = [:check_box, :choice, :date, :datetime, :label, :numeric, :password, :mono_choice, :string, :text_area].freeze
9
+ TYPES = [:check_box, :choice, :date, :datetime, :label, :numeric, :password, :mono_choice, :string, :text_area].freeze
9
10
 
10
- def initialize(form, parent, name, options={})
11
- super(form, parent)
12
- @name = name.to_s
13
- @options = (options.is_a?(Hash) ? options : {})
14
- @column = form.model.columns_hash[@name]
15
- @record_name = form.record_name
16
- @method = @name
17
- unless @options[:default].nil?
18
- @default = (@options[:default].is_a?(String) ? Code.new(@options[:default]) : @options[:default])
19
- end
20
- @html_options = @options.delete(:html_options)||{}
21
- @depend_on = @options.delete(:depend_on)
22
- raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.fields[@depend_on].nil?
23
- if type = @options.delete(:as)
24
- raise ArgumentError.new("Unknown field type (got #{@options[:as].inspect}, expects #{TYPES.join(', ')})") unless TYPES.include? type
25
- @type = type
26
- else
27
- @type = :password if @name.to_s.match /password/
28
- if @choices = @options.delete(:choices)
29
- if @choices.is_a? Array
30
- @type = :choice
31
- elsif [Symbol, Hash].include? @choices.class
32
- @type = :mono_choice
33
- @reflection = form.model.reflections[@method.to_sym]
34
- @source = @options.delete(:source) # || @reflection.class_name
35
- @is_method = true if @options[:new]
36
- @method_name = self.form.unique_name + "_inf_" + @name
37
- @method = @reflection.primary_key_name
38
- unless @item_label = @options.delete(:item_label)
39
- model = @reflection.class_name.constantize
40
- available_methods = (model.columns_hash.keys+model.instance_methods).collect{|x| x.to_s}
41
- @item_label = [:label, :name, :title, :code, :number, :inspect].detect{|x| available_methods.include?(x.to_s)}
11
+ def initialize(form, parent, name, options={})
12
+ super(form, parent, options)
13
+ @name = name.to_s
14
+ @column = form.model.columns_hash[@name]
15
+ @record_name = form.record_name
16
+ @method = @name
17
+ unless @options[:default].nil?
18
+ @default = @options.delete(:default) # (@options[:default].is_a?(String) ? Formize::Generator::Code.new(@options[:default]) : @options[:default])
19
+ end
20
+ @html_options = @options.delete(:html_options)||{}
21
+ @depend_on = @options.delete(:depend_on)
22
+ raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.all_fields[@depend_on].nil?
23
+ if type = @options.delete(:as)
24
+ raise ArgumentError.new("Unknown field type (got #{@options[:as].inspect}, expects #{TYPES.join(', ')})") unless TYPES.include? type
25
+ @type = type
26
+ else
27
+ @type = :password if @name.to_s.match /password/
28
+ if @choices = @options.delete(:choices)
29
+ if @choices.is_a? Array
30
+ @type = :choice
31
+ elsif [Symbol, Hash].include? @choices.class
32
+ @type = :mono_choice
33
+ @reflection = form.model.reflections[@method.to_sym]
34
+ @source = @options.delete(:source) # || @reflection.class_name
35
+ @is_method = true if @options[:new]
36
+ @method_name = self.form.unique_name + "_inf_" + @name
37
+ @method = @reflection.primary_key_name
38
+ unless @item_label = @options.delete(:item_label)
39
+ model = @reflection.class_name.constantize
40
+ available_methods = (model.columns_hash.keys+model.instance_methods).collect{|x| x.to_s}
41
+ @item_label = [:label, :name, :title, :code, :number, :inspect].detect{|x| available_methods.include?(x.to_s)}
42
+ end
43
+ @search_attributes = @options[:search] || @reflection.class_name.constantize.content_columns.select{|c| c.type != :boolean and ![:created_at, :updated_at, :lock_version].include?(c.name.to_sym)}.collect{|c| c.name.to_sym}
44
+ else
45
+ raise ArgumentError.new("Option :choices must be Array, Symbol or Hash (got #{@choices.class.name})")
42
46
  end
43
- @search_attributes = @options[:search] || @reflection.class_name.constantize.content_columns.select{|c| c.type != :boolean and ![:created_at, :updated_at, :lock_version].include?(c.name.to_sym)}.collect{|c| c.name.to_sym}
44
- else
45
- raise ArgumentError.new("Option :choices must be Array, Symbol or Hash (got #{@choices.class.name})")
46
47
  end
48
+ if column
49
+ @type = :check_box if column.type == :boolean
50
+ @type = :date if column.type == :date
51
+ @type = :datetime if column.type==:datetime or column.type==:timestamp
52
+ @type = :numeric if [:integer, :float, :decimal].include? column.type
53
+ @type = :text_area if column.type == :text
54
+ end
55
+ @type = :label if @form.model.readonly_attributes.include? @record_name
56
+ @type ||= :string
47
57
  end
48
- if column
49
- @type = :check_box if column.type == :boolean
50
- @type = :date if column.type == :date
51
- @type = :datetime if column.type==:datetime or column.type==:timestamp
52
- @type = :numeric if [:integer, :float, :decimal].include? column.type
53
- @type = :text_area if column.type == :text
54
- end
55
- @type = :label if @form.model.readonly_attributes.include? @record_name
56
- @type ||= :string
58
+ @required = false
59
+ @required = !@column.null if @column
60
+ @required = true if @options.delete(:required).is_a?(TrueClass)
61
+ @input_id = form.model.name.underscore << '_' << method.to_s
62
+ @field_id = "ff" << Time.now.to_i.to_s(36) << rand.to_s[2..-1].to_i.to_s(36)
57
63
  end
58
- @required = false
59
- @required = !@column.null if @column
60
- @required = true if @options.delete(:required).is_a?(TrueClass)
61
- @input_id = form.model.name.underscore << '_' << method.to_s
62
- @field_id = "ff" << Time.now.to_i.to_s(36) << rand.to_s[2..-1].to_i.to_s(36)
64
+
63
65
  end
64
66
 
65
67
  end
@@ -1,40 +1,65 @@
1
1
  module Formize
2
+
3
+ module Definition
2
4
 
5
+ # Represents a group of fields which can depend on other fields
6
+ class Group < FormElement
7
+ attr_reader :name, :options, :html_options
8
+
9
+ def initialize(form, parent, name=nil, options={})
10
+ super(form, parent, options)
11
+ @name = if name.blank?
12
+ rand.to_s[2..-1].to_i.to_s(36)
13
+ else
14
+ raise ArgumentError.new("Name of group must be written only with a-z and 0-9 and _ (not #{name.inspect})") unless name.to_s == name.to_s.downcase.gsub(/[^a-z0-9\_]/, '')
15
+ name.to_s
16
+ end
17
+ @depend_on = options.delete(:depend_on)
18
+ raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.all_fields[@depend_on].nil?
19
+ @html_options = @options.delete(:html_options)||{}
20
+ end
3
21
 
4
22
 
5
- # Represents a group of fields which can depend on other fields
6
- class FieldSet < FormElement
7
- attr_reader :name, :options, :title, :html_options
8
-
9
- def initialize(form, parent, name=nil, options={})
10
- super(form, parent)
11
- @title = nil
12
- @name = if name.blank?
13
- rand.to_s[2..-1].to_i.to_s(36)
14
- else
15
- raise ArgumentError.new("Name of field_set must be written only with a-z and 0-9 and _ (not #{name.inspect})") unless name.to_s == name.to_s.downcase.gsub(/[^a-z0-9\_]/, '')
16
- @title = name
17
- name.to_s
18
- end
19
- @depend_on = options.delete(:depend_on)
20
- raise ArgumentError.new("A depended element must defined before its dependencies (#{@depended.inspect})") if !@depend_on.blank? and form.fields[@depend_on].nil?
21
- @options = (options.is_a?(Hash) ? options : {})
22
- @html_options = @options.delete(:html_options)||{}
23
- end
23
+ def field_set(name=nil, options={}, &block)
24
+ raise ArgumentError.new("Missing block") unless block_given?
25
+ field_set = self.new_child(FieldSet, name, options)
26
+ yield field_set
27
+ end
24
28
 
29
+ def group(name=nil, options={}, &block)
30
+ raise ArgumentError.new("Missing block") unless block_given?
31
+ name, options = nil, name if name.is_a? Hash
32
+ group = self.new_child(Group, name, options)
33
+ yield group
34
+ end
25
35
 
26
- def field_set(name=nil, options={}, &block)
27
- raise ArgumentError.new("Missing block") unless block_given?
28
- field_set = self.new_child(FieldSet, name, options)
29
- yield field_set
30
- end
36
+ def field(name, options={})
37
+ self.new_child(Field, name, options)
38
+ end
39
+
40
+ def fields(*args)
41
+ options = {}
42
+ options = args.delete_at(-1) if args[-1].is_a?(Hash)
43
+ for name in args
44
+ self.new_child(Field, name, options)
45
+ end
46
+ end
31
47
 
32
- def field(name, options={})
33
- self.new_child(Field, name, options)
34
48
  end
35
49
 
36
- end
37
50
 
51
+ # Represents a set of fields which can depend on other fields
52
+ # It can be used with a title
53
+ class FieldSet < Group
54
+ attr_reader :title
55
+
56
+ def initialize(form, parent, name=nil, options={})
57
+ super(form, parent, name, options)
58
+ @title = name
59
+ end
38
60
 
61
+ end
62
+
63
+ end
39
64
 
40
65
  end
@@ -1,89 +1,103 @@
1
- module Formize
2
-
3
- # Represents an environment for a form or list of fields of one Record
4
- class Form
5
- attr_reader :model, :elements, :record_name, :unique_name, :options, :id
6
- @@count = 0
7
-
8
-
9
- def initialize(name, model, options={})
10
- @name = name
11
- @model = model
12
- @options = options
13
- @elements = []
14
- @@count += 1
15
- @id = @@count.to_s(36)
16
- @unique_name = @options.delete(:unique_name) unless @options[:unique_name].blank?
17
- @unique_name ||= "_formize#{@id}"
18
- @record_name = @model.name.underscore
19
- end
20
-
21
- def field_set(name=nil, options={}, &block)
22
- raise ArgumentError.new("Missing block") unless block_given?
23
- field_set = new_element(FieldSet, name, options)
24
- yield field_set
25
- end
26
-
27
- def field(name, options={})
28
- return new_element(Field, name, options)
29
- end
30
-
31
- # def inner_method_code(options={})
32
- # varh = options[:html_variable] || 'html'
33
- # code = "#{varh} = ''\n"
34
- # for child in children
35
- # code << "#{varh} << " << child.method_call_code << "\n"
36
- # end
37
- # code << "return #{varh}\n"
38
- # return code
39
- # end
40
-
41
- def controller_method_name
42
- @options[:controller_method_name] || "formize_#{model.underscore}"
43
- end
44
-
45
- def view_method_name
46
- @options[:method_name] || "_form_#{model.underscore}"
47
- end
48
-
49
- def action_name
50
- @options[:action_name] || :formize
51
- end
52
-
53
- # def methodics
54
- # return elements.collect{|e| e.methodics}.flatten
55
- # end
56
-
57
- def mono_choices
58
- return elements.collect{|e| e.mono_choices}.flatten
59
- end
60
-
61
- def fields
62
- return elements.inject(HashWithIndifferentAccess.new){|h, e| h.merge!(e.fields)}
63
- end
64
-
65
- def dependents
66
- return elements.collect{|e| e.dependents}.flatten
67
- end
68
-
69
- def all_elements
70
- return elements.collect{|e| e.all_elements}.flatten
71
- end
72
-
73
- def dependents_on(element)
74
- return elements.collect{|e| e.dependents_on(element)}.flatten
75
- end
76
1
 
2
+ module Formize
77
3
 
78
- private
4
+ module Definition
5
+ # Represents an environment for a form or list of fields of one Record
6
+ class Form
7
+ attr_reader :elements, :model, :name, :record_name, :unique_name, :options, :id
8
+ @@count = 0
9
+
10
+
11
+ def initialize(name, model, options={})
12
+ @name = name
13
+ @model = model
14
+ @options = options
15
+ @elements = []
16
+ @@count += 1
17
+ @id = @@count.to_s(36)
18
+ @unique_name = @options.delete(:unique_name) unless @options[:unique_name].blank?
19
+ @unique_name ||= "_formize#{@id}"
20
+ @record_name = @model.name.underscore
21
+ end
22
+
23
+ def field_set(name=nil, options={}, &block)
24
+ raise ArgumentError.new("Missing block") unless block_given?
25
+ field_set = new_element(FieldSet, name, options)
26
+ yield field_set
27
+ end
28
+
29
+ def group(name, options={}, &block)
30
+ raise ArgumentError.new("Missing block") unless block_given?
31
+ name, options = nil, name if name.is_a? Hash
32
+ group = new_element(Group, name, options)
33
+ yield group
34
+ end
35
+
36
+ def field(name, options={})
37
+ return new_element(Field, name, options)
38
+ end
39
+
40
+ def fields(*args)
41
+ options = {}
42
+ options = args.delete_at(-1) if args[-1].is_a?(Hash)
43
+ for name in args
44
+ new_element(Field, name, options)
45
+ end
46
+ end
47
+
48
+
49
+ # protected
50
+
51
+ def controller_method_name
52
+ @options[:controller_method_name] || "formize_#{model.underscore}"
53
+ end
54
+
55
+ def view_method_name
56
+ @options[:method_name] || "_form_#{model.underscore}"
57
+ end
58
+
59
+ def action_name
60
+ @options[:action_name] || :formize
61
+ end
62
+
63
+ def mono_choices
64
+ return elements.collect{|e| e.mono_choices}.flatten
65
+ end
66
+
67
+ def all_fields
68
+ return elements.inject(HashWithIndifferentAccess.new){|h, e| h.merge!(e.all_fields)}
69
+ end
70
+
71
+ def dependents
72
+ return elements.collect{|e| e.dependents}.flatten
73
+ end
74
+
75
+ def all_elements
76
+ return elements.collect{|e| e.all_elements}.flatten
77
+ end
78
+
79
+ def dependents_on(element)
80
+ return elements.collect{|e| e.dependents_on(element)}.flatten
81
+ end
82
+
83
+ def shown_if(element)
84
+ return elements.collect{|e| e.shown_if(element)}.flatten
85
+ end
86
+
87
+ def hidden_if(element)
88
+ return elements.collect{|e| e.hidden_if(element)}.flatten
89
+ end
90
+
91
+
92
+ private
93
+
94
+ def new_element(klass, *args)
95
+ raise ArgumentError.new("Bad child type: #{klass.name} (#{klass.ancestors.inspect}). Must be an Formize::Definition::FormElement") unless klass < Formize::Definition::FormElement # klass.ancestors.include? Formize::FormElement
96
+ element = klass.new(self, nil, *args)
97
+ @elements << element
98
+ return element
99
+ end
79
100
 
80
- def new_element(klass, *args)
81
- raise ArgumentError.new("Bad child type (#{klass.name}). Must be an Formize::FormElement") unless klass < FormElement
82
- element = klass.new(self, nil, *args)
83
- @elements << element
84
- return element
85
101
  end
86
-
87
102
  end
88
-
89
103
  end