extjsml 0.0.2

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/bin/extjsmlc +70 -0
  3. data/lib/extclasses/actioncolumn.rb +11 -0
  4. data/lib/extclasses/booleancolumn.rb +34 -0
  5. data/lib/extclasses/button.rb +11 -0
  6. data/lib/extclasses/checkbox.rb +30 -0
  7. data/lib/extclasses/checkboxgroup.rb +14 -0
  8. data/lib/extclasses/checkcolumn.rb +16 -0
  9. data/lib/extclasses/combo.rb +56 -0
  10. data/lib/extclasses/compositefield.rb +11 -0
  11. data/lib/extclasses/container.rb +12 -0
  12. data/lib/extclasses/datecolumn.rb +21 -0
  13. data/lib/extclasses/datefield.rb +16 -0
  14. data/lib/extclasses/editorgrid.rb +97 -0
  15. data/lib/extclasses/fieldcontainer.rb +23 -0
  16. data/lib/extclasses/fieldset.rb +61 -0
  17. data/lib/extclasses/filefield.rb +18 -0
  18. data/lib/extclasses/form.rb +33 -0
  19. data/lib/extclasses/grid.rb +141 -0
  20. data/lib/extclasses/gridcolumn.rb +19 -0
  21. data/lib/extclasses/hidden.rb +7 -0
  22. data/lib/extclasses/htmleditor.rb +15 -0
  23. data/lib/extclasses/label.rb +10 -0
  24. data/lib/extclasses/numbercolumn.rb +30 -0
  25. data/lib/extclasses/numberfield.rb +19 -0
  26. data/lib/extclasses/paging.rb +12 -0
  27. data/lib/extclasses/panel.rb +29 -0
  28. data/lib/extclasses/passwordfield.rb +27 -0
  29. data/lib/extclasses/pivotgrid.rb +91 -0
  30. data/lib/extclasses/radio.rb +25 -0
  31. data/lib/extclasses/radiogroup.rb +14 -0
  32. data/lib/extclasses/runningcolumn.rb +9 -0
  33. data/lib/extclasses/tabpanel.rb +17 -0
  34. data/lib/extclasses/tbfill.rb +5 -0
  35. data/lib/extclasses/tbseparator.rb +5 -0
  36. data/lib/extclasses/templatecolumn.rb +11 -0
  37. data/lib/extclasses/textarea.rb +12 -0
  38. data/lib/extclasses/textfield.rb +27 -0
  39. data/lib/extclasses/timefield.rb +16 -0
  40. data/lib/extclasses/toolbar.rb +7 -0
  41. data/lib/extclasses/viewport.rb +8 -0
  42. data/lib/extclasses/window.rb +34 -0
  43. data/lib/extjsml/basenode.rb +347 -0
  44. data/lib/extjsml/ext_util.rb +232 -0
  45. data/lib/extjsml/generator.rb +578 -0
  46. data/lib/extjsml/parser.rb +35 -0
  47. data/lib/extmodules/form_field.rb +32 -0
  48. data/lib/extmodules/magic.rb +196 -0
  49. data/lib/extplugins/currency.rb +25 -0
  50. data/lib/extplugins/currencycolumn.rb +18 -0
  51. data/lib/extplugins/numeric.rb +32 -0
  52. data/lib/extplugins/pricefield.rb +36 -0
  53. data/lib/extuxs/uxaccount.rb +8 -0
  54. data/lib/extuxs/uxbroker.rb +7 -0
  55. data/lib/extuxs/uxchq.rb +8 -0
  56. data/lib/extuxs/uxreceiverinfo.rb +8 -0
  57. data/lib/extuxs/uxsettlement.rb +8 -0
  58. data/lib/test/test_parser.rb +97 -0
  59. metadata +115 -0
