formize 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. data/.travis.yml +1 -1
  2. data/Gemfile +3 -1
  3. data/README.rdoc +7 -0
  4. data/VERSION +1 -1
  5. data/ci/Gemfile.rails-3.0.x +2 -0
  6. data/ci/{Gemfile.rails-2.3.x → Gemfile.rails-3.1.x} +3 -1
  7. data/formize.gemspec +82 -6
  8. data/lib/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  9. data/lib/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  10. data/lib/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  11. data/lib/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  12. data/lib/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  13. data/lib/assets/images/ui-bg_glass_75_ffffff_1x400.png +0 -0
  14. data/lib/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  15. data/lib/assets/images/ui-bg_inset-soft_95_fef1ec_1x100.png +0 -0
  16. data/lib/assets/images/ui-icons_222222_256x240.png +0 -0
  17. data/lib/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  18. data/lib/assets/images/ui-icons_454545_256x240.png +0 -0
  19. data/lib/assets/images/ui-icons_888888_256x240.png +0 -0
  20. data/lib/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
  21. data/lib/assets/javascripts/formize.js +238 -340
  22. data/lib/assets/javascripts/jquery.ui.formize.js +231 -0
  23. data/lib/assets/javascripts/locales/jquery.ui.datepicker-af.js +23 -0
  24. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ar.js +24 -0
  25. data/lib/assets/javascripts/locales/jquery.ui.datepicker-az.js +23 -0
  26. data/lib/assets/javascripts/locales/jquery.ui.datepicker-bg.js +24 -0
  27. data/lib/assets/javascripts/locales/jquery.ui.datepicker-bs.js +23 -0
  28. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ca.js +23 -0
  29. data/lib/assets/javascripts/locales/jquery.ui.datepicker-cs.js +23 -0
  30. data/lib/assets/javascripts/locales/jquery.ui.datepicker-da.js +23 -0
  31. data/lib/assets/javascripts/locales/jquery.ui.datepicker-de-CH.js +23 -0
  32. data/lib/assets/javascripts/locales/jquery.ui.datepicker-de.js +23 -0
  33. data/lib/assets/javascripts/locales/jquery.ui.datepicker-el.js +23 -0
  34. data/lib/assets/javascripts/locales/jquery.ui.datepicker-en-GB.js +23 -0
  35. data/lib/assets/javascripts/locales/jquery.ui.datepicker-eo.js +23 -0
  36. data/lib/assets/javascripts/locales/jquery.ui.datepicker-es.js +23 -0
  37. data/lib/assets/javascripts/locales/jquery.ui.datepicker-et.js +23 -0
  38. data/lib/assets/javascripts/locales/jquery.ui.datepicker-eu.js +23 -0
  39. data/lib/assets/javascripts/locales/jquery.ui.datepicker-fa.js +23 -0
  40. data/lib/assets/javascripts/locales/jquery.ui.datepicker-fi.js +23 -0
  41. data/lib/assets/javascripts/locales/jquery.ui.datepicker-fo.js +23 -0
  42. data/lib/assets/javascripts/locales/jquery.ui.datepicker-fr-CH.js +23 -0
  43. data/lib/assets/javascripts/locales/jquery.ui.datepicker-fr.js +23 -0
  44. data/lib/assets/javascripts/locales/jquery.ui.datepicker-he.js +23 -0
  45. data/lib/assets/javascripts/locales/jquery.ui.datepicker-hr.js +23 -0
  46. data/lib/assets/javascripts/locales/jquery.ui.datepicker-hu.js +23 -0
  47. data/lib/assets/javascripts/locales/jquery.ui.datepicker-hy.js +23 -0
  48. data/lib/assets/javascripts/locales/jquery.ui.datepicker-id.js +23 -0
  49. data/lib/assets/javascripts/locales/jquery.ui.datepicker-is.js +23 -0
  50. data/lib/assets/javascripts/locales/jquery.ui.datepicker-it.js +23 -0
  51. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ja.js +23 -0
  52. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ko.js +23 -0
  53. data/lib/assets/javascripts/locales/jquery.ui.datepicker-lt.js +23 -0
  54. data/lib/assets/javascripts/locales/jquery.ui.datepicker-lv.js +23 -0
  55. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ms.js +23 -0
  56. data/lib/assets/javascripts/locales/jquery.ui.datepicker-nl-BE.js +23 -0
  57. data/lib/assets/javascripts/locales/jquery.ui.datepicker-nl.js +23 -0
  58. data/lib/assets/javascripts/locales/jquery.ui.datepicker-no.js +23 -0
  59. data/lib/assets/javascripts/locales/jquery.ui.datepicker-pl.js +23 -0
  60. data/lib/assets/javascripts/locales/jquery.ui.datepicker-pt-BR.js +23 -0
  61. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ro.js +26 -0
  62. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ru.js +23 -0
  63. data/lib/assets/javascripts/locales/jquery.ui.datepicker-sk.js +23 -0
  64. data/lib/assets/javascripts/locales/jquery.ui.datepicker-sl.js +24 -0
  65. data/lib/assets/javascripts/locales/jquery.ui.datepicker-sq.js +23 -0
  66. data/lib/assets/javascripts/locales/jquery.ui.datepicker-sr-SR.js +23 -0
  67. data/lib/assets/javascripts/locales/jquery.ui.datepicker-sr.js +23 -0
  68. data/lib/assets/javascripts/locales/jquery.ui.datepicker-sv.js +23 -0
  69. data/lib/assets/javascripts/locales/jquery.ui.datepicker-ta.js +23 -0
  70. data/lib/assets/javascripts/locales/jquery.ui.datepicker-th.js +23 -0
  71. data/lib/assets/javascripts/locales/jquery.ui.datepicker-tr.js +23 -0
  72. data/lib/assets/javascripts/locales/jquery.ui.datepicker-uk.js +23 -0
  73. data/lib/assets/javascripts/locales/jquery.ui.datepicker-vi.js +23 -0
  74. data/lib/assets/javascripts/locales/jquery.ui.datepicker-zh-CN.js +23 -0
  75. data/lib/assets/javascripts/locales/jquery.ui.datepicker-zh-HK.js +23 -0
  76. data/lib/assets/javascripts/locales/jquery.ui.datepicker-zh-TW.js +23 -0
  77. data/lib/assets/stylesheets/formize.css +20 -0
  78. data/lib/assets/stylesheets/jquery-ui.css +568 -0
  79. data/lib/formize/action_pack.rb +5 -5
  80. data/lib/formize/definition/field.rb +1 -1
  81. data/lib/formize/form_helper.rb +91 -3
  82. data/lib/formize/generator.rb +83 -109
  83. data/lib/generators/formize/install/install_generator.rb +25 -1
  84. metadata +103 -11
