netzke-basepack 0.5.5.1 → 0.5.6

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 (41) hide show
  1. data/CHANGELOG.rdoc +16 -1
  2. data/README.rdoc +31 -56
  3. data/Rakefile +2 -2
  4. data/TODO.rdoc +3 -0
  5. data/javascripts/basepack.js +70 -30
  6. data/lib/app/models/netzke_auto_column.rb +1 -53
  7. data/lib/app/models/netzke_auto_field.rb +4 -0
  8. data/lib/app/models/netzke_auto_table.rb +61 -0
  9. data/lib/netzke-basepack.rb +13 -7
  10. data/lib/netzke/active_record/basepack.rb +28 -0
  11. data/lib/netzke/active_record/data_accessor.rb +2 -0
  12. data/lib/netzke/basic_app.rb +3 -4
  13. data/lib/netzke/{basic_app_extras → basic_app}/statusbar_ext.js +0 -0
  14. data/lib/netzke/data_accessor.rb +2 -0
  15. data/lib/netzke/ext.rb +1 -1
  16. data/lib/netzke/fields_configurator.rb +22 -6
  17. data/lib/netzke/form_panel.rb +20 -11
  18. data/lib/netzke/form_panel/form_panel_api.rb +78 -0
  19. data/lib/netzke/form_panel/form_panel_js.rb +143 -0
  20. data/lib/netzke/{form_panel_extras → form_panel}/javascripts/netzkefileupload.js +0 -0
  21. data/lib/netzke/{form_panel_extras → form_panel}/javascripts/xcheckbox.js +0 -0
  22. data/lib/netzke/grid_panel.rb +33 -24
  23. data/lib/netzke/grid_panel/grid_panel_api.rb +358 -0
  24. data/lib/netzke/grid_panel/grid_panel_js.rb +747 -0
  25. data/lib/netzke/{grid_panel_extras → grid_panel}/javascripts/filters.js +0 -0
  26. data/lib/netzke/{grid_panel_extras → grid_panel}/javascripts/rows-dd.js +0 -0
  27. data/lib/netzke/grid_panel/record_form_window.rb +44 -0
  28. data/lib/netzke/panel.rb +1 -3
  29. data/lib/netzke/property_editor.rb +2 -0
  30. data/lib/netzke/{property_editor_extras → property_editor}/helper_model.rb +2 -2
  31. data/lib/netzke/search_panel.rb +3 -3
  32. data/lib/netzke/window.rb +9 -3
  33. data/test/unit/grid_panel_test.rb +0 -2
  34. data/test/unit/helper_model_test.rb +2 -2
  35. metadata +16 -15
  36. data/lib/netzke/field_model.rb +0 -131
  37. data/lib/netzke/form_panel_api.rb +0 -78
  38. data/lib/netzke/form_panel_js.rb +0 -141
  39. data/lib/netzke/grid_panel_api.rb +0 -356
  40. data/lib/netzke/grid_panel_extras/record_form_window.rb +0 -46
  41. data/lib/netzke/grid_panel_js.rb +0 -725
