flex_scaffold 0.1.0
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 +4 -0
- data/MIT-LICENSE +20 -0
- data/README +169 -0
- data/Rakefile +116 -0
- data/TODO +23 -0
- data/generators/flex_scaffold/USAGE +16 -0
- data/generators/flex_scaffold/flex_scaffold_generator.rb +434 -0
- data/generators/flex_scaffold/templates/_form.rhtml +1 -0
- data/generators/flex_scaffold/templates/_index.rmxml +210 -0
- data/generators/flex_scaffold/templates/_list.rhtml +0 -0
- data/generators/flex_scaffold/templates/_list.rmxml +17 -0
- data/generators/flex_scaffold_resource/USAGE +36 -0
- data/generators/flex_scaffold_resource/flex_scaffold_resource_generator.rb +81 -0
- data/generators/flex_scaffold_resource/templates/controller.rb +101 -0
- data/generators/flex_scaffold_resource/templates/index.rhtml +3 -0
- data/generators/flex_scaffold_resource/templates/layout.rhtml +19 -0
- data/init.rb +29 -0
- data/install.rb +1 -0
- data/lib/action_view_helper.rb +49 -0
- data/lib/actionscript_helper.rb +81 -0
- data/lib/config.rb +49 -0
- data/lib/flex_scaffold_plugin.rb +25 -0
- data/lib/flexobject_view_helper.rb +132 -0
- data/lib/mtag_helper.rb +98 -0
- data/lib/mxml_helper.rb +107 -0
- data/lib/rest_scaffolding.rb +137 -0
- data/lib/validations.rb +180 -0
- data/public/crossdomain.xml +6 -0
- data/public/history.htm +21 -0
- data/public/history.swf +0 -0
- data/public/images/add.gif +0 -0
- data/public/images/arrow_down.gif +0 -0
- data/public/images/arrow_up.gif +0 -0
- data/public/images/create.gif +0 -0
- data/public/images/delete.gif +0 -0
- data/public/images/indicator-small.gif +0 -0
- data/public/images/indicator.gif +0 -0
- data/public/images/read.gif +0 -0
- data/public/images/search.gif +0 -0
- data/public/images/update.gif +0 -0
- data/public/javascripts/flashobject.js +168 -0
- data/public/javascripts/history.js +48 -0
- data/public/playerProductInstall.swf +0 -0
- data/public/stylesheets/default.css +28 -0
- data/tasks/compile_swf.rake +100 -0
- data/tasks/flex_scaffold.rake +38 -0
- data/uninstall.rb +1 -0
- metadata +125 -0
@@ -0,0 +1,434 @@
|
|
1
|
+
require 'rails_generator/generators/components/scaffold/scaffold_generator'
|
2
|
+
|
3
|
+
class FlexScaffoldingSandbox < ScaffoldingSandbox
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def mxml_tags(record, record_name, options={})
|
7
|
+
input_block = options[:input_block] || ""
|
8
|
+
filtered_columns = !options[:exclude].blank? ? record.class.content_columns.reject { |column| options[:exclude].include?(column.name) } : record.class.content_columns
|
9
|
+
filtered_columns.collect{ |column| input_block.call(record_name, column) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def mxml_form(options)
|
13
|
+
Proc.new do |record, column|
|
14
|
+
item = "<mx:FormItem label='#{column.human_name}'>"
|
15
|
+
case column.type
|
16
|
+
when :string, :integer, :decimal, :float
|
17
|
+
item << "<mx:TextInput id='field#{prefix(options)}_#{column.name}' text='#{column.default}'/>"
|
18
|
+
when :date, :datetime, :time, :timestamp
|
19
|
+
item << "<mx:DateField id='field#{prefix(options)}_#{column.name}' yearNavigationEnabled='true'/>"
|
20
|
+
when :text, :textarea
|
21
|
+
item << "<mx:TextArea id='field#{prefix(options)}_#{column.name}'><mx:text/></mx:TextArea>"
|
22
|
+
when :boolean
|
23
|
+
item << "<mx:CheckBox id='field#{prefix(options)}_#{column.name}' selected='#{column.default}'/>"
|
24
|
+
end
|
25
|
+
item << "</mx:FormItem>"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def mxml_as_xml_resource(options)
|
30
|
+
Proc.new { |record, column| "<#{column.name}>{field#{prefix(options)}_#{column.name}.#{text(column.type)}}</#{column.name}>" }
|
31
|
+
end
|
32
|
+
|
33
|
+
def mxml_grid_column
|
34
|
+
Proc.new { |record, column| "<mx:DataGridColumn headerText='#{column.human_name}' dataField='#{column.name}'/>" }
|
35
|
+
end
|
36
|
+
|
37
|
+
def mxml_as_actionscript_form_action(options)
|
38
|
+
if options[:prefix] == 'create'
|
39
|
+
Proc.new { |record, column| "field#{prefix(options)}_#{column.name}.#{text(column.type)} = #{cast(column)};" }
|
40
|
+
else
|
41
|
+
Proc.new { |record, column| "field#{prefix(options)}_#{column.name}.#{text(column.type)} = #{record}_grid.selectedItem.#{column.name};" }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def mxml_as_actionscript_resource_params(options)
|
46
|
+
Proc.new { |record, column| "params['#{record}[#{column.name}]'] = field#{prefix(options)}_#{column.name}.#{text(column.type)};" }
|
47
|
+
end
|
48
|
+
|
49
|
+
def mxml_model_tags(record, record_name, options={})
|
50
|
+
input_block = options[:input_block] || ""
|
51
|
+
filtered_columns = !options[:exclude].blank? ? record.class.content_columns.reject { |column| options[:exclude].include?(column.name) } : record.class.content_columns
|
52
|
+
filtered_columns.collect{ |column| input_block.call(record, column) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Options:
|
56
|
+
# :message text
|
57
|
+
# :on (:save, :create, or :update)
|
58
|
+
|
59
|
+
def mxml_model_validators(options)
|
60
|
+
Proc.new do |record, column|
|
61
|
+
validations = record.class.new_validations.instance_variable_get(:@validations) rescue nil
|
62
|
+
validators = ""
|
63
|
+
|
64
|
+
field_name, trigger_btn = form_field(options, column), form_submit(options)
|
65
|
+
|
66
|
+
# validates_format_of :length, :with => /^\d+(in|cm)/
|
67
|
+
if has_model_validation?(validations, column, :format)
|
68
|
+
validators << <<-MX
|
69
|
+
<mx:RegExpValidator
|
70
|
+
source="{#{field_name}}" property="text"
|
71
|
+
required="#{required?(column.null)}"
|
72
|
+
flags="g" expression="#{validation(validations, column, :format, :with).source}"
|
73
|
+
noMatchError="#{validation(validations, column, :format, :message)}"
|
74
|
+
trigger="{#{field_name}}" triggerEvent="change" />
|
75
|
+
MX
|
76
|
+
end
|
77
|
+
# validates_numericality_of :height_in_meters
|
78
|
+
# validates_numericality_of :age, :only_integer => true
|
79
|
+
if has_model_validation?(validations, column, :numericality)
|
80
|
+
validators << <<-MX
|
81
|
+
<mx:NumberValidator
|
82
|
+
source="{#{field_name}}" property="text"
|
83
|
+
integerError="Enter Integer value"
|
84
|
+
required="#{required?(column.null)}"
|
85
|
+
minValue="" maxValue="#{column.limit}" domain="int"
|
86
|
+
trigger="{#{field_name}}" triggerEvent="change" />
|
87
|
+
MX
|
88
|
+
end
|
89
|
+
# TODO: uniqueness needs to check all the other values in the datagrid
|
90
|
+
if has_model_validation?(validations, column, :uniqueness)
|
91
|
+
validators << <<-MX
|
92
|
+
<!-- Uniqueness not implemented as yet -->
|
93
|
+
MX
|
94
|
+
end
|
95
|
+
# TODO: implement the actionscript to make this work
|
96
|
+
# Checks that one fields equals another
|
97
|
+
if has_model_validation?(validations, column, :confirmation)
|
98
|
+
validators << <<-MX
|
99
|
+
<!-- Confirmation not implemented as yet -->
|
100
|
+
MX
|
101
|
+
end
|
102
|
+
|
103
|
+
# validates_inclusion_of :gender,
|
104
|
+
# :in => %w{ male female },
|
105
|
+
# :message => "should be 'male' or 'female'"
|
106
|
+
# validates_inclusion_of :age,
|
107
|
+
# :in => 0..130,
|
108
|
+
# :message => "should be between 0 and 130"
|
109
|
+
# TODO: implement inclusion
|
110
|
+
if has_model_validation?(validations, column, :inclusion)
|
111
|
+
# use :in as range
|
112
|
+
if validation(validations, column, :inclusion, :in).is_a?(Range)
|
113
|
+
validators << <<-MX
|
114
|
+
<mx:NumberValidator
|
115
|
+
source="{#{field_name}}" property="text"
|
116
|
+
integerError="#{validation(validations, column, :inclusion, :message)}"
|
117
|
+
required="#{required?(column.null)}"
|
118
|
+
minValue="#{min(validations, column, :inclusion)}"
|
119
|
+
maxValue="#{max(validations, column, :inclusion)}"
|
120
|
+
domain="int"
|
121
|
+
trigger="{#{field_name}}" triggerEvent="change" />
|
122
|
+
MX
|
123
|
+
end
|
124
|
+
# use :in as part of a list or regexp
|
125
|
+
if validation(validations, column, :inclusion, :in).is_a?(Array)
|
126
|
+
validators << <<-MX
|
127
|
+
<mx:RegExpValidator
|
128
|
+
source="{#{field_name}}" property="text"
|
129
|
+
required="#{required?(column.null)}"
|
130
|
+
flags="g" expression="#{in_list(validations, column, :inclusion)}"
|
131
|
+
noMatchError="#{validation(validations, column, :inclusion, :message)}"
|
132
|
+
trigger="{#{field_name}}" triggerEvent="change" />
|
133
|
+
MX
|
134
|
+
end
|
135
|
+
end
|
136
|
+
# validates_exclusion_of :genre,
|
137
|
+
# :in => %w{ polka twostep foxtrot },
|
138
|
+
# :message => "no wild music allowed"
|
139
|
+
# validates_exclusion_of :age,
|
140
|
+
# :in => 13..19,
|
141
|
+
# :message => "cannot be a teenager"
|
142
|
+
# TODO: implement exclusion
|
143
|
+
if has_model_validation?(validations, column, :exclusion)
|
144
|
+
# use :in as range
|
145
|
+
if validation(validations, column, :exclusion, :in).is_a?(Range)
|
146
|
+
validators << <<-MX
|
147
|
+
<!-- Exclusion (range) not implemented as yet -->
|
148
|
+
MX
|
149
|
+
end
|
150
|
+
# use :in as part of a list or regexp
|
151
|
+
if validation(validations, column, :exclusion, :in).is_a?(Array)
|
152
|
+
validators << <<-MX
|
153
|
+
<!-- Exclusion (list) not implemented as yet -->
|
154
|
+
MX
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# validates_length_of :name, :maximum => 50
|
159
|
+
# validates_length_of :password, :in => 6..20
|
160
|
+
# validates_length_of :address, :minimum => 10,
|
161
|
+
# :message => "seems too short"
|
162
|
+
#
|
163
|
+
# Options:
|
164
|
+
# :in range The length of value must be in range.
|
165
|
+
# :minimum integer Value may not be less than the integer characters long.
|
166
|
+
# :maximum integer Value may not be greater than integer characters long.
|
167
|
+
# :message text The default message depends on the test being performed. The message
|
168
|
+
# may contain a single %d sequence, which will be replaced by the
|
169
|
+
# maximum, minimum, or exact length required.
|
170
|
+
# :on :save, :create, or :update.
|
171
|
+
# :too_long text A synonym for :message when :maximum is being used.
|
172
|
+
# :too_short text A synonym for :message when :minimum is being used.
|
173
|
+
#
|
174
|
+
# <mx:StringValidator
|
175
|
+
# maxLength="NaN"
|
176
|
+
# minLength="NaN"
|
177
|
+
# tooLongError="This string is longer than the maximum allowed length."
|
178
|
+
# tooShortError="This string is shorter than the minimum allowed length."
|
179
|
+
# />
|
180
|
+
if has_model_validation?(validations, column, :length)
|
181
|
+
validators << <<-MX
|
182
|
+
<mx:StringValidator
|
183
|
+
source="{#{field_name}}" property="text"
|
184
|
+
required="#{required?(column.null)}"
|
185
|
+
trigger="{#{field_name}}" triggerEvent="change"
|
186
|
+
tooLongError="#{validation(validations, column, :length, :too_long)}"
|
187
|
+
tooShortError="#{validation(validations, column, :length, :too_short)}"
|
188
|
+
maxLength="#{max(validations, column)}"
|
189
|
+
minLength="#{min(validations, column)}" />
|
190
|
+
MX
|
191
|
+
end
|
192
|
+
|
193
|
+
# validates_acceptance_of :terms,
|
194
|
+
# :message => "Please accept the terms to proceed"
|
195
|
+
#
|
196
|
+
# Note: this assumes acceptance to be boolean such as a check box
|
197
|
+
if has_model_validation?(validations, column, :acceptance)
|
198
|
+
validators << <<-MX
|
199
|
+
<mx:Validator
|
200
|
+
source="{#{field_name}}" property="selected"
|
201
|
+
enabled="#{column.null}"
|
202
|
+
required="#{required?(column.null)}"
|
203
|
+
requiredFieldError="This field is required."
|
204
|
+
trigger="{#{trigger_btn}}" triggerEvent="click" />
|
205
|
+
MX
|
206
|
+
end
|
207
|
+
if has_model_validation?(validations, column, :presence)
|
208
|
+
validators << <<-MX
|
209
|
+
<mx:Validator
|
210
|
+
source="{#{field_name}}" property="text"
|
211
|
+
enabled="#{column.null}"
|
212
|
+
required="#{required?(column.null)}"
|
213
|
+
requiredFieldError="#{validation(validations, column, :presence, :message)}"
|
214
|
+
trigger="{#{trigger_btn}}" triggerEvent="click" />
|
215
|
+
MX
|
216
|
+
end
|
217
|
+
|
218
|
+
validators
|
219
|
+
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
# Returns the regular expression that looks for an item in a string
|
226
|
+
# Order of value:
|
227
|
+
# * :in => %w{john fred mary} => john|fred|mary
|
228
|
+
#
|
229
|
+
def in_list(validations, column, type, condition=:in)
|
230
|
+
regex = "("
|
231
|
+
regex << validation(validations, column, type, condition).join("|") unless validation(validations, column, type, condition).nil?
|
232
|
+
regex << ")"
|
233
|
+
end
|
234
|
+
|
235
|
+
# Returns the minimum length
|
236
|
+
# Order of value:
|
237
|
+
# * :min => 5 => 5
|
238
|
+
# * :in => 1..3 => 1
|
239
|
+
# * :within => 1..3 => 1
|
240
|
+
# * => NaN (default)
|
241
|
+
#
|
242
|
+
# Note: <tt>:in</tt> and <tt>:within</tt> are not available options
|
243
|
+
def min(validations, column, type=:length)
|
244
|
+
validation(validations, column, type, :minimum) || (validation(validations, column, type, :in).first unless validation(validations, column, type, :in).nil?) || (validation(validations, column, type, :within).first unless validation(validations, column, type, :within).nil?) || "NaN"
|
245
|
+
end
|
246
|
+
|
247
|
+
# Returns the maximum length correctly depending on whether <tt>:in</tt> is used
|
248
|
+
# Order of value:
|
249
|
+
# * :maximum => 10 => 10
|
250
|
+
# * :in => 1..3 => 3
|
251
|
+
# * :within => 1..3 => 3
|
252
|
+
# * => NaN (default)
|
253
|
+
#
|
254
|
+
# Note: <tt>:in</tt> and <tt>:within</tt> are not available options
|
255
|
+
def max(validations, column, type=:length)
|
256
|
+
validation(validations, column, type, :maximum) || (validation(validations, column, type, :in).last unless validation(validations, column, type, :in).nil?) || (validation(validations, column, type, :within).first unless validation(validations, column, type, :within).nil?) || "NaN"
|
257
|
+
end
|
258
|
+
|
259
|
+
# Returns the schema validations for a column name
|
260
|
+
#
|
261
|
+
# Example: From the migration
|
262
|
+
#
|
263
|
+
# t.column :title, :string, :limit=>20
|
264
|
+
# t.column :name, :string, :limit=>255, :null=>false
|
265
|
+
# t.column :dob, :date
|
266
|
+
# t.column :email, :string
|
267
|
+
# t.column :description, :text
|
268
|
+
# t.column :available, :boolean, :default=>false
|
269
|
+
#
|
270
|
+
# >> column_validations(validations, :name)
|
271
|
+
# => type=>string, limit=>255, deafult=>
|
272
|
+
|
273
|
+
def column_validations(validations, column)
|
274
|
+
result = []
|
275
|
+
FlexScaffold::Validations::SCHEMA_INFO.each do |aRule|
|
276
|
+
validations.fetch(column.name, nil)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# Returns the model validations for a column name
|
281
|
+
#
|
282
|
+
# Example: From the model
|
283
|
+
#
|
284
|
+
# validates_format_of :name,
|
285
|
+
# :with => /^\w+$/,
|
286
|
+
# :message => "is missing or invalid"
|
287
|
+
#
|
288
|
+
# >> model_validations(validations, :name, :format)
|
289
|
+
# => with => /^\w+$/, message => "is missing or invalid", :on=>
|
290
|
+
|
291
|
+
def model_validations(validations, column, type)
|
292
|
+
validations.fetch(column.name, nil).fetch(type.to_s, nil)
|
293
|
+
end
|
294
|
+
|
295
|
+
# Returns the actual validation condition for a column name
|
296
|
+
#
|
297
|
+
# Example: From the model
|
298
|
+
#
|
299
|
+
# validates_format_of :name,
|
300
|
+
# :with => /^\w+$/,
|
301
|
+
# :message => "is missing or invalid"
|
302
|
+
#
|
303
|
+
# >> validation(validations, :name, :format, :with)
|
304
|
+
# => /^\w+$/
|
305
|
+
|
306
|
+
def validation(validations, column, type, name)
|
307
|
+
model_validations(validations, column, type).fetch(name.to_s, nil)
|
308
|
+
end
|
309
|
+
|
310
|
+
# Returns the whether the validation has particular condition for a column name
|
311
|
+
#
|
312
|
+
# Example: From the model
|
313
|
+
#
|
314
|
+
# validates_format_of :name,
|
315
|
+
# :with => /^\w+$/,
|
316
|
+
# :message => "is missing or invalid"
|
317
|
+
#
|
318
|
+
# >> has_vvalidation_condition?(validations, :name, :format)
|
319
|
+
# => true
|
320
|
+
#
|
321
|
+
# >> has_validation_condition?(validations, :name, :inclusion)
|
322
|
+
# => false
|
323
|
+
|
324
|
+
def has_validation_condition?(validations, column, type)
|
325
|
+
validation_condition.fetch(column.name).has_key?(type.to_s) rescue false
|
326
|
+
end
|
327
|
+
# Returns the whether model has the validation for a column name
|
328
|
+
#
|
329
|
+
# Example: From the model
|
330
|
+
#
|
331
|
+
# validates_format_of :name,
|
332
|
+
# :with => /^\w+$/,
|
333
|
+
# :message => "is missing or invalid"
|
334
|
+
#
|
335
|
+
# >> has_model_validation?(validations, :name, :format)
|
336
|
+
# => true
|
337
|
+
#
|
338
|
+
# >> has_model_validation?(validations, :name, :inclusion)
|
339
|
+
# => false
|
340
|
+
|
341
|
+
def has_model_validation?(validations, column, type)
|
342
|
+
validations.fetch(column.name).has_key?(type.to_s) rescue false
|
343
|
+
end
|
344
|
+
|
345
|
+
def prefix(options)
|
346
|
+
!options[:prefix].empty? ? "_#{options[:prefix]}" : ""
|
347
|
+
end
|
348
|
+
|
349
|
+
def text(val=nil)
|
350
|
+
(val.to_sym != :boolean) ? "text" : "selected"
|
351
|
+
end
|
352
|
+
|
353
|
+
def required?(value)
|
354
|
+
!value
|
355
|
+
end
|
356
|
+
|
357
|
+
def cast(column)
|
358
|
+
(column.type.to_sym != :boolean) ? "'#{column.default}'" : "#{column.default}"
|
359
|
+
end
|
360
|
+
|
361
|
+
def form_field(options, column)
|
362
|
+
(options[:prefix] == 'create') ? "field_create_#{column.name}" : "field_edit_#{column.name}"
|
363
|
+
end
|
364
|
+
|
365
|
+
def form_submit(options)
|
366
|
+
(options[:prefix] == 'create') ? "btn_add_create" : "btn_update_edit"
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
372
|
+
|
373
|
+
class FlexScaffoldGenerator < ScaffoldGenerator
|
374
|
+
|
375
|
+
alias_method :base_controller_file_path, :controller_file_path
|
376
|
+
|
377
|
+
def manifest
|
378
|
+
record do |m|
|
379
|
+
|
380
|
+
m.class_collisions controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper"
|
381
|
+
m.class_collisions class_path, class_name, "#{singular_name}Test"
|
382
|
+
|
383
|
+
m.directory File.join('app/flex', class_path)
|
384
|
+
m.directory File.join('app/flex' ,"#{plural_name}")
|
385
|
+
|
386
|
+
m.complex_template '_index.rmxml', File.join('app/flex', "#{plural_name}", "_#{plural_name}.mxml"),
|
387
|
+
:insert => '_form.rhtml',
|
388
|
+
:sandbox => lambda { create_sandbox },
|
389
|
+
:mark_id => singular_name,
|
390
|
+
:assigns => {:fields_as_xml => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_as_xml_resource(:prefix=>'create'))},
|
391
|
+
:fields_as_update_params => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_as_actionscript_resource_params(:prefix=>'edit'))},
|
392
|
+
:fields_as_create_text => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_as_actionscript_form_action(:prefix=>'create'))},
|
393
|
+
:fields_as_edit_text => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_as_actionscript_form_action(:prefix=>'edit'))},
|
394
|
+
:fields_as_input_edit => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_form(:prefix=>'edit'))},
|
395
|
+
:fields_as_input_create => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_form(:prefix=>'create'))},
|
396
|
+
:model_validators_create => lambda {FlexScaffoldingSandbox.mxml_model_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_model_validators(:prefix=>'create'))},
|
397
|
+
:model_validators_edit => lambda {FlexScaffoldingSandbox.mxml_model_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_model_validators(:prefix=>'edit'))}
|
398
|
+
}
|
399
|
+
|
400
|
+
m.complex_template '_list.rmxml', File.join('app/flex', "#{plural_name}", "_list.mxml"),
|
401
|
+
:insert => '_list.rhtml',
|
402
|
+
:sandbox => lambda { create_sandbox },
|
403
|
+
:mark_id => singular_name,
|
404
|
+
:assigns => {:fields_as_grid => lambda {FlexScaffoldingSandbox.mxml_tags(model_instance, singular_name, :input_block => FlexScaffoldingSandbox.mxml_grid_column)}}
|
405
|
+
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
def scaffold_name
|
412
|
+
FlexScaffold::Config.plugin_name
|
413
|
+
end
|
414
|
+
|
415
|
+
def controller_file_path
|
416
|
+
"/" + base_controller_file_path
|
417
|
+
end
|
418
|
+
|
419
|
+
def create_sandbox
|
420
|
+
sandbox = FlexScaffoldingSandbox.new
|
421
|
+
sandbox.singular_name = singular_name
|
422
|
+
begin
|
423
|
+
sandbox.instance_variable_set(:@validations, class_name.constantize.new_validations)
|
424
|
+
sandbox.model_instance = model_instance
|
425
|
+
sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance)
|
426
|
+
rescue ActiveRecord::StatementInvalid => e
|
427
|
+
logger.error "Before updating scaffolding from new DB schema, try creating a table from your model (#{class_name} - try rake db:migrate)"
|
428
|
+
raise SystemExit
|
429
|
+
end
|
430
|
+
sandbox.suffix = suffix
|
431
|
+
sandbox
|
432
|
+
end
|
433
|
+
|
434
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,210 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
|
3
|
+
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
|
4
|
+
creationComplete="{resourceGet.send();}"
|
5
|
+
xmlns:fxrails="*"
|
6
|
+
backgroundGradientColors="[#808080, #ffffff]">
|
7
|
+
|
8
|
+
<mx:Style source="stylesheets/flex_scaffold/default.css"/>
|
9
|
+
|
10
|
+
<mx:HTTPService id="resourceGet" url="/<%= plural_name %>.xml" useProxy="false" method="GET"/>
|
11
|
+
<mx:HTTPService id="resourcePut" useProxy="false" method="POST" result="resourceGet.send();handlePutResultHttpService(event)" resultFormat="e4x"/>
|
12
|
+
<mx:HTTPService id="resourceDelete" useProxy="false" method="POST" result="resourceGet.send();handleDeleteResultHttpService(event)" resultFormat="e4x"/>
|
13
|
+
<mx:HTTPService id="resourcePost" url="/<%= plural_name %>.xml" useProxy="false" method="POST" result="resourceGet.send();handlePostResultHttpService(event)" resultFormat="e4x"
|
14
|
+
contentType="application/xml">
|
15
|
+
<mx:request xmlns="">
|
16
|
+
<<%= singular_name %>>
|
17
|
+
<%= fields_as_xml.call -%>
|
18
|
+
</<%= singular_name %>>
|
19
|
+
</mx:request>
|
20
|
+
</mx:HTTPService>
|
21
|
+
|
22
|
+
<mx:Script>
|
23
|
+
<![CDATA[
|
24
|
+
import mx.rpc.events.ResultEvent
|
25
|
+
import mx.controls.Alert;
|
26
|
+
|
27
|
+
[Bindable]
|
28
|
+
private var _error:String;
|
29
|
+
|
30
|
+
private function clearErrorMessage():void {_error = ""}
|
31
|
+
|
32
|
+
private function handleDeleteResultHttpService(event:ResultEvent):void {
|
33
|
+
var result:XML = XML(event.result)
|
34
|
+
if (!(result == null || result == "")) {
|
35
|
+
_error = result;
|
36
|
+
} else {
|
37
|
+
_error = "Item Deleted";
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
private function handlePutResultHttpService(event:ResultEvent):void {
|
42
|
+
var result:XML = XML(event.result)
|
43
|
+
if (!(result == null || result == "")) {
|
44
|
+
_error = result;
|
45
|
+
} else {
|
46
|
+
_error = "Item Updated";
|
47
|
+
currentState = '';
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
private function handlePostResultHttpService(event:ResultEvent):void {
|
52
|
+
var result:XML = XML(event.result)
|
53
|
+
if (!(result == null || result == "")) {
|
54
|
+
_error = result;
|
55
|
+
} else {
|
56
|
+
_error = "Item Created";
|
57
|
+
currentState = '';
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
private function createHandler(event:Event):void {
|
62
|
+
currentState = 'Create'
|
63
|
+
clearErrorMessage()
|
64
|
+
<%= fields_as_create_text.call -%>
|
65
|
+
btn_add_create.addEventListener('click', createResource);
|
66
|
+
btn_cancel_create.addEventListener('click', cancelCreate);
|
67
|
+
}
|
68
|
+
|
69
|
+
public function createResource(event:Event) : void
|
70
|
+
{
|
71
|
+
resourcePost.send();
|
72
|
+
}
|
73
|
+
|
74
|
+
public function cancelCreate(event:Event) : void
|
75
|
+
{
|
76
|
+
clearErrorMessage()
|
77
|
+
currentState = '';
|
78
|
+
}
|
79
|
+
|
80
|
+
public function deleteResource(id:String):void {
|
81
|
+
resourceDelete.url = "/<%= plural_name %>/" + id + ".xml";
|
82
|
+
resourceDelete.send({_method: "DELETE"});
|
83
|
+
}
|
84
|
+
|
85
|
+
]]>
|
86
|
+
</mx:Script>
|
87
|
+
|
88
|
+
<mx:Script>
|
89
|
+
<![CDATA[
|
90
|
+
import mx.controls.Alert;
|
91
|
+
import mx.events.CloseEvent;
|
92
|
+
|
93
|
+
public function deleteHandler(event:Event) : void
|
94
|
+
{
|
95
|
+
Alert.show("Are you sure you want to delete this item?", "Delete Item", 3, this,
|
96
|
+
function(event:CloseEvent):void
|
97
|
+
{
|
98
|
+
if (event.detail==Alert.YES)
|
99
|
+
clearErrorMessage()
|
100
|
+
mx.core.Application.application.deleteResource(<%= singular_name %>_grid.selectedItem.id);
|
101
|
+
});
|
102
|
+
}
|
103
|
+
]]>
|
104
|
+
</mx:Script>
|
105
|
+
|
106
|
+
|
107
|
+
<mx:Script>
|
108
|
+
<![CDATA[
|
109
|
+
|
110
|
+
public function updateHandler(event:Event) : void
|
111
|
+
{
|
112
|
+
clearErrorMessage()
|
113
|
+
currentState = 'Edit';
|
114
|
+
<%= fields_as_edit_text.call -%>
|
115
|
+
btn_update_edit.addEventListener('click', updateResource);
|
116
|
+
btn_cancel_edit.addEventListener('click', cancelEdit);
|
117
|
+
}
|
118
|
+
|
119
|
+
public function updateResource(event:Event) : void
|
120
|
+
{
|
121
|
+
var params:Object = new Object();
|
122
|
+
params['_method'] = "PUT";
|
123
|
+
<%= fields_as_update_params.call -%>
|
124
|
+
|
125
|
+
resourcePut.url = "/<%= plural_name %>/" + <%= singular_name %>_grid.selectedItem.id + ".xml";
|
126
|
+
resourcePut.send(params);
|
127
|
+
}
|
128
|
+
|
129
|
+
public function cancelEdit(event:Event) : void
|
130
|
+
{
|
131
|
+
clearErrorMessage()
|
132
|
+
currentState = '';
|
133
|
+
}
|
134
|
+
]]>
|
135
|
+
</mx:Script>
|
136
|
+
|
137
|
+
<mx:states>
|
138
|
+
<mx:State name="Create">
|
139
|
+
<mx:RemoveChild target="{hbox_create}"/>
|
140
|
+
<mx:AddChild relativeTo="{<%= singular_name %>_grid}" position="before">
|
141
|
+
<mx:target>
|
142
|
+
<mx:Form id="create_form">
|
143
|
+
<%= fields_as_input_create.call -%>
|
144
|
+
<mx:ControlBar width="100%">
|
145
|
+
<mx:Spacer width="50"/>
|
146
|
+
<mx:Button label="Create" id="btn_add_create"/>
|
147
|
+
<mx:LinkButton label="Cancel" id="btn_cancel_create"/>
|
148
|
+
</mx:ControlBar>
|
149
|
+
</mx:Form>
|
150
|
+
</mx:target>
|
151
|
+
</mx:AddChild>
|
152
|
+
</mx:State>
|
153
|
+
|
154
|
+
<mx:State name="Edit">
|
155
|
+
<mx:AddChild relativeTo="{<%= singular_name %>_grid}" position="before">
|
156
|
+
<mx:target>
|
157
|
+
<mx:Form id="edit_form">
|
158
|
+
<%= fields_as_input_edit.call -%>
|
159
|
+
<mx:ControlBar width="100%">
|
160
|
+
<mx:Spacer width="50"/>
|
161
|
+
<mx:Button label="Update" id="btn_update_edit" />
|
162
|
+
<mx:LinkButton label="Cancel" id="btn_cancel_edit"/>
|
163
|
+
</mx:ControlBar>
|
164
|
+
</mx:Form>
|
165
|
+
</mx:target>
|
166
|
+
</mx:AddChild>
|
167
|
+
</mx:State>
|
168
|
+
|
169
|
+
</mx:states>
|
170
|
+
|
171
|
+
<mx:transitions>
|
172
|
+
<mx:Transition id="createItem" fromState="*" toState="Create">
|
173
|
+
<mx:Sequence targets="{[createPanel]}">
|
174
|
+
<mx:RemoveChildAction/>
|
175
|
+
<mx:Resize target="{createPanel}"/>
|
176
|
+
<mx:AddChildAction/>
|
177
|
+
</mx:Sequence>
|
178
|
+
</mx:Transition>
|
179
|
+
|
180
|
+
<mx:Transition id="addItem" fromState="Create" toState="*">
|
181
|
+
<mx:Sequence targets="{[createPanel]}">
|
182
|
+
<mx:RemoveChildAction/>
|
183
|
+
<mx:Resize target="{createPanel}"/>
|
184
|
+
<mx:AddChildAction/>
|
185
|
+
</mx:Sequence>
|
186
|
+
</mx:Transition>
|
187
|
+
|
188
|
+
<mx:Transition id="editItem" fromState="*" toState="Edit">
|
189
|
+
<mx:Sequence targets="{[createPanel]}">
|
190
|
+
<mx:RemoveChildAction/>
|
191
|
+
<mx:Resize target="{createPanel}"/>
|
192
|
+
<mx:AddChildAction/>
|
193
|
+
</mx:Sequence>
|
194
|
+
</mx:Transition>
|
195
|
+
</mx:transitions>
|
196
|
+
|
197
|
+
<%= model_validators_create.call %>
|
198
|
+
<%= model_validators_edit.call %>
|
199
|
+
|
200
|
+
<mx:Panel title="<%= plural_name.capitalize %>" id="createPanel">
|
201
|
+
|
202
|
+
<mx:HBox id="hbox_create" width="90%" horizontalAlign="right" height="40" horizontalGap="8" verticalAlign="middle" >
|
203
|
+
<mx:Button label="Create" id="btn_create" styleName="btn_create" icon="@Embed('images/flex_scaffold/create.gif')" click="mx.core.Application.application.createHandler(event);"/>
|
204
|
+
</mx:HBox>
|
205
|
+
<mx:Text id="error" styleName="error" htmlText="{_error}" color="#ff0033"/>
|
206
|
+
<fxrails:_list id="<%= singular_name %>_grid" dataProvider="{resourceGet.lastResult.<%= plural_name %>.<%= singular_name %>}" />
|
207
|
+
|
208
|
+
</mx:Panel>
|
209
|
+
|
210
|
+
</mx:Application>
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
|
3
|
+
<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml">
|
4
|
+
<mx:columns>
|
5
|
+
<%= fields_as_grid.call %>
|
6
|
+
<mx:DataGridColumn editable="false" width="120">
|
7
|
+
<mx:itemRenderer>
|
8
|
+
<mx:Component>
|
9
|
+
<mx:Box direction="horizontal">
|
10
|
+
<mx:LinkButton label="Delete" click="mx.core.Application.application.deleteHandler(event);"/>
|
11
|
+
<mx:LinkButton label="Edit" click="mx.core.Application.application.updateHandler(event);"/>
|
12
|
+
</mx:Box>
|
13
|
+
</mx:Component>
|
14
|
+
</mx:itemRenderer>
|
15
|
+
</mx:DataGridColumn>
|
16
|
+
</mx:columns>
|
17
|
+
</mx:DataGrid>
|