@@ -1,6 +1,34 @@
1
1
  module Formize
2
2
  module FormHelper
3
3
 
4
+ # Code picked from Justin French's formtastic gem
5
+ FIELD_ERROR_PROC = proc do |html_tag, instance_tag|
6
+ html_tag
7
+ end
8
+
9
+ def with_custom_field_error_proc(&block)
10
+ default_field_error_proc = ::ActionView::Base.field_error_proc
11
+ ::ActionView::Base.field_error_proc = FIELD_ERROR_PROC
12
+ yield
13
+ ensure
14
+ ::ActionView::Base.field_error_proc = default_field_error_proc
15
+ end
16
+
17
+
18
+
19
+ # Include all stylesheets, javascripts and locales
20
+ # For Rails 3.0, not needed in Rails 3.1
21
+ def formize_include_tag(options={})
22
+ options[:locale] ||= I18n.locale
23
+ html = ""
24
+ html << javascript_include_tag('jquery.ui.formize')
25
+ html << javascript_include_tag('locales/jquery.ui.datepicker-' + locale.to_s)
26
+ html << javascript_include_tag('formize')
27
+ html << stylesheet_link_tag('jquery-ui')
28
+ html << stylesheet_link_tag('formize') unless options[:skip_stylesheet]
29
+ return html.html_safe
30
+ end
31
+
4
32
  # Generates a form with all its fields as defined in controller.
5
33
  # If no name is given, it uses the name of the controller to find the corresponding model
6
34
  def formize_form(*args)
@@ -23,7 +51,14 @@ module Formize
23
51
  def hard_content_tag(name, options={}, escape=true, &block)
24
52
  content = ''
25
53
  yield content
26
- return content_tag(name, content, options, escape)
54
+ return content_tag(name, content.html_safe, options, escape)
55
+ end
56
+
57
+ # Permits to create a submit button well named for the given record
58
+ def submit_for(record, value=nil, options={})
59
+ value, options = nil, value if value.is_a?(Hash)
60
+ value ||= ::I18n.translate("helpers.submit.#{record.new_record? ? 'create' : 'update'}", :model=>record.class.model_name.human, :record=>record.class.model_name.human.mb_chars.downcase)
61
+ submit_tag(value, options.reverse_merge(:id => "#{record.class.name.underscore}_submit"))
27
62
  end
28
63
 
29
64
  # Returns a list of radio buttons for specified attribute (identified by +method+)
@@ -49,10 +84,63 @@ module Formize
49
84
  end
50
85
  html = ""
51
86
  html << hidden_field(object_name, method, input_options)
52
- html << tag(:input, :type=>:text, "data-unroll"=>url_for(choices), "data-value-container"=>"#{object_name}_#{method}", :value=>label.call(object.send(method.to_s.gsub(/_id$/, ''))), :size=>html_options.delete(:size)||32)
53
- return content_tag(:span, html, html_options)
87
+ html << tag(:input, :type=>:text, "data-unroll"=>url_for(choices.merge(:format=>:json)), "data-value-container"=>"#{object_name}_#{method}", :value=>label.call(object.send(method.to_s.gsub(/_id$/, ''))), :size=>html_options.delete(:size)||32)
88
+ return content_tag(:span, html.html_safe, html_options)
54
89
  end
55
90
 
91
+
92
+ # Returns a text field for selecting a Date with a hidden field containing
93
+ # the well formatted date
94
+ # Options are:
95
+ # - +:format+: If +format+ is a +String+ it specify date format using a little subset of strftime options
96
+ # %d, %j, %a, %A, %m, %b, %B, %y and %Y
97
+ # else if +format+ is a +Symbol+ it uses I18n to find format
98
+ def date_field(object_name, method, options = {})
99
+ object = instance_variable_get("@#{object_name}")
100
+ format = options[:format]||:default
101
+ raise ArgumentError.new("Option :format must be a Symbol referencing a translation 'date.formats.<format>'")unless format.is_a?(Symbol)
102
+ if localized_value = object.send(method)
103
+ localized_value = I18n.localize(localized_value, :format=>format)
104
+ end
105
+ format = I18n.translate('date.formats.'+format.to_s)
106
+ conv = {
107
+ 'dd' => '%d',
108
+ 'oo' => '%j',
109
+ 'D' => '%a',
110
+ 'DD' => '%A',
111
+ 'mm' => '%m',
112
+ 'M' => '%b',
113
+ 'MM' => '%B',
114
+ 'y' => '%y',
115
+ 'yy' => '%Y'
116
+ }
117
+ conv.each{|js, rb| format.gsub!(rb, js)}
118
+ html = ""
119
+ html << hidden_field(object_name, method)
120
+ html << tag(:input, :type=>:text, "data-datepicker"=>"#{object_name}_#{method}", "data-date-format"=>format, :value=>localized_value, "data-locale"=>I18n.locale, :size=>options.delete(:size)||10)
121
+ return html
122
+ end
123
+
124
+
125
+ # Returns a text field for selecting a Date with hour
126
+ # with a hidden field containing the well formatted datetime
127
+ def datetime_field(object_name, method, options = {})
128
+ object = instance_variable_get("@#{object_name}")
129
+ html = ""
130
+ html << hidden_field(object_name, method)
131
+ html << tag(:input, :type=>:text, "data-datepicker"=>"#{object_name}_#{method}", :size=>options.delete(:size)||10)
132
+ return html
133
+ end
134
+
135
+
136
+ # Returns a text area which can be resized in the south-east corner
137
+ # Works exactly the same as +textarea+
138
+ def resizable_text_area(object_name, method, options = {})
139
+ # options["data-resize-in"] = "ri"+rand.to_s[2..-1].to_i.to_s(36)
140
+ # return content_tag(:div, text_area(object_name, method, options), :id=>options["data-resize-in"])
141
+ options["data-resizable"] = "true"
142
+ return text_area(object_name, method, options)
143
+ end
56
144
 
57
145
 
58
146
  end
@@ -62,6 +62,9 @@ module Formize
62
62
  event << " #{record_name}.#{df.name} = " << (df.reflection.nil? ? "params[:#{df.input_id}]" : "#{df.reflection.class_name}.find_by_id(params[:#{df.input_id}])") << "\n"
63
63
  # locals[df.name.to_sym] = Code.new(df.name)
64
64
  end
65
+ if dependent.is_a?(Formize::Field) and dependent.reflection
66
+ event << " #{record_name}.#{dependent.reflection.primary_key_name} = params[:selected].to_i if params[:selected]\n"
67
+ end
65
68
  event << " render(:inline=>'<%=#{dependent.prototype}-%>', :locals=>#{locals.inspect})\n"
66
69
  event << "end\n"
67
70
  end
@@ -73,7 +76,7 @@ module Formize
73
76
  code << "end\n"
74
77
  code.gsub!(/end\s*if/, 'elsif')
75
78
  # raise code
76
- # list = code.split("\n"); list.each_index{|x| puts((x+1).to_s.rjust(4)+": "+list[x])}
79
+ list = code.split("\n"); list.each_index{|x| puts((x+1).to_s.rjust(4)+": "+list[x])}
77
80
  return code