@@ -1,141 +0,0 @@
1
- module Netzke
2
- module FormPanelJs
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def js_base_class
9
- "Ext.FormPanel"
10
- end
11
-
12
- def js_extend_properties
13
- {
14
- :body_style => 'padding:5px 5px 0',
15
- :auto_scroll => true,
16
- :label_width => 150,
17
- :default_type => 'textfield',
18
-
19
- :init_component => <<-END_OF_JAVASCRIPT.l,
20
- function(){
21
- var recordFields = []; // Record
22
- this.items = [];
23
- var index = 0;
24
-
25
- // Process columns
26
- Ext.each(this.clmns, function(field){
27
- if (typeof field == 'string') field = {name:field}; // normalize field
28
- if (!field.hidden || field.name == 'id') {
29
- recordFields.push({name:field.name, mapping:index++});
30
-
31
- var defaultColumnConfig = Ext.apply({}, this.defaultColumnConfig);
32
- var columnConfig = Ext.apply(defaultColumnConfig, field);
33
-
34
- // apply dynamically defined properties
35
- Ext.apply(columnConfig, {
36
- fieldLabel: columnConfig.fieldLabel || columnConfig.name.humanize(),
37
- hideLabel: columnConfig.hidden, // completely hide fields marked "hidden"
38
- parentId: this.id,
39
- name: columnConfig.name,
40
- checked: columnConfig.xtype == "xcheckbox" ? columnConfig.value : null // checkbox state
41
- });
42
-
43
- this.items.push(columnConfig);
44
- }
45
- }, this);
46
-
47
- var Record = Ext.data.Record.create(recordFields);
48
- this.reader = new Ext.data.RecordArrayReader({root:"data"}, Record);
49
-
50
- delete this.clmns; // we don't need them anymore
51
-
52
- // Now let Ext.form.FormPanel do the rest
53
- #{js_full_class_name}.superclass.initComponent.call(this);
54
-
55
- // Apply event
56
- this.addEvents('apply');
57
- }
58
- END_OF_JAVASCRIPT
59
-
60
- # Defaults for each field
61
- :defaults => {
62
- :anchor => '-20', # to leave some space for the scrollbar
63
- # :width => 180, # we do NOT want fixed size because it doesn't look nice when resizing
64
- :listeners => {
65
- # On "return" key, submit the form
66
- :specialkey => {
67
- :fn => <<-END_OF_JAVASCRIPT.l
68
- function(field, event){
69
- if (event.getKey() == 13) this.ownerCt.onApply();
70
- }
71
- END_OF_JAVASCRIPT
72
- }
73
- }
74
- },
75
-
76
- :default_column_config => config_columns.inject({}){ |r, c| r.merge!({
77
- c[:name] => c[:default]
78
- }) },
79
-
80
- :set_form_values => <<-END_OF_JAVASCRIPT.l,
81
- function(values){
82
- this.form.loadRecord(this.reader.readRecords({data:[values]}).records[0]);
83
- }
84
- END_OF_JAVASCRIPT
85
-
86
- :load_record => <<-END_OF_JAVASCRIPT.l,
87
- function(id, neighbour){
88
- this.netzkeLoad({id:id});
89
- }
90
- END_OF_JAVASCRIPT
91
-
92
- # :previous => <<-END_OF_JAVASCRIPT.l,
93
- # function() {
94
- # var currentId = this.form.getValues().id;
95
- # this.loadRecord(currentId, 'previous');
96
- # }
97
- # END_OF_JAVASCRIPT
98
- #
99
- # :next => <<-END_OF_JAVASCRIPT.l,
100
- # function() {
101
- # var currentId = this.form.getValues().id;
102
- # this.loadRecord(currentId, 'next');
103
- # }
104
- # END_OF_JAVASCRIPT
105
-
106
- :on_apply => <<-END_OF_JAVASCRIPT.l
107
- function() {
108
- if (this.fireEvent('apply', this)) {
109
- var values = this.getForm().getValues();
110
- for (var k in values) {
111
- if (values[k] == "") {delete values[k]}
112
- }
113
- if (this.fileUpload) {
114
- // Not a Netzke's standard API call, because the form is multipart
115
- this.getForm().submit({
116
- url: this.id + '__netzke_submit',
117
- params: {
118
- data: Ext.encode(values)
119
- },
120
- failure: function(form, action){
121
- // It will always be failure, as we don't play along with the Ext success indication (not returning {success: true})
122
- this.bulkExecute(Ext.decode(action.response.responseText));
123
- this.fireEvent('submitsuccess');
124
- },
125
- scope: this
126
- });
127
- } else {
128
- // Submit the data and process the result
129
- this.netzkeSubmit(Ext.apply((this.baseParams || {}), {data:Ext.encode(values)}), function(result){
130
- if (result === "ok") {this.fireEvent("submitsuccess")};
131
- }, this);
132
- }
133
- }
134
- }
135
- END_OF_JAVASCRIPT
136
- }
137
- end
138
-
139
- end
140
- end
141
- end
@@ -1,356 +0,0 @@
1
- module Netzke
2
- module GridPanelApi
3
- def post_data(params)
4
- success = true
5
- mod_records = {}
6
- [:create, :update].each do |operation|
7
- data = ActiveSupport::JSON.decode(params["#{operation}d_records"]) if params["#{operation}d_records"]
8
- if !data.nil? && !data.empty? # data may be nil for one of the operations
9
- mod_records[operation] = process_data(data, operation)
10
- mod_records[operation] = nil if mod_records[operation].empty?
11
- end
12
- break if !success
13
- end
14
- {
15
- :update_new_records => mod_records[:create],
16
- :update_mod_records => mod_records[:update] || {},
17
- :feedback => @flash
18
- }
19
- end
20
-
21
- def get_data(params = {})
22
- if !ext_config[:prohibit_read]
23
- records = get_records(params)
24
- {:data => records.map{|r| r.to_array(normalized_columns, self)}, :total => ext_config[:enable_pagination] && records.total_entries}
25
- else
26
- flash :error => "You don't have permissions to read data"
27
- {:feedback => @flash}
28
- end
29
- end
30
-
31
- def delete_data(params)
32
- if !ext_config[:prohibit_delete]
33
- record_ids = ActiveSupport::JSON.decode(params[:records])
34
- klass = config[:data_class_name].constantize
35
- klass.destroy(record_ids)
36
- {:feedback => "Deleted #{record_ids.size} record(s)", :load_store_data => get_data}
37
- else
38
- {:feedback => "You don't have permissions to delete data"}
39
- end
40
- end
41
-
42
- # Given an index of a column among enabled (non-excluded) columns, provides the index (position) in the table
43
- def normalize_index(index)
44
- norm_index = 0
45
- index.times do
46
- while true do
47
- norm_index += 1
48
- break unless normalized_columns[norm_index][:excluded]
49
- end
50
- end
51
- norm_index
52
- end
53
-
54
- def resize_column(params)
55
- raise "Called api_resize_column while not configured to do so" if ext_config[:enable_column_resize] == false
56
- column_at(normalize_index(params[:index].to_i))[:width] = params[:size].to_i
57
- save_columns!
58
- {}
59
- end
60
-
61
- def hide_column(params)
62
- raise "Called api_hide_column while not configured to do so" if ext_config[:enable_column_hide] == false
63
- column_at(normalize_index(params[:index].to_i))[:hidden] = params[:hidden].to_b
64
- save_columns!
65
- {}
66
- end
67
-
68
- def move_column(params)
69
- raise "Called api_move_column while not configured to do so" if ext_config[:enable_column_move] == false
70
- remove_from = normalize_index(params[:old_index].to_i)
71
- insert_to = normalize_index(params[:new_index].to_i)
72
- column_to_move = columns.delete_at(remove_from)
73
- columns.insert(insert_to, column_to_move)
74
- save_columns!
75
-
76
- # reorder the columns on the client side (still not sure if it's not an overkill)
77
- # {:reorder_columns => columns.map(&:name)} # Well, I think it IS an overkill - commented out
78
- # until proven to be necessary
79
- {}
80
- end
81
-
82
- # Return the choices for the column
83
- def get_combobox_options(params)
84
- column = params[:column]
85
- query = params[:query]
86
- {:data => config[:data_class_name].constantize.options_for(column, query).map{|s| [s]}}
87
- end
88
-
89
- # Returns searchlogic's search with all the conditions
90
- def get_search(params)
91
- @search ||= begin
92
- raise ArgumentError, "No data_class_name specified for widget '#{name}'" if !config[:data_class_name]
93
-
94
- # make params coming from Ext grid filters understandable by searchlogic
95
- search_params = normalize_params(params)
96
-
97
- # merge with conditions coming from the config
98
- search_params[:conditions].deep_merge!(config[:conditions] || {})
99
-
100
- # merge with extra conditions (in searchlogic format, come from the extended search form)
101
- search_params[:conditions].deep_merge!(
102
- normalize_extra_conditions(ActiveSupport::JSON.decode(params[:extra_conditions]))
103
- ) if params[:extra_conditions]
104
-
105
- search = config[:data_class_name].constantize.search(search_params)
106
-
107
- # applying scopes
108
- scopes.each do |s|
109
- if s.is_a?(Array)
110
- scope_name, *args = s
111
- search.send(scope_name, *args)
112
- else
113
- search.send(s, true)
114
- end
115
- end
116
-
117
- search
118
- end
119
- end
120
-
121
- def configuration_panel__columns__get_combobox_options(params)
122
- query = params[:query]
123
-
124
- data_arry = case params[:column]
125
- when "name"
126
- predefined_columns.map{ |c| c[:name].to_s }
127
- else
128
- raise RuntimeError, "Don't know about options for column '#{params[:column]}'"
129
- end
130
-
131
- {:data => data_arry.grep(/^#{query}/).map{ |n| [n] }}.to_nifty_json
132
- end
133
-
134
- protected
135
-
136
- # operation => :update || :create
137
- def process_data(data, operation)
138
- success = true
139
- # mod_record_ids = []
140
- mod_records = {}
141
- if !ext_config["prohibit_#{operation}".to_sym]
142
- klass = config[:data_class_name].constantize
143
- modified_records = 0
144
- data.each do |record_hash|
145
- id = record_hash.delete('id')
146
- record = operation == :create ? klass.new : klass.find(id)
147
- success = true
148
-
149
- # merge with strong default attirbutes
150
- record_hash.merge!(config[:strong_default_attrs]) if config[:strong_default_attrs]
151
-
152
- # process all attirubutes for this record
153
- record_hash.each_pair do |k,v|
154
- begin
155
- record.send("#{k}=",v)
156
- rescue ArgumentError => exc
157
- flash :error => exc.message
158
- success = false
159
- break
160
- end
161
- end
162
-
163
- # try to save
164
- # modified_records += 1 if success && record.save
165
- mod_records[id] = record.to_array(columns, self) if success && record.save
166
- # mod_record_ids << id if success && record.save
167
-
168
- # flash eventual errors
169
- if !record.errors.empty?
170
- success = false
171
- record.errors.each_full do |msg|
172
- flash :error => msg
173
- end
174
- end
175
- end
176
- # flash :notice => "#{operation.to_s.capitalize}d #{modified_records} record(s)"
177
- else
178
- success = false
179
- flash :error => "You don't have permissions to #{operation} data"
180
- end
181
- mod_records
182
- end
183
-
184
- # get records
185
- def get_records(params)
186
- # Restore params from widget_session if requested
187
- if params[:with_last_params]
188
- params = widget_session[:last_params]
189
- else
190
- # remember the last params
191
- widget_session[:last_params] = params
192
- end
193
-
194
- search = get_search(params)
195
-
196
- # sorting
197
- if params[:sort]
198
- assoc, method = params[:sort].split('__')
199
- sort_string = method.nil? ? assoc : "#{assoc}_#{method}"
200
- sort_string = (params[:dir] == "ASC" ? "ascend_by_" : "descend_by_") + sort_string
201
- search.order(sort_string)
202
- end
203
-
204
- # pagination
205
- if ext_config[:enable_pagination]
206
- per_page = ext_config[:rows_per_page]
207
- page = params[:limit] ? params[:start].to_i/params[:limit].to_i + 1 : 1
208
- search.paginate(:per_page => per_page, :page => page)
209
- else
210
- search.all
211
- end
212
- end
213
-
214
- # Create record with form
215
- def create_new_record(params)
216
- form_data = ActiveSupport::JSON.decode(params[:data])
217
- res = aggregatee_instance(:new_record_form).create_or_update_record(form_data)
218
-
219
- if res[:set_form_values]
220
- # successful creation
221
- res[:set_form_values] = nil
222
- res[:on_successfull_record_creation] = true
223
- end
224
- res
225
- end
226
-
227
- # Move rows
228
- def move_rows(params)
229
- if defined?(ActsAsList) && data_class.ancestors.include?(ActsAsList::InstanceMethods)
230
- ids = JSON.parse(params[:ids]).reverse
231
- ids.each_with_index do |id, i|
232
- r = data_class.find(id)
233
- r.insert_at(params[:new_index].to_i + i + 1)
234
- end
235
- else
236
- raise RuntimeError, "Data class should 'acts_as_list' to support moving rows"
237
- end
238
- {}
239
- end
240
-
241
- # When providing the edit_form aggregatee, fill in the form with the requested record
242
- def load_aggregatee_with_cache(params)
243
- if params[:id] == 'editForm'
244
- aggregatees[:edit_form].merge!(:record_id => params[:record_id])
245
- end
246
-
247
- super
248
- end
249
-
250
- # Search scopes, in searchlogic format
251
- def scopes
252
- @scopes ||= config[:scopes] || []
253
- end
254
-
255
- # Converts Ext.grid.GridFilters filters to searchlogic conditions, e.g.
256
- # {"0" => {
257
- # "data" => {
258
- # "type" => "numeric",
259
- # "comparison" => "gt",
260
- # "value" => 10 },
261
- # "field" => "id"
262
- # },
263
- # "1" => {
264
- # "data" => {
265
- # "type" => "string",
266
- # "value" => "pizza"
267
- # },
268
- # "field" => "food_name"
269
- # }}
270
- #
271
- # =>
272
- #
273
- # {"id_gt" => 100, "food_name_contains" => "pizza"}
274
- def convert_filters(column_filter)
275
- res = {}
276
- column_filter.each_pair do |k,v|
277
- field = v["field"].dup
278
- case v["data"]["type"]
279
- when "string"
280
- field << "_contains"
281
- when "numeric"
282
- field << "_#{v["data"]["comparison"]}"
283
- end
284
- value = v["data"]["value"]
285
- res.merge!({field => value})
286
- end
287
- res
288
- end
289
-
290
- def normalize_extra_conditions(conditions)
291
- conditions.deep_convert_keys{|k| k.to_s.gsub("__", "_").to_sym}
292
- end
293
-
294
- # make params understandable to searchlogic
295
- def normalize_params(params)
296
- # filters
297
- conditions = params[:filter] && convert_filters(params[:filter])
298
-
299
- normalized_conditions = {}
300
- conditions && conditions.each_pair do |k, v|
301
- assoc, method = k.split('__')
302
- normalized_conditions.merge!(method.nil? ? {assoc => v} : {assoc => {method => v}})
303
- end
304
-
305
- {:conditions => normalized_conditions}
306
- end
307
-
308
- ## Edit in form specific API
309
- def new_record_form__netzke_submit(params)
310
- res = aggregatee_instance(:new_record_form).netzke_submit(params)
311
-
312
- if res[:set_form_values]
313
- # successful creation
314
- res[:set_form_values] = nil
315
- res.merge!({
316
- :parent => {:on_successfull_record_creation => true}
317
- })
318
- end
319
- res.to_nifty_json
320
- end
321
-
322
- def check_for_positive_result(res)
323
- if res[:set_form_values]
324
- # successful creation
325
- res[:set_form_values] = nil
326
- res.merge!({
327
- :parent => {:on_successfull_edit => true}
328
- })
329
- end
330
- end
331
-
332
- def edit_form__netzke_submit(params)
333
- res = aggregatee_instance(:edit_form).netzke_submit(params)
334
-
335
- check_for_positive_result(res)
336
-
337
- res.to_nifty_json
338
- end
339
-
340
- def multi_edit_form__netzke_submit(params)
341
- ids = ActiveSupport::JSON.decode(params.delete(:ids))
342
-
343
- res = {}
344
- ids.each do |id|
345
- form_instance = aggregatee_instance(:edit_form, :record => data_class.find(id))
346
- res = form_instance.netzke_submit(params)
347
- break if !res[:set_form_values]
348
- end
349
-
350
- check_for_positive_result(res)
351
-
352
- res.to_nifty_json
353
- end
354
-
355
- end
356
- end