@@ -0,0 +1,232 @@
1
+ class String
2
+
3
+ EXT_CLASS_MAP = {
4
+ box: 'Ext.BoxComponent',
5
+ button: 'Ext.Button',
6
+ buttongroup: 'Ext.ButtonGroup',
7
+ colorpalette: 'Ext.ColorPalette',
8
+ component: 'Ext.Component',
9
+ container: 'Ext.Container',
10
+ cycle: 'Ext.CycleButton',
11
+ dataview: 'Ext.DataView',
12
+ datepicker: 'Ext.DatePicker',
13
+ editor: 'Ext.Editor',
14
+ editorgrid: 'Ext.grid.EditorGridPanel',
15
+ flash: 'Ext.FlashComponent',
16
+ grid: 'Ext.grid.GridPanel',
17
+ listview: 'Ext.ListView',
18
+ multislider: 'Ext.slider.MultiSlider',
19
+ panel: 'Ext.Panel',
20
+ progress: 'Ext.ProgressBar',
21
+ propertygrid: 'Ext.grid.PropertyGrid',
22
+ slider: 'Ext.slider.SingleSlider',
23
+ spacer: 'Ext.Spacer',
24
+ splitbutton: 'Ext.SplitButton',
25
+ tabpanel: 'Ext.TabPanel',
26
+ treepanel: 'Ext.tree.TreePanel',
27
+ viewport: 'Ext.Viewport',
28
+ window: 'Ext.Window',
29
+
30
+ # Toolbar component
31
+ paging: 'Ext.PagingToolbar',
32
+ pagingtoolbar: 'Ext.PagingToolbar', # 4.2
33
+ toolbar: 'Ext.Toolbar',
34
+ tbbutton: 'Ext.Toolbar.Button',
35
+ tbfill: 'Ext.Toolbar.Fill',
36
+ tbitem: 'Ext.Toolbar.Item',
37
+ tbseparator: 'Ext.Toolbar.Separator',
38
+ tbspacer: 'Ext.Toolbar.Spacer',
39
+ tbsplit: 'Ext.Toolbar.SplitButton',
40
+ tbtext: 'Ext.Toolbar.TextItem',
41
+
42
+ # Menu components
43
+ menu: 'Ext.menu.Menu',
44
+ colormenu: 'Ext.menu.ColorMenu',
45
+ datemenu: 'Ext.menu.DateMenu',
46
+ menubaseitem: 'Ext.menu.BaseItem',
47
+ menucheckitem: 'Ext.menu.CheckItem',
48
+ menuitem: 'Ext.menu.Item',
49
+ menuseparator: 'Ext.menu.Separator',
50
+ menutextitem: 'Ext.menu.TextItem',
51
+
52
+ # Form components
53
+ form: 'Ext.form.FormPanel',
54
+ checkbox: 'Ext.form.Checkbox',
55
+ checkboxgroup: 'Ext.form.CheckboxGroup',
56
+ combo: 'Ext.form.ComboBox',
57
+ compositefield: 'Ext.form.CompositeField',
58
+ datefield: 'Ext.form.DateField',
59
+ displayfield: 'Ext.form.DisplayField',
60
+ field: 'Ext.form.Field',
61
+ fieldset: 'Ext.form.FieldSet',
62
+ hidden: 'Ext.form.Hidden',
63
+ htmleditor: 'Ext.form.HtmlEditor',
64
+ label: 'Ext.form.Label',
65
+ numberfield: 'Ext.form.NumberField',
66
+ radio: 'Ext.form.Radio',
67
+ radiogroup: 'Ext.form.RadioGroup',
68
+ textarea: 'Ext.form.TextArea',
69
+ textfield: 'Ext.form.TextField',
70
+ timefield: 'Ext.form.TimeField',
71
+ trigger: 'Ext.form.TriggerField',
72
+ # additional
73
+ # :currency => $ 1,222.00
74
+ currency: 'Ext.form.Currency',
75
+ # :numeric => 1,222.00
76
+ numeric: 'Ext.form.Numeric',
77
+ # ux filefield
78
+ filefield: 'Ext.ux.form.FieldUploadField',
79
+
80
+ # Chart components
81
+ chart: 'Ext.chart.Chart',
82
+ barchart: 'Ext.chart.BarChart',
83
+ cartesianchart: 'Ext.chart.CartesianChart',
84
+ columnchart: 'Ext.chart.ColumnChart',
85
+ linechart: 'Ext.chart.LineChart',
86
+ piechart: 'Ext.chart.PieChart',
87
+
88
+ # Store xtypes
89
+ arraystore: 'Ext.data.ArrayStore',
90
+ directstore: 'Ext.data.DirectStore',
91
+ groupingstore: 'Ext.data.GroupingStore',
92
+ jsonstore: 'Ext.data.JsonStore',
93
+ simplestore: 'Ext.data.SimpleStore',
94
+ store: 'Ext.data.Store',
95
+ xmlstore: 'Ext.data.XmlStore',
96
+
97
+ # Grid Columns
98
+ gridcolumn: 'Ext.grid.Column',
99
+ booleancolumn: 'Ext.grid.BooleanColumn',
100
+ numbercolumn: 'Ext.grid.NumberColumn',
101
+ datecolumn: 'Ext.grid.DateColumn',
102
+ templatecolumn: 'Ext.grid.TemplateColumn',
103
+ # additional
104
+ # gcurrency
105
+ currencycolumn: 'Ext.grid.CurrencyColumn'
106
+
107
+ }
108
+
109
+ def self.get_all_xtypes
110
+ EXT_CLASS_MAP.keys
111
+ end
112
+
113
+ def to_extclassname
114
+ EXT_CLASS_MAP[self.to_sym]
115
+ end
116
+
117
+ def capitalize
118
+ self[0].upcase + self[1..-1]
119
+ end
120
+
121
+ def to_storeid(delimeter = '-')
122
+ sid = self.split(delimeter)
123
+ temp = sid[1..-1]
124
+ fword = sid[0];
125
+ temp.each do |el|
126
+ fword += (el[0].upcase + el[1..-1])
127
+ end
128
+
129
+ fword
130
+ end
131
+ end
132
+
133
+ class ExtUtil
134
+ # TODO move to file
135
+ ALIAS_TABLE = {
136
+ :tab => :tabpanel,
137
+ :div => :container,
138
+ # column alias
139
+ :gtext => :gridcolumn,
140
+ :gboolean => :booleancolumn,
141
+ :gnumber => :numbercolumn,
142
+ :gdate => :datecolumn,
143
+ :gtemplate => :templatecolumn,
144
+ :gaction => :actioncolumn,
145
+ :gcurrency => :currencycolumn,
146
+ :gcheck => :checkcolumn
147
+ }
148
+
149
+ CONTAINER_XTYPE = [
150
+ "div",
151
+ "container",
152
+ "panel",
153
+ "tabpanel",
154
+ "form",
155
+ "fieldset",
156
+ "fieldcontainer"
157
+ ]
158
+
159
+ DATA_COLUNMS = [
160
+ "gridcolumn",
161
+ "numbercolumn",
162
+ "booleancolumn",
163
+ "datecolumn",
164
+ "currencycolumn",
165
+ "numericcolumn"
166
+ ]
167
+
168
+ FIELD_XTYPE = [
169
+ "fieldcontainer",
170
+ "fileuploadfield",
171
+ "checkbox",
172
+ "checkboxgroup",
173
+ "combo",
174
+ "compositefield",
175
+ "datefield",
176
+ "displayfield",
177
+ "field",
178
+ "fieldset",
179
+ "hidden",
180
+ "htmleditor",
181
+ "label",
182
+ "numberfield",
183
+ "radio",
184
+ "radiogroup",
185
+ "textarea",
186
+ "textfield",
187
+ "timefield",
188
+ "trigger",
189
+
190
+ "uxaccount",
191
+ "uxsettlement",
192
+ "uxchq",
193
+ "uxbroker"
194
+ ];
195
+
196
+ def self.xtype_alias(xtype)
197
+ ALIAS_TABLE[xtype.to_sym] || xtype
198
+ end
199
+
200
+ def self.field_xtype
201
+ FIELD_XTYPE
202
+ end
203
+
204
+ def self.data_xtype
205
+ DATA_COLUNMS
206
+ end
207
+
208
+ def self.container_xtype
209
+ CONTAINER_XTYPE
210
+ end
211
+
212
+ def self.FontWidthRatio
213
+ 9
214
+ end
215
+
216
+ def self.all_xtype
217
+ return String.get_all_xtypes
218
+ end
219
+
220
+ require "securerandom"
221
+ def self.random_id
222
+ "_" + SecureRandom.urlsafe_base64.gsub(/\d|\W/,'')
223
+ end
224
+
225
+
226
+ end
227
+
228
+ # test
229
+ if __FILE__ == $0
230
+ p "jsonstore".to_extclassname
231
+ p "x-test-xxx".to_storeid
232
+ end
@@ -0,0 +1,578 @@
1
+ require 'yaml'
2
+ require "json"
3
+ # require "awesome_print"
4
+ # require "jsmin"
5
+ BASE_DIR = File.dirname(__FILE__)
6
+
7
+ # $: << File.dirname(__FILE__)
8
+ require_relative "./parser"
9
+ require_relative "./ext_util"
10
+ require_relative "./basenode"
11
+
12
+
13
+ Dir.open("#{BASE_DIR}/../extmodules").each do |f|
14
+ next unless f.match /rb$/
15
+ require "extmodules/#{f}"
16
+ end
17
+
18
+ Dir.open("#{BASE_DIR}/../extclasses").grep(/rb$/).each do |f|
19
+ require "extclasses/#{f}"
20
+ end
21
+
22
+ Dir.open("#{BASE_DIR}/../extplugins").grep(/rb$/).each do |f|
23
+ require "extplugins/#{f}"
24
+ end
25
+
26
+ Dir.open("#{BASE_DIR}/../extuxs").grep(/rb$/).each do |f|
27
+ require "extuxs/#{f}"
28
+ end
29
+
30
+ # recusive building node tree
31
+ def build_node(*args, &block)
32
+ element = args[0]
33
+ parent = args[1]
34
+ params = args[2] || {}
35
+
36
+ if parent.nil?
37
+ k = element.keys.first
38
+ v = element[k]
39
+ xtype, options = ExtParser.parse(k)
40
+ options = yield(xtype, options) if block_given?
41
+ xtype = ExtUtil.xtype_alias(xtype);
42
+ node = eval("Ext#{xtype.capitalize}").new(options, parent)
43
+ node.add_child build_node(v, node, &block)
44
+ return node
45
+ end
46
+
47
+ if element.is_a? Hash
48
+ begin
49
+ wrapper_hash = ExtContainer.new({ layout: "fit",
50
+ autoHeight: true,
51
+ style: "{height: 100%; margin: 0em 0em;}",
52
+ defaults: { margins: "0 0"}},
53
+ parent)
54
+ element.each do |k,v|
55
+ xtype, options = ExtParser.parse(k)
56
+ options = yield(xtype, options) if block_given?
57
+ xtype = ExtUtil.xtype_alias(xtype);
58
+ node = eval("Ext#{xtype.capitalize}").new(options, parent)
59
+ node.add_child(build_node(v, node, &block))
60
+ node.childs.each do |c|
61
+ if c.xtype == "container" and
62
+ c.config[:layout] == "hbox" and
63
+ node.xtype == "container" and
64
+ if c.child_of? "fieldset", "form"
65
+ c.config.delete :labelWidth
66
+ c.childs.each do |_c|
67
+ # _c.config.delete :labelWidth
68
+ _c.config.delete :defaults
69
+ _c.config.delete :style
70
+ _c.config.merge!({:margins => "0 0", :col_index => 0})
71
+ _c.childs.each do |_f|
72
+ if ExtUtil.field_xtype.include? _f.xtype
73
+ # _f.config.delete :labelWidth
74
+ # break;
75
+ end
76
+ end
77
+ break;
78
+ end
79
+ end
80
+ end
81
+ end
82
+ wrapper_hash.add_child node
83
+ end
84
+
85
+ # skip wrapper
86
+ if wrapper_hash.child_of?("viewport","container","grid","toolbar", "tabpanel", "form", "window", "editorgrid", "radiogroup", "checkboxgroup", "fieldset")
87
+ # unwrap
88
+ wrapper_hash = wrapper_hash.childs
89
+ end
90
+ wrapper_hash
91
+ rescue Exception => e
92
+ puts e.message, __FILE__, __LINE__, "in Hash"
93
+ raise e
94
+ end
95
+ elsif element.is_a? Array
96
+ begin
97
+
98
+ if element[0].is_a? Array
99
+ new_element = element
100
+
101
+ # default config
102
+ inherit_config = {
103
+ margins: "0 2.5"
104
+ }
105
+
106
+ # temp config of parent
107
+ _config = {}
108
+ if ExtUtil.container_xtype.include?(parent.xtype)
109
+ # _config.merge!({ :padding => parent.config[:padding] }) if parent.config[:padding]
110
+ _config.merge!({ :margins => parent.config[:margins] }) if parent.config[:margins]
111
+ end
112
+ inherit_config.merge! _config
113
+ wrapper = ExtContainer.new({ layout: "hbox",
114
+ layoutConfig: { pack: "start", align: 'stretchmax'},
115
+ defaults: inherit_config },
116
+ parent)
117
+ new_element.each_with_index do |el, col|
118
+ wrapper.add_child(build_node(el, wrapper, { :col_index => col } , &block))
119
+ end
120
+
121
+ wrapper
122
+ else
123
+ node = ExtContainer.new({ layout: "anchor",
124
+ style: "{ height: 100%; margin: 0em 0em; }",
125
+ defaults: { margins: "0 0"}}, parent)
126
+ element.each_with_index do |el, col|
127
+ node.config.merge! params
128
+ node.add_child(build_node(el, node, &block))
129
+ end
130
+
131
+ # check first child is the field component
132
+ if node.childs.count > 0
133
+ if ExtUtil.field_xtype.include?(node.childs.first.xtype) and
134
+ "toolbar" != parent.xtype
135
+ # inherit fieldLableWidth
136
+ _config = { :layout => "anchor" }
137
+ _config = { :layout => "hbox" } if parent.xtype == 'fieldcontainer'
138
+ pnode = node.find_parent("form","fieldset");
139
+ # calculated proper labelWidth
140
+ lw = []
141
+ mlb = 0 # max label width
142
+ offset = 15 # offset label width TODO ??
143
+ is_contain_fieldset = false
144
+ node.childs.each do |c|
145
+ next if c.xtype == "hidden"
146
+ is_contain_fieldset = true if c.xtype == "fieldset"
147
+ if ["radiogroup","checkboxgroup"].include? c.xtype
148
+ lb = []
149
+ c.childs.each do |r|
150
+ _lb = r.config[:boxLabel].size * ExtUtil.FontWidthRatio + offset unless r.config[:boxLabel].nil?
151
+ lb << _lb
152
+ r.override_config :width => _lb + offset
153
+ end
154
+ if lb.max > 0 and not c.config[:width]
155
+ lb_width = lb.inject(&:+)
156
+ # c.override_config :width => (lb.max * lb.count) if lb.max > 0
157
+ c.override_config :width => lb_width
158
+ end
159
+ end
160
+ lw << c.config[:fieldLabel].size * ExtUtil.FontWidthRatio + offset unless c.config[:fieldLabel].nil?
161
+ end
162
+
163
+ if parent.config[:fieldLabel]
164
+ lw << parent.config[:fieldLabel].size * ExtUtil.FontWidthRatio + offset
165
+ end
166
+
167
+ _config.merge! :labelWidth => lw.max || 10 if pnode and pnode.config[:labelWidth].nil?
168
+
169
+ node.override_config _config
170
+ node.config.merge! :defaults => { :labelWidth => lw.max }
171
+
172
+ # fix for chrome 21.x
173
+ # container should have layout auto for fieldset
174
+ if is_contain_fieldset
175
+ node.override_config :layout => "auto"
176
+ end
177
+
178
+ if parent and parent.xtype == "container" and parent.config[:layout] == "hbox"
179
+ parent.config.merge! :labelWidth => lw.max
180
+ end
181
+ # end
182
+
183
+ # update config if setting fileuploadfield
184
+ if node.childs.any? {|n| n.xtype == "fileuploadfield"}
185
+ f = node.find_parent("form")
186
+ unless f.nil?
187
+ f.config.merge! :frame => true, :fileUpload => true
188
+ else
189
+ puts "warning: fileupload may need to be rendered under a form"
190
+ end
191
+ end
192
+
193
+ end
194
+ end
195
+
196
+ # unwrap
197
+ if node.child_of?("grid","toolbar", "editorgrid", "radiogroup", "checkboxgroup") or ["fieldset", "tabpanel","form", "window", "toolbar", "compositefield", "fieldcontainer"].include? parent.xtype
198
+ unless _config.nil? and parent
199
+ parent.config.merge! _config
200
+ #puts "#{parent.xtype}, #{_config}"
201
+ end
202
+ node = node.childs
203
+ end
204
+
205
+ node
206
+ end
207
+ rescue Exception => e
208
+ puts e.message, e.backtrace, __FILE__, __LINE__, "in Array of"
209
+ raise e
210
+ end
211
+
212
+ elsif element.is_a? String
213
+ # leaf node
214
+ xtype, options = ExtParser.parse(element)
215
+ options = yield(xtype, options) if block_given?
216
+ xtype = ExtUtil.xtype_alias(xtype);
217
+ node = eval("Ext#{xtype.capitalize}").new(options, parent)
218
+ end
219
+ end
220
+
221
+ def compile_jext(yaml_str, js_class, options={})
222
+ original_source = yaml_str.read
223
+ preload_state = /^:?preload.*/.match original_source
224
+ preload_source = false
225
+ if preload_state
226
+ preload_state = YAML.load(preload_state.to_s)
227
+ preload = preload_state[:preload].split(/\s+/)
228
+ if preload.is_a? Array
229
+ preload_source = []
230
+ preload.each do |path|
231
+ path.gsub!(/^\.\//, '')
232
+ extend_path = "#{options[:filedir]}/#{path}"
233
+ preload_source << "#{path}:\n"
234
+ another_script = File.open(extend_path, 'rb') do |f|
235
+ while not f.eof
236
+ l = f.readline
237
+ preload_source << " #{l}"
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ load_source = preload_source ? preload_source.join('') + original_source : original_source
245
+ # puts load_source
246
+ ast = YAML.load(load_source)
247
+ # ap ast
248
+ # require "awesome_print"
249
+ # separate layout and config
250
+ layout = ast[:layout]
251
+ raise "require layout" if layout.nil?
252
+
253
+ config = ast[:config] || ast['config'] || {}
254
+ engine = ast[:engine] || ast['engine'] || {}
255
+
256
+ js_class = engine[:class] || js_class.capitalize
257
+
258
+ config.each do |k,v|
259
+ if v.has_key? :as
260
+ # TODO nested as
261
+ # lookup shared config
262
+ begin
263
+ sharedconfig = YAML.load(File.open("#{BASE_DIR}/sharedconfig/#{v[:as]}.yaml","r"))
264
+ rescue Exception => e
265
+ p "raise", __FILE__, __LINE__
266
+ puts "not found #{v[:as]} config in #{BASE_DIR}/sharedconfig/"
267
+ end
268
+ v.delete :as
269
+ v = sharedconfig.merge v
270
+ config[k] = v
271
+ end
272
+ end unless config.nil?
273
+
274
+ begin
275
+ root_node = build_node(layout, nil) do |xtype, opt|
276
+
277
+ unless config.nil?
278
+ opt.merge! config[xtype] unless config[xtype].nil?
279
+ opt.merge! config[opt[:id]] unless config[opt[:id]].nil?
280
+ end
281
+
282
+ if opt[:as]
283
+ # read sharedconfig
284
+ begin
285
+ sharedconfig = YAML.load(File.open("#{BASE_DIR}/sharedconfig/#{opt[:as]}.yaml","r"))
286
+ opt = sharedconfig.merge opt
287
+ rescue Exception => e
288
+ puts "#{e.message} not found #{opt[:as]} config in #{BASE_DIR}/sharedconfig/"
289
+ end
290
+ opt.delete :as
291
+ end
292
+
293
+ opt
294
+ end
295
+ rescue Exception => e
296
+ p "raise", __FILE__, __LINE__, e
297
+ raise e
298
+ end
299
+
300
+ # tree has built
301
+
302
+ # set to_extjs option
303
+ engine.merge! options
304
+ ExtNode.set_generator_config(engine)
305
+
306
+ # extjs_tree = root_node.to_extjs
307
+ event_template = []
308
+ ExtNode.get_events.each do |el, h|
309
+ event_template << "self.#{el}.on(\"#{h[0]}\", self.#{h[1]}, self);"
310
+ end
311
+
312
+ unless engine[:with_requirejs]
313
+
314
+ ui_class_content = %Q{
315
+ #{js_class}UI = Ext.extend(#{root_node.xtype.to_extclassname},{
316
+ #{JSON.pretty_generate(root_node.config).gsub!(/\{|\}/,"").strip!},
317
+ initComponent: function(){
318
+ Ext.applyIf(this,#{root_node.config={};nil}
319
+ #{JSON.pretty_generate(root_node.to_extjs, { space: "", max_nesting: 50})});
320
+ #{js_class}UI.superclass.initComponent.call(this);
321
+ var self = this;
322
+ #{event_template.join("\n")}
323
+ #{ExtNode.get_refs.map{|id, ref| "self._#{ref} = Ext.getCmp(\"#{id}\");"}.join("\n")}
324
+ }
325
+ });
326
+ }.strip
327
+ else
328
+
329
+ ui_class_content = %Q{
330
+ define(function(){
331
+ var #{js_class}UI = Ext.extend(#{root_node.xtype.to_extclassname},{
332
+ #{JSON.pretty_generate(root_node.config).gsub!(/\{|\}/,"").strip!},
333
+ initComponent: function(){
334
+ Ext.applyIf(this,#{root_node.config={};nil}
335
+ #{JSON.pretty_generate(root_node.to_extjs, { space: "", max_nesting: 50})});
336
+ #{js_class}UI.superclass.initComponent.call(this);
337
+ var self = this;
338
+ #{event_template.join("\n")}
339
+ // manually make auto ref
340
+ Ext.each(self.query('*'), function(element, index){
341
+ if(element.cmp_id) {
342
+ self["_" + element.cmp_id] = element;
343
+ }
344
+ });
345
+ }
346
+ });
347
+
348
+ return #{js_class}UI;
349
+ });
350
+ }.strip
351
+ end
352
+
353
+ # INQUIRY
354
+ eve_inqury = ""
355
+ if engine[:mode] == "inqury"
356
+ # Must have base
357
+ base_model = engine[:base]
358
+ # TODO
359
+ eve_inqury = %Q{
360
+ self.search.on({
361
+ click: function(){
362
+ if(self.frm.isValid()){
363
+ var params = Ext.apply(self.frm.serializeObject({ onlyDirty: false}), { model: "#{base_model}" });
364
+ self.grd.fetch(params);
365
+ }
366
+ }
367
+ });
368
+
369
+ self.toggleWidth.on({
370
+ click: function() {
371
+ var el_id = "#" + this.el.id;
372
+ var filter_id = "#" + self.frm.id;
373
+ var pressed = $(el_id).attr("is_pressed");
374
+ if(pressed == "t"){
375
+ $(el_id).attr("is_pressed", "f");
376
+ this.setText("Expand Width");
377
+ self.grd.setSize(780); // TODO
378
+ self.grd.doLayout();
379
+ $(filter_id).parent().fadeIn();
380
+ } else{
381
+ $(el_id).attr("is_pressed", "t");
382
+ this.setText("Reduce Width");
383
+ var w = $(window.document).width() - 50;
384
+ self.grd.setSize(w);
385
+ self.grd.doLayout();
386
+ $(filter_id).parent().hide();
387
+ }
388
+ }
389
+ });
390
+
391
+ self.exportXlsx.on({
392
+ click: function() {
393
+ if(self.frm.isValid()){
394
+ var params = Ext.apply(self.frm.serializeObject({ onlyDirty: false}), { model: "#{base_model}", export_xlsx: true });
395
+
396
+ if(self.grd.store.getSortState()){
397
+ var sort = self.grd.store.getSortState();
398
+
399
+ params = Ext.apply(params, {
400
+ sort: sort.field,
401
+ dir: sort.direction
402
+ });
403
+ }
404
+
405
+ var url = "/inquiry?" + Ext.urlEncode(params);
406
+
407
+ window.open(url, "_blank")
408
+ }
409
+ }
410
+ });
411
+
412
+ self.exportCsv.on({
413
+ click: function() {
414
+ if(self.frm.isValid()){
415
+ var params = Ext.apply(self.frm.serializeObject({ onlyDirty: false}), { model: "#{base_model}", export_csv: true });
416
+
417
+ if(self.grd.store.getSortState()){
418
+ var sort = self.grd.store.getSortState();
419
+
420
+ params = Ext.apply(params, {
421
+ sort: sort.field,
422
+ dir: sort.direction
423
+ });
424
+ }
425
+
426
+ var url = "/inquiry?" + Ext.urlEncode(params);
427
+
428
+ window.open(url, "_blank")
429
+ }
430
+ }
431
+ });
432
+
433
+ self.exportPdf.on({
434
+ click: function() {
435
+ if(self.frm.isValid()){
436
+ var params = Ext.apply(self.frm.serializeObject({ onlyDirty: false}), { model: "#{base_model}", export_pdf: true });
437
+
438
+ if(self.grd.store.getSortState()){
439
+ var sort = self.grd.store.getSortState();
440
+
441
+ params = Ext.apply(params, {
442
+ sort: sort.field,
443
+ dir: sort.direction
444
+ });
445
+ }
446
+
447
+ var url = "/inquiry?" + Ext.urlEncode(params);
448
+
449
+ window.open(url, "_blank")
450
+ }
451
+ }
452
+ });
453
+
454
+ self.grd.on({
455
+ datachanged: function () {
456
+ var st = self.grd.getStore();
457
+ try {
458
+
459
+ if(st && st.reader.jsonData.grand_summary){
460
+ var summary = st.reader.jsonData.grand_summary;
461
+ self.grandSummary.fillData(summary);
462
+ }
463
+
464
+ if(st && st.reader.jsonData.page_summary){
465
+ var summary = st.reader.jsonData.page_summary;
466
+ self.pageSummary.fillData(summary);
467
+ }
468
+
469
+ } catch(e){
470
+ console.log("summary stuff " + e);
471
+ }
472
+ }
473
+ });
474
+
475
+ }
476
+ end
477
+ #################################################
478
+
479
+ # REPORT
480
+ eve_report = ""
481
+ if engine[:mode] == "report"
482
+ eve_inqury = %Q{
483
+ self.search.on({
484
+ click: function() {
485
+ var f = $("iframe")
486
+ if(f){
487
+ var url = f.attr("src");
488
+ var ff = f[0];
489
+ var fragments = url.split("?");
490
+ var host = fragments[0];
491
+ var params = fragments[1];
492
+ params = Ext.urlDecode(params);
493
+
494
+ // reset params
495
+ for(var k in params){
496
+ console.log("key", k)
497
+ if(k != "cmd" && k != "code"){
498
+ delete params[k];
499
+ }
500
+ }
501
+ var filter = self.frm.serializeObject();
502
+
503
+ var src = host + "?" + Ext.urlEncode(Ext.apply(params, filter));
504
+ ff.contentWindow.location = src;
505
+ } else{
506
+ Ext.Notify.error("Cannot Render");
507
+ }
508
+ }
509
+ });
510
+ }
511
+ end
512
+
513
+ #################################################
514
+
515
+ unless engine[:with_requirejs]
516
+ event_class_content = %Q{
517
+ #{js_class} = Ext.extend(#{js_class}UI,{
518
+ constructor: function (config) {
519
+ config = config || {};
520
+ Ext.apply(this, config);
521
+ #{js_class}.superclass.constructor.call(this)
522
+ },
523
+
524
+ initComponent: function(){
525
+ #{js_class}.superclass.initComponent.call(this);
526
+ var self = x = this;
527
+ // use x for debugging at console
528
+ #{eve_report}
529
+ #{eve_inqury}
530
+ }
531
+ });
532
+ }.strip
533
+ else
534
+ event_class_content = %Q{
535
+ define(["./#{js_class}.ui"], function(#{js_class}UI){
536
+ var #{js_class} = Ext.extend(#{js_class}UI,{
537
+ constructor: function (config) {
538
+ config = config || {};
539
+ Ext.apply(this, config);
540
+ #{js_class}.superclass.constructor.call(this)
541
+ },
542
+
543
+ initComponent: function(){
544
+ #{js_class}.superclass.initComponent.call(this);
545
+ var self = x = this;
546
+ // use x for debugging at console
547
+ #{eve_report}
548
+ #{eve_inqury}
549
+ }
550
+ });
551
+
552
+ return #{js_class};
553
+ });
554
+ }.strip
555
+ end # end engine.with_requirejs
556
+
557
+ # replace js code
558
+ if ui_class_content.match(/<js>(.*)<\/js>/im)
559
+ buf = []
560
+ ui_class_content.each_line do |line|
561
+ jscode = line.match(/<js>(.*)<\/js>/im)
562
+ unless jscode.nil?
563
+ line.gsub!(/\"[^:]*<js>(.*)<\/js>.*\"/im,'\1')
564
+ line.gsub!(/\\n/,"")
565
+ line.gsub!(/\\\"/,'"')
566
+ end
567
+ # TODO
568
+ # buf << JSMin.minify(line)
569
+ buf << line
570
+ end
571
+ ui_class_content = buf.join("").strip
572
+ end
573
+
574
+ ExtNode.reset_generator_config
575
+
576
+ return {ui_class_content: ui_class_content,
577
+ event_class_content: event_class_content}
578
+ end