78
81
  end
79
82
 
@@ -96,23 +99,39 @@ module Formize
96
99
  code << "def #{form.options[:view_fields_method_name]}(#{form.record_name}=nil)\n"
97
100
  code << " #{form.record_name} = @#{form.record_name} unless #{form.record_name}.is_a?(#{form.model.name})\n"
98
101
  code << " #{varh} = ''\n"
102
+ code << " with_custom_field_error_proc do\n"
99
103
  for element in form.elements
100
- code << view_method_call(element, varh).strip.gsub(/^/, ' ') << "\n" #
101
- # code << " #{varh} << " << element.method_call_code.gsub(/^/, ' ').strip << "\n"
104
+ code << view_method_call(element, varh).strip.gsub(/^/, ' ') << "\n"
102
105
  end
103
- code << " return #{varh}\n"
106
+ code << " end\n"
107
+ code << " return #{varh}.html_safe\n"
104
108
  code << "end\n"
105
109
 
106
110
  code << "\n"
107
111
  code << "def #{form.options[:view_form_method_name]}(#{form.record_name}=nil)\n"
108
112
  code << " #{form.record_name} = @#{form.record_name} unless #{form.record_name}.is_a?(#{form.model.name})\n"
109
- code << " return form_for(#{form.record_name}) do\n"
110
- code << " #{form.options[:view_fields_method_name]}(#{form.record_name})\n"
113
+ code << " #{varh} = ''\n"
114
+ code << " if #{form.record_name}.errors.any?\n"
115
+ code << " #{varh} << hard_content_tag(:div, :class=>'errors') do |fe|\n"
116
+ code << " fe << content_tag(:h2, ::I18n.translate('activerecord.errors.template.body', :count=>#{form.record_name}.errors.size))\n"
117
+ code << " if #{form.record_name}.errors[:base].any?\n"
118
+ code << " fe << '<ul>'\n"
119
+ code << " for error in #{form.record_name}.errors[:base]\n"
120
+ code << " fe << content_tag(:li, error)\n"
121
+ code << " end\n"
122
+ code << " fe << '</ul>'\n"
123
+ code << " end\n"
124
+ code << " end\n"
125
+ code << " end\n"
126
+ code << " #{varh} << form_for(#{form.record_name}, :html=>(params[:dialog] ? {'data-dialog'=>params[:dialog]} : {})) do\n"
127
+ code << " concat(#{form.options[:view_fields_method_name]}(#{form.record_name}))\n"
128
+ code << " concat(submit_for(#{form.record_name}))\n"
111
129
  code << " end\n"
130
+ code << " return #{varh}.html_safe\n"
112
131
  code << "end\n"
113
132
 
114
133
  # raise code
115
- # list = code.split("\n"); list.each_index{|x| puts((x+1).to_s.rjust(4)+": "+list[x])}
134
+ list = code.split("\n"); list.each_index{|x| puts((x+1).to_s.rjust(4)+": "+list[x])}
116
135
  return code
117
136
  end
118
137
 
@@ -155,7 +174,7 @@ module Formize
155
174
  code = "def #{element.prototype}\n"
156
175
  code << " #{varh} = ''\n"
157
176
  code << view_partial_code(element, varh).strip.gsub(/^/, ' ') << "\n"
158
- code << " return #{varh}\n"
177
+ code << " return #{varh}.html_safe\n"
159
178
  code << "end\n"
160
179
  return code
161
180
  end
@@ -171,14 +190,14 @@ module Formize
171
190
  end
172
191
 
173
192
  def wrapper_attrs(element)
174
- html_options = (element.respond_to?(:html_options) ? element.html_options : {})
193
+ html_options = (element.respond_to?(:html_options) ? element.html_options.dup : {})
175
194
  html_options[:id] = element.html_id
176
195
  if @partials.include?(element)
177
196
  url = {:controller => controller.controller_name.to_sym, :action=>form.action_name.to_sym, :refresh=>element.html_id}
178
- for depended in element.dependeds
179
- df = form.fields[depended[:name]]
180
- url[df.input_id.to_sym] = Code.new(df.reflection.nil? ? df.name : "#{df.name}.id")
181
- end
197
+ # for depended in element.dependeds
198
+ # df = form.fields[depended[:name]]
199
+ # # url[df.input_id.to_sym] = Code.new(df.reflection.nil? ? df.name : "#{df.name}.id")
200
+ # end
182
201
  html_options["data-refresh"] = Code.new("url_for(#{url.inspect})")
183
202
  end
184
203
  special_method = "#{element.class.name.split('::')[-1].underscore}_#{__method__}".to_sym
@@ -206,43 +225,6 @@ module Formize
206
225
  return code
207
226
  end
208
227
 
209
- # def field_set_view_method_code(field_set, varh='html')
210
- # code = "def #{field_set.prototype}\n"
211
- # code << " #{varh} = ''\n"
212
- # code << field_set_view_partial_code(field_set, varh).strip.gsub(/^/, ' ') << "\n"
213
- # code << " return #{varh}\n"
214
- # code << "end\n"
215
- # return code
216
- # end
217
-
218
- # def field_set_view_method_call(field_set, varh='varh')
219
- # code = ""
220
- # call = if @partials.include?(field_set)
221
- # "#{varh} << #{field_set.prototype}\n"
222
- # else
223
- # field_set_view_partial_code(field_set, varh).strip << "\n"
224
- # end
225
-
226
- # if field_set.depend_on
227
- # depended_field = form.fields[field_set.depend_on]
228
- # code << "#{field_set.depend_on} = #{form.record_name}.#{depended_field.name}\n"
229
- # if ref = depended_field.reflection
230
- # code << "#{field_set.depend_on} ||= #{field_datasource(depended_field)}.first\n"
231
- # end
232
- # code << "if #{field_set.depend_on}\n"
233
- # code << call.strip.gsub(/^/, ' ') << "\n"
234
- # code << "else\n"
235
- # opt = {:id=>field_set.html_id, :class=>"waiting", "data-refresh"=>Code.new("url_for(:controller=>:#{controller.controller_name}, :action=>:#{form.action_name}, :refresh=>'#{field_set.html_id}')")}
236
- # code << " #{varh} << tag(:div, #{opt.inspect})\n"
237
-
238
- # code << "end\n"
239
- # else
240
- # code = call
241
- # end
242
-
243
- # return code
244
- # end
245
-
246
228
  #####################################################################################
247
229
  # F I E L D M E T H O D S #
248
230
  #####################################################################################
@@ -251,70 +233,49 @@ module Formize
251
233
  input_attrs = (field.options[:input_options].is_a?(Hash) ? field.options[:input_options] : {})
252
234
  deps = form.dependents_on(field)
253
235
  if deps.size > 0
254
- input_attrs["data-dependents"] = deps.collect{|d| d.html_id}.join(',')
236
+ input_attrs["data-dependents"] = deps.collect{|d| "##{d.html_id}"}.join(',')
255
237
  end
256
238
 
257
239
  # Initialize html attributes
258
240
  html_options = wrapper_attrs(field)
259
241
 
260
242
  varc = field.html_id
261
- code = "#{varh} << hard_content_tag(:div, #{html_options.inspect}) do |#{varc}|\n"
243
+ code = "#{varh} << hard_content_tag(:table, #{html_options.inspect}) do |#{varc}|\n"
244
+ code << " #{varc} << '<tr><td class=\"label\">'\n"
262
245
  code << " #{varc} << label(:#{form.record_name}, :#{field.name}, nil, :class=>'attr')\n"
246
+ code << " #{varc} << '</td><td class=\"input\">'\n"
263
247
  code << " #{form.record_name}.#{field.name} ||= #{field.default.inspect}\n" if field.default
264
248
  code << self.send("field_#{field.type}_input", field, input_attrs, varc).strip.gsub(/^/, ' ') << "\n"
249
+ code << " if @#{form.record_name}.errors['#{field.name}'].any?\n"
250
+ code << " #{varc} << '<ul class=\"inline-errors\">'\n"
251
+ code << " for error in @#{form.record_name}.errors['#{field.name}']\n"
252
+ code << " #{varc} << content_tag(:li, error)\n"
253
+ code << " end\n"
254
+ code << " #{varc} << '</ul>'\n"
255
+ code << " end\n"
256
+ code << " #{varc} << '</td></tr>'\n"
265
257
  code << "end\n"
266
258
  return code
267
259
  end
268
260
 
269
- # def field_view_method_code(field, varh='html')
270
- # code = "def #{field.prototype}\n"
271
- # code << " #{varh} = ''\n"
272
- # code << field_view_partial_code(field, varh).strip.gsub(/^/, ' ') << "\n"
273
- # code << " return #{varh}\n"
274
- # code << "end\n"
275
- # return code
276
- # end
277
-
278
- # def field_view_method_call(field, varh='varh')
279
- # code = ""
280
- # call = if @partials.include?(field)
281
- # "#{varh} << #{field.prototype}\n"
282
- # else
283
- # field_view_partial_code(field, varh).strip << "\n"
284
- # end
285
-
286
- # if field.depend_on
287
- # depended_field = form.fields[field.depend_on]
288
- # code << "#{field.depend_on} = #{form.record_name}.#{depended_field.name}\n"
289
- # code << "if #{field.depend_on}\n"
290
- # code << call.strip.gsub(/^/, ' ') << "\n"
291
- # code << "else\n"
292
- # attrs = field_wrapper_attrs(field)
293
- # attrs[:class] = "#{attrs[:class]} waiting".strip
294
- # code << " #{varh} << tag(:div, #{attrs.inspect})\n"
295
- # code << "end\n"
296
- # else
297
- # code = call
298
- # end
299
-
300
- # return code
301
- # end
302
-
303
-
304
261
  def field_datasource(field)
305
262
  source = field.source
306
263
  source = Formize.default_source unless [Array, String, Symbol].include?(source.class)
307
264
  if source.is_a?(Array)
308
265
  return "#{source[0]}.#{field.choices}"
309
266
  elsif source == :foreign_class
267
+ # return field.reflection.class_name if field.choices.to_s == "all"
310
268
  return "#{field.reflection.class_name}.#{field.choices}"
311
269
  elsif source == :class
270
+ # return form.model.name if field.choices.to_s == "all"
312
271
  return "#{form.model.name}.#{field.choices}"
313
272
  else
314
273
  return "#{source}.#{field.choices}"
315
274
  end
316
275
  end
317
276
 
277
+ # Returns the name of the class of the source
278
+ #
318
279
  def field_datasource_class_name(field)
319
280
  source = field.source
320
281
  source = Formize.default_source unless [Array, String, Symbol].include?(source.class)
@@ -333,9 +294,10 @@ module Formize
333
294
  end
334
295
 
335
296
  def field_wrapper_attrs(field, html_options={})
336
- html_options[:class] = "field #{html_options[:class]}".strip
297
+ html_options[:class] = "fz field #{html_options[:class]}".strip
337
298
  html_options[:class] = "#{html_options[:class]} #{field.type.to_s.gsub('_', '-')}".strip
338
299
  html_options[:class] = "#{html_options[:class]} required".strip if field.required
300
+ html_options[:class] = Code.new("\"#{html_options[:class]}\#{' invalid' if @#{field.form.record_name}.errors['#{field.name}'].any?}\"")
339
301
  return html_options
340
302
  end
341
303
 
@@ -356,12 +318,13 @@ module Formize
356
318
  end
357
319
 
358
320
  def field_date_input(field, attrs={}, varc='varc')
359
- attrs[:size] ||= 16
321
+ attrs[:size] ||= 10
360
322
  return "#{varc} << date_field(:#{field.record_name}, :#{field.method}, #{attrs.inspect})\n"
361
323
  end
362
324
 
363
325
  def field_datetime_input(field, attrs={}, varc='varc')
364
326
  attrs[:size] ||= 16
327
+ # TODO define Date format
365
328
  return "#{varc} << datetime_field(:#{field.record_name}, :#{field.method}, #{attrs.inspect})\n"
366
329
  end
367
330
 
@@ -395,9 +358,9 @@ module Formize
395
358
  def field_mono_choice_input(field, attrs={}, varc='varc')
396
359
  source_model = field_datasource_class_name(field).constantize
397
360
  reflection = source_model.reflections[field.choices]
398
- if reflection.nil?
399
- raise Exception.new("#{source_model.name} must have a reflection :#{field.choices}.")
400
- end
361
+ # if reflection.nil?
362
+ # raise Exception.new("#{source_model.name} must have a reflection :#{field.choices}.")
363
+ # end
401
364
  count = "#{field.choices}_count"
402
365
  select_first_if_empty = " #{record_name}.#{field.name} ||= #{field_datasource(field)}.first\n"
403
366
  code = "#{count} = #{field_datasource(field)}.count\n"
@@ -406,7 +369,7 @@ module Formize
406
369
  code << "elsif (#{count} <= #{Formize.radio_count_max})\n"
407
370
  code << select_first_if_empty
408
371
  code << field_mono_radio_input(field, attrs, varc).strip.gsub(/^/, ' ') << "\n"
409
- if reflection.options[:finder_sql].nil?
372
+ if !reflection or (reflection and reflection.options[:finder_sql].nil?)
410
373
  code << "elsif (#{count} <= #{Formize.select_count_max})\n"
411
374
  code << select_first_if_empty
412
375
  code << field_mono_select_input(field, attrs, varc).strip.gsub(/^/, ' ') << "\n"
@@ -432,7 +395,7 @@ module Formize
432
395
  new_item_url[k] = Code.new(v) if v.is_a?(String)
433
396
  end
434
397
  edit_item_url = {} unless edit_item_url.is_a? Hash
435
- if field.method.to_s.match(/_id$/) and refl = form.model.reflections[field.method.to_s[0..-4].to_sym]
398
+ if field.method.to_s.match(/_id$/) and refl = field.reflection # form.model.reflections[field.method.to_s[0..-4].to_sym]
436
399
  new_item_url[:controller] ||= refl.class_name.underscore.pluralize
437
400
  edit_item_url[:controller] ||= new_item_url[:controller]
438
401
  end
@@ -440,7 +403,7 @@ module Formize
440
403
  edit_item_url[:action] ||= :edit
441
404
  data = field.options.delete(:update)||field.html_id
442
405
  html_options = {"data-add-item"=>data, :class=>"icon im-new"}
443
- code << "#{varc} << content_tag(:span, content_tag(:span, link_to(tg(:new), #{new_item_url.inspect}, #{html_options.inspect}).html_safe, :class=>:tool).html_safe, :class=>\"toolbar mini-toolbar\") if authorized?(#{new_item_url.inspect})\n"
406
+ code << "#{varc} << content_tag(:span, content_tag(:span, link_to(::I18n.translate('form.new'), #{new_item_url.inspect}, #{html_options.inspect}).html_safe, :class=>:tool).html_safe, :class=>\"toolbar mini-toolbar\")\n" if authorized?(#{new_item_url.inspect})
444
407
  end
445
408
  return code
446
409
  end
@@ -461,7 +424,7 @@ module Formize
461
424
  df = form.fields[depended[:name]]
462
425
  url[df.input_id.to_sym] = Code.new(df.reflection.nil? ? df.name : "#{df.name}.id")
463
426
  end
464
- return "#{varc} << unroll(:#{field.record_name}, :#{field.method}, url_for(#{url.inspect}), #{options.inspect}, #{attrs.inspect})"
427
+ return "#{varc} << unroll(:#{field.record_name}, :#{field.method}, #{url.inspect}, #{options.inspect}, #{attrs.inspect})"
465
428
  end
466
429
 
467
430
  def field_string_input(field, attrs={}, varc='varc')
@@ -477,7 +440,7 @@ module Formize
477
440
  attrs[:cols] ||= 40
478
441
  attrs[:rows] ||= 3
479
442
  attrs[:class] = "#{attrs[:class]} #{attrs[:cols]==80 ? :code : nil}".strip
480
- return "#{varc} << text_area(:#{field.record_name}, :#{field.method}, #{attrs.inspect})\n"
443
+ return "#{varc} << resizable_text_area(:#{field.record_name}, :#{field.method}, #{attrs.inspect})\n"
481
444
  end
482
445
 
483
446
 
@@ -510,11 +473,11 @@ module Formize
510
473
 
511
474
  def mono_choice_search_code(field)
512
475
  source_model = field_datasource_class_name(field).constantize
513
- reflection = source_model.reflections[field.choices]
514
- if reflection.nil?
515
- raise Exception.new("#{source_model.name} must have a reflection :#{field.choices}.")
516
- end
517
- model = reflection.class_name.constantize
476
+ # reflection = source_model.reflections[field.choices]
477
+ # if reflection.nil?
478
+ # raise Exception.new("#{source_model.name} must have a reflection :#{field.choices}.")
479
+ # end
480
+ model = field.reflection.class_name.constantize #reflection.class_name.constantize
518
481
  foreign_record = model.name.underscore
519
482
  foreign_records = "#{source_model.name.underscore}_#{field.choices}"
520
483
  options = field.options
@@ -550,12 +513,11 @@ module Formize
550
513
  end
551
514
 
552
515
  select = (model.table_name+".id AS id, "+attributes_hash.collect{|k,v| v+" AS "+k}.join(", ")).inspect
553
- joins = options[:joins] ? ", :joins=>"+options[:joins].inspect : ""
554
516
 
555
517
  code = ""
556
518
  code << "conditions = [#{query.join(' AND ').inspect+parameters}]\n"
557
- code << "search = params[:search]\n"
558
- code << "words = search.lower.split(/[\\s\\,]+/)\n"
519
+ code << "search = params[:term]\n"
520
+ code << "words = search.to_s.mb_chars.downcase.strip.normalize.split(/[\\s\\,]+/)\n"
559
521
  code << "if words.size > 0\n"
560
522
  code << " conditions[0] << '#{' AND ' if query.size>0}('\n"
561
523
  code << " words.each_index do |index|\n"
@@ -572,8 +534,14 @@ module Formize
572
534
  code << " end\n"
573
535
  code << " conditions[0] << ')'\n"
574
536
  code << "end\n"
575
- order = ", :order=>"+attributes.collect{|key| "#{key[0]} ASC"}.join(', ').inspect
576
- limit = ", :limit=>"+(options[:limit]||12).to_s
537
+
538
+ # joins = options[:joins] ? ", :joins=>"+options[:joins].inspect : ""
539
+ # order = ", :order=>"+attributes.collect{|key| "#{key[0]} ASC"}.join(', ').inspect
540
+ # limit = ", :limit=>"+(options[:limit]||80).to_s
541
+ joins = options[:joins] ? ".joins(#{options[:joins].inspect})" : ""
542
+ order = ".order("+attributes.collect{|key| "#{key[0]} ASC"}.join(', ').inspect+")"
543
+ limit = ".limit(#{options[:limit]||80})"
544
+
577
545
  partial = options[:partial]
578
546
 
579
547
  html = "<ul><%for #{foreign_record} in #{foreign_records}-%><li id='<%=#{foreign_record}.id-%>'>"
@@ -586,8 +554,14 @@ module Formize
586
554
  end
587
555
  html << '</li><%end-%></ul>'
588
556
 
589
- code << "#{foreign_records} = #{field_datasource(field)}.find(:all, :conditions=>conditions"+joins+order+limit+")\n"
590
- code << "render :inline=>#{html.inspect}, :locals=>{:#{foreign_records}=>#{foreign_records}, :search=>search}\n"
557
+ # code << "#{foreign_records} = #{field_datasource(field)}.find(:all, :conditions=>conditions"+joins+order+limit+")\n"
558
+ code << "#{foreign_records} = #{field_datasource(field).gsub(/\.all$/, '')}.where(conditions)"+joins+order+limit+"\n"
559
+ # Render HTML is old Style
560
+ code << "respond_to do |format|\n"
561
+ code << " format.html { render :inline=>#{html.inspect}, :locals=>{:#{foreign_records}=>#{foreign_records}, :search=>search} }\n"
562
+ code << " format.json { render :json=>#{foreign_records}.collect{|#{foreign_record}| {:label=>#{foreign_record}.#{field.item_label}, :id=>#{foreign_record}.id}}.to_json }\n"
563
+ code << " format.xml { render :xml=>#{foreign_records}.collect{|#{foreign_record}| {:label=>#{foreign_record}.#{field.item_label}, :id=>#{foreign_record}.id}}.to_xml }\n"
564
+ code << "end\n"
591
565
  return code
592
566
  end
593
567
 
@@ -4,11 +4,35 @@ module Formize
4
4
 
5
5
  class InstallGenerator < ::Rails::Generators::Base
6
6
  source_root File.expand_path('../templates', __FILE__)
7
+ class_option :no_ui, :type => :boolean, :default => false, :desc => "Do not include special jQuery-UI JavaScripts"
8
+ class_option :no_locales, :type => :boolean, :default => false, :desc => "Do not include locales for jQuery-UI date picker"
9
+ class_option :no_stylesheet, :type => :boolean, :default => false, :desc => "Do not include stylesheet of jQuery-UI"
7
10
 
8
11
  unless ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR >= 1
9
12
  def copy_assets
10
13
  copy_file '../../../../assets/javascripts/formize.js', 'public/javascripts/formize.js'
11
- # copy_file '../../../../assets/stylesheets/formize.css', 'public/stylesheets/formize.css'
14
+
15
+ unless options[:no_ui]
16
+ copy_file '../../../../assets/javascripts/jquery.ui.formize.js', 'public/javascripts/jquery.ui.formize.js'
17
+ end
18
+
19
+ unless options[:no_locales]
20
+ for locale in Dir.glob(File.expand_path('../../../../assets/javascripts/locales/*.js', __FILE__))
21
+ file = locale.split(/[\\\/]+/)[-1]
22
+ copy_file "../../../../assets/javascripts/locales/#{file}", "public/javascripts/locales/#{file}"
23
+ end
24
+ end
25
+
26
+ copy_file '../../../../assets/stylesheets/formize.css', 'public/stylesheets/formize.css'
27
+
28
+ unless options[:no_stylesheet]
29
+ copy_file '../../../../assets/stylesheets/jquery-ui.css', 'public/stylesheets/jquery-ui.css'
30
+ for image in Dir.glob(File.expand_path('../../../../assets/images/*.png', __FILE__))
31
+ file = image.split(/[\\\/]+/)[-1]
32
+ copy_file "../../../../assets/images/#{file}", "public/images/#{file}"
33
+ end
34
+ end
35
+
12
36
  end
13
37
  end
14
38