netzke-basepack 0.5.12 → 0.5.13
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.rdoc +13 -0
- data/Rakefile +2 -2
- data/TODO.rdoc +4 -0
- data/lib/app/models/netzke_persistent_array_auto_model.rb +1 -1
- data/lib/netzke/active_record/attributes.rb +1 -1
- data/lib/netzke/active_record/combobox_options.rb +3 -33
- data/lib/netzke/data_accessor.rb +46 -26
- data/lib/netzke/form_panel.rb +11 -5
- data/lib/netzke/form_panel/form_panel_api.rb +5 -1
- data/lib/netzke/form_panel/form_panel_fields.rb +58 -56
- data/lib/netzke/grid_panel.rb +34 -38
- data/lib/netzke/grid_panel/grid_panel_api.rb +11 -2
- data/lib/netzke/grid_panel/grid_panel_columns.rb +79 -65
- data/lib/netzke/grid_panel/grid_panel_js.rb +2 -736
- data/lib/netzke/grid_panel/javascripts/advanced_search.js +65 -0
- data/lib/netzke/grid_panel/javascripts/edit_in_form.js +47 -0
- data/lib/netzke/grid_panel/javascripts/grid_panel_pre.js +562 -0
- data/lib/netzke/json_array_editor.rb +7 -1
- data/lib/netzke/tab_panel.rb +1 -0
- data/stylesheets/basepack.css +1 -1
- metadata +10 -7
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
= v0.5.13 - 2010-08-11
|
2
|
+
* regression
|
3
|
+
* combobox options configuration again has effect
|
4
|
+
|
5
|
+
* bug fix
|
6
|
+
* when a TabPanel was used as a standalone widget, the first tab was rendered empty
|
7
|
+
* Grid/FormPanel: dynamically changing of columns doesn't erase those column settings that are not configurable via GUI, but which were specified in the code
|
8
|
+
|
9
|
+
* enhancements
|
10
|
+
* scopes can now be specified for an association combobox in Grid/FormPanels
|
11
|
+
* GridPanel: you can now configure add/edit/multi_edit/search panels (e.g. to override the fields) and corresponding windows (e.g. to override the title)
|
12
|
+
* minor refactoring GridPanel: moved static js out of grid_panel_js.rb
|
13
|
+
|
1
14
|
= v0.5.12 - 2010-06-21
|
2
15
|
* Fix: when used with Bundler, was crashing with the "uninitialized constant" exception
|
3
16
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'jeweler'
|
3
3
|
Jeweler::Tasks.new do |gemspec|
|
4
|
-
gemspec.version = "0.5.
|
4
|
+
gemspec.version = "0.5.13"
|
5
5
|
gemspec.name = "netzke-basepack"
|
6
6
|
gemspec.summary = "Pre-built Rails + ExtJS widgets for your RIA"
|
7
7
|
gemspec.description = "A set of full-featured extendible Netzke widgets (such as FormPanel, GridPanel, Window, BorderLayoutPanel, etc) which can be used as building block for your RIA"
|
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
gemspec.homepage = "http://github.com/skozlov/netzke-basepack"
|
10
10
|
gemspec.rubyforge_project = "netzke-basepack"
|
11
11
|
gemspec.authors = ["Sergei Kozlov"]
|
12
|
-
gemspec.add_dependency("netzke-core", ">=0.5.
|
12
|
+
gemspec.add_dependency("netzke-core", ">=0.5.4")
|
13
13
|
gemspec.add_dependency("searchlogic", ">=2.0.0")
|
14
14
|
gemspec.add_dependency("will_paginate", ">=2.0.0")
|
15
15
|
gemspec.add_dependency("acts_as_list", ">=0.1.2")
|
data/TODO.rdoc
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
== Priority
|
2
2
|
* Add icons to buttons to actions (toolbars/menus)
|
3
3
|
* On grid refresh, reset the dirty fields, so that the "Apply" button doesn't do anything
|
4
|
+
* GridPanel's read_only vs editable (doesn't work now) options
|
5
|
+
* Solve the confusion about columns being stored in the persistent config
|
6
|
+
* Inclusion of css in a stand-alone widget
|
7
|
+
* Rename the "l" method to something else
|
4
8
|
|
5
9
|
== Foolproof
|
6
10
|
* Should not be possible delete the "ID" field from grids/forms
|
@@ -41,7 +41,7 @@ class NetzkePersistentArrayAutoModel < ActiveRecord::Base
|
|
41
41
|
# only select those attributes that were provided to us as columns. The rest is ignored.
|
42
42
|
column_names = config[:columns].map{ |c| c[:name] }
|
43
43
|
clean_data = data.collect{ |c| c.reject{ |k,v| !column_names.include?(k.to_s) } }
|
44
|
-
|
44
|
+
Rails.logger.debug "!!! clean_data: #{clean_data.inspect}\n"
|
45
45
|
self.delete_all
|
46
46
|
self.create(clean_data)
|
47
47
|
end
|
@@ -56,7 +56,7 @@ module Netzke::ActiveRecord::Attributes
|
|
56
56
|
in_columns_hash = columns_hash[attr_name] && {:name => attr_name, :attr_type => columns_hash[attr_name].type, :default_value => columns_hash[attr_name].default} || {} # {:virtual => true} # if nothing found in columns, mark it as "virtual" or not?
|
57
57
|
if in_columns_hash.empty?
|
58
58
|
# If not among the model columns, it's either virtual, or an association
|
59
|
-
merged = association_attr?(attr_name) ?
|
59
|
+
merged = association_attr?(attr_name) ? declared.merge!(:name => attr_name) : declared.merge(:virtual => true)
|
60
60
|
else
|
61
61
|
# .. otherwise merge with what's declared
|
62
62
|
merged = in_columns_hash.merge(declared)
|
@@ -1,43 +1,13 @@
|
|
1
1
|
module Netzke::ActiveRecord::ComboboxOptions
|
2
2
|
module ClassMethods
|
3
|
-
# TODO: rename to netzke_options_for (to avoid
|
3
|
+
# TODO: rename to netzke_options_for (to avoid naming conflicts)
|
4
4
|
def options_for(column, query = "")
|
5
|
-
|
6
|
-
|
7
|
-
# options = NetzkePreference[:combobox_options] || {}
|
8
|
-
# if options[column]
|
9
|
-
# options[column].select{ |o| o.index(/^#{query}/) }
|
10
|
-
if respond_to?("#{column}_combobox_options")
|
11
|
-
# AR model provides the choices itself
|
12
|
-
send("#{column}_combobox_options", query)
|
13
|
-
else
|
14
|
-
# Returns all unique values for a column, filtered with <tt>query</tt>
|
15
|
-
if (assoc_name, *assoc_method = column.split('__')).size > 1
|
16
|
-
# column is an association column
|
17
|
-
assoc_method = assoc_method.join('__') # in case we get something like country__continent__name
|
18
|
-
association = reflect_on_association(assoc_name.to_sym) || raise(NameError, "Association #{assoc_name} not known for class #{name}")
|
19
|
-
association.klass.options_for(assoc_method, query)
|
20
|
-
else
|
21
|
-
column = assoc_name
|
22
|
-
if self.column_names.include?(column)
|
23
|
-
# it's simply a column in the table
|
24
|
-
records = query.empty? ? find_by_sql("select distinct #{column} from #{table_name}") : find_by_sql("select distinct #{column} from #{table_name} where #{column} like '#{query}%'")
|
25
|
-
records.map{|r| r.send(column)}
|
26
|
-
else
|
27
|
-
# it's a "virtual" column - the least effective search
|
28
|
-
records = self.find(:all).map{|r| r.send(column)}.uniq
|
29
|
-
query.empty? ? records : records.select{|r| r.index(/^#{query}/)}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
5
|
+
records = query.empty? ? find_by_sql("select distinct #{column} from #{table_name}") : find_by_sql("select distinct #{column} from #{table_name} where #{column} like '#{query}%'")
|
6
|
+
records.map{|r| r.send(column)}
|
33
7
|
end
|
34
8
|
end
|
35
9
|
|
36
|
-
module InstanceMethods
|
37
|
-
end
|
38
|
-
|
39
10
|
def self.included(receiver)
|
40
11
|
receiver.extend ClassMethods
|
41
|
-
receiver.send :include, InstanceMethods
|
42
12
|
end
|
43
13
|
end
|
data/lib/netzke/data_accessor.rb
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
require "netzke/active_record/data_accessor"
|
2
|
+
require "searchlogic"
|
2
3
|
|
3
4
|
module Netzke
|
4
|
-
# This module is included into such data-driven widgets as GridPanel, FormPanel, etc.
|
5
|
-
# flexible pre-configuration of (virtual) attributes.
|
6
|
-
#
|
7
|
-
# TODO: show examples of how to create the helpers
|
5
|
+
# This module is included into such data-driven widgets as GridPanel, FormPanel, etc.
|
8
6
|
module DataAccessor
|
9
|
-
|
10
|
-
# This method should be called from the constructor of the widget. It dynamically includes:
|
11
|
-
# 1) helpers into the data model for this widget; those may contain instance methods used as virtual attributes
|
12
|
-
# 2) generic (used by all "data accessor" widgets) extensions into the data model for this widget
|
7
|
+
# This method should be called from the constructor of the widget.
|
13
8
|
def apply_helpers
|
14
9
|
# Generic extensions to the data model
|
15
10
|
if data_class # because some widgets, like FormPanel, may have it optional
|
@@ -17,6 +12,41 @@ module Netzke
|
|
17
12
|
end
|
18
13
|
end
|
19
14
|
|
15
|
+
# Returns options for comboboxes in grids/forms
|
16
|
+
def combobox_options_for_column(column, method_options = {})
|
17
|
+
# First, check if we have options for this column defined in persistent storage
|
18
|
+
options = column[:combobox_options] && column[:combobox_options].split("\n")
|
19
|
+
if options
|
20
|
+
(method_options[:query].nil? ? options : options.select{ |o| o.index(/^#{method_options[:query]}/) }).map{ |el| [el] }
|
21
|
+
else
|
22
|
+
assoc, assoc_method = assoc_and_assoc_method_for_column(column)
|
23
|
+
|
24
|
+
if assoc
|
25
|
+
# Options for an asssociation attribute
|
26
|
+
|
27
|
+
search = assoc.klass.searchlogic
|
28
|
+
|
29
|
+
# apply scopes
|
30
|
+
method_options[:scopes] && method_options[:scopes].each do |s|
|
31
|
+
if s.is_a?(Array)
|
32
|
+
scope_name, *args = s
|
33
|
+
search.send(scope_name, *args)
|
34
|
+
else
|
35
|
+
search.send(s, true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# apply query
|
40
|
+
search.send("#{assoc_method}_like", "#{method_options[:query]}%") if method_options[:query]
|
41
|
+
|
42
|
+
search.all.map{ |r| [r.send(assoc_method)] }
|
43
|
+
else
|
44
|
+
# Options for a non-association attribute
|
45
|
+
data_class.options_for(column[:name], method_options[:query]).map{|s| [s]}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
20
50
|
# [:col1, "col2", {:name => :col3}] =>
|
21
51
|
# [{:name => "col1"}, {:name => "col2"}, {:name => "col3"}]
|
22
52
|
def normalize_attr_config(cols)
|
@@ -24,26 +54,16 @@ module Netzke
|
|
24
54
|
c.is_a?(Symbol) || c.is_a?(String) ? {:name => c.to_s} : c.merge(:name => c[:name].to_s)
|
25
55
|
end
|
26
56
|
end
|
27
|
-
|
28
|
-
# Make sure we have keys as symbols, not strings
|
29
|
-
def normalize_array_of_columns(arry)
|
30
|
-
arry.map do |f|
|
31
|
-
if f.is_a?(Hash)
|
32
|
-
f.symbolize_keys
|
33
|
-
else
|
34
|
-
f.to_sym
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
57
|
|
39
|
-
#
|
40
|
-
def
|
41
|
-
|
58
|
+
# Returns association and association method for a column
|
59
|
+
def assoc_and_assoc_method_for_column(c)
|
60
|
+
assoc_name, assoc_method = c[:name].split('__')
|
61
|
+
assoc = data_class.reflect_on_association(assoc_name.to_sym) if assoc_method
|
62
|
+
[assoc, assoc_method]
|
42
63
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
items.map{|c| normalize_column(c)}
|
64
|
+
|
65
|
+
def association_attr?(name)
|
66
|
+
!!name.to_s.index("__")
|
47
67
|
end
|
48
68
|
|
49
69
|
end
|
data/lib/netzke/form_panel.rb
CHANGED
@@ -65,15 +65,21 @@ module Netzke
|
|
65
65
|
apply_helpers
|
66
66
|
end
|
67
67
|
|
68
|
+
# Model class
|
68
69
|
# (We can't memoize this method because at some point we extend it, e.g. in Netzke::DataAccessor)
|
69
70
|
def data_class
|
70
71
|
@data_class ||= begin
|
71
72
|
klass = "Netzke::ModelExtensions::#{config[:model]}For#{short_widget_class_name}".constantize rescue nil
|
72
|
-
klass ||
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
klass || original_data_class
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Model class before model extensions are taken into account
|
78
|
+
def original_data_class
|
79
|
+
@original_data_class ||= begin
|
80
|
+
::ActiveSupport::Deprecation.warn("data_class_name option is deprecated. Use model instead", caller) if config[:data_class_name]
|
81
|
+
model_name = config[:model] || config[:data_class_name]
|
82
|
+
model_name && model_name.constantize
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
@@ -59,8 +59,12 @@ module Netzke
|
|
59
59
|
def get_combobox_options(params)
|
60
60
|
column = params[:column]
|
61
61
|
query = params[:query]
|
62
|
+
|
63
|
+
column = fields.detect{ |c| c[:name] == params[:column] }.try(:to_options!)
|
64
|
+
scopes = column.to_options[:scopes]
|
65
|
+
query = params[:query]
|
62
66
|
|
63
|
-
{:data =>
|
67
|
+
{:data => combobox_options_for_column(column, :query => query, :scopes => scopes)}
|
64
68
|
end
|
65
69
|
|
66
70
|
def configuration_panel__fields__get_combobox_options(params)
|
@@ -14,71 +14,70 @@ module Netzke
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
17
|
+
def fields
|
18
|
+
@fields ||= begin
|
19
|
+
flds = load_fields
|
20
|
+
reverse_merge_equally_named_fields(flds, initial_fields) if flds
|
21
|
+
flds ||= initial_fields
|
22
|
+
|
23
|
+
flds.map! do |c|
|
24
|
+
value = record.send(c[:name])
|
25
|
+
value.nil? ? c : c.merge(:value => value)
|
26
|
+
end if record
|
27
|
+
|
28
|
+
flds
|
30
29
|
end
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def default_fields
|
33
|
+
@default_fields ||= load_model_level_attrs || (data_class && data_class.netzke_attributes) || []
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def initial_fields(only_included = true)
|
37
|
+
::ActiveSupport::Deprecation.warn("The :columns option for FormPanel is deprecated. Use :fields instead", caller) if config[:columns]
|
38
|
+
|
39
|
+
# Normalize here, as from the config we can get symbols (names) instead of hashes
|
40
|
+
fields_from_config = (config[:columns] || config[:fields]) && normalize_attr_config(config[:columns] || config[:fields])
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
fields_for_create = fields_from_config
|
49
|
-
elsif default_fields
|
50
|
-
# we didn't have fields configured in widget's config, so, use the fields from the data class
|
51
|
-
fields_for_create = default_fields
|
52
|
-
else
|
53
|
-
raise ArgumentError, "No fields specified for widget '#{global_id}'"
|
42
|
+
if fields_from_config
|
43
|
+
# reverse-merge each column hash from config with each column hash from exposed_attributes (fields from config have higher priority)
|
44
|
+
for c in fields_from_config
|
45
|
+
corresponding_exposed_column = default_fields.find{ |k| k[:name] == c[:name] }
|
46
|
+
c.reverse_merge!(corresponding_exposed_column) if corresponding_exposed_column
|
54
47
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
fields_for_create
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
c[:name] = "#{assoc.name}__#{assoc_method}"
|
68
|
-
end
|
48
|
+
fields_for_create = fields_from_config
|
49
|
+
elsif default_fields
|
50
|
+
# we didn't have fields configured in widget's config, so, use the fields from the data class
|
51
|
+
fields_for_create = default_fields
|
52
|
+
else
|
53
|
+
raise ArgumentError, "No fields specified for widget '#{global_id}'"
|
54
|
+
end
|
55
|
+
|
56
|
+
fields_for_create.reject!{ |c| c[:included] == false }
|
57
|
+
|
58
|
+
fields_for_create.map! do |c|
|
59
|
+
if data_class
|
69
60
|
|
70
|
-
|
61
|
+
detect_association_with_method(c)
|
62
|
+
|
63
|
+
# detect association column (e.g. :category_id)
|
64
|
+
if assoc = data_class.reflect_on_all_associations.detect{|a| a.primary_key_name == c[:name]}
|
65
|
+
c[:xtype] ||= xtype_for_association
|
66
|
+
assoc_method = %w{name title label id}.detect{|m| (assoc.klass.instance_methods + assoc.klass.column_names).include?(m) } || assoc.klass.primary_key
|
67
|
+
c[:name] = "#{assoc.name}__#{assoc_method}"
|
71
68
|
end
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
c[:xtype] ||= xtype_for_attr_type(c[:attr_type]) # unless xtype_map[type].nil?
|
76
|
-
c
|
70
|
+
c[:hidden] = true if c[:name] == data_class.primary_key && c[:hidden].nil? # hide ID column by default
|
77
71
|
end
|
78
72
|
|
79
|
-
|
80
|
-
|
73
|
+
set_default_field_label(c)
|
74
|
+
|
75
|
+
c[:xtype] ||= xtype_for_attr_type(c[:attr_type]) # unless xtype_map[type].nil?
|
76
|
+
c
|
81
77
|
end
|
78
|
+
|
79
|
+
fields_for_create
|
80
|
+
|
82
81
|
end
|
83
82
|
|
84
83
|
private
|
@@ -130,13 +129,16 @@ module Netzke
|
|
130
129
|
end
|
131
130
|
end
|
132
131
|
end
|
133
|
-
|
134
132
|
end
|
135
133
|
|
134
|
+
# Receives 2 arrays of columns. Merges the missing config from the +source+ into +dest+, matching columns by name
|
135
|
+
def reverse_merge_equally_named_fields(dest, source)
|
136
|
+
dest.each{ |dc| dc.reverse_merge!(source.detect{ |sc| sc[:name] == dc[:name] }) }
|
137
|
+
end
|
138
|
+
|
136
139
|
|
137
140
|
def self.included(receiver)
|
138
141
|
receiver.extend ClassMethods
|
139
|
-
receiver.send :include, InstanceMethods
|
140
142
|
|
141
143
|
receiver.class_eval do
|
142
144
|
alias :initial_columns :initial_fields
|
data/lib/netzke/grid_panel.rb
CHANGED
@@ -44,7 +44,7 @@ module Netzke
|
|
44
44
|
# * <tt>:strong_default_attrs</tt> - a hash of attributes to be merged atop of every created/updated record.
|
45
45
|
# * <tt>:scopes</tt> - an array of named scopes to filter grid data, e.g.:
|
46
46
|
#
|
47
|
-
# [["user_id_not", 100], ["name_like", "Peter"]]
|
47
|
+
# [["user_id_not", 100], ["name_like", "Peter"], :recent]
|
48
48
|
#
|
49
49
|
# In the <tt>:ext_config</tt> hash (see Netzke::Base) the following GridPanel specific options are available:
|
50
50
|
#
|
@@ -57,10 +57,12 @@ module Netzke
|
|
57
57
|
# * <tt>:rows_per_page</tt> - number of rows per page (ignored when <tt>:enable_pagination</tt> is set to <tt>false</tt>)
|
58
58
|
# * <tt>:load_inline_data</tt> - load initial data into the grid right after its instantiation (saves a request to server); defaults to <tt>true</tt>
|
59
59
|
# * <tt>:mode</tt> - when set to <tt>:config</tt>, GridPanel loads in configuration mode
|
60
|
+
# * <tt>:add/edit/multi_edit/search_form_config</tt> - additional configuration for add/edit/multi_edit/search form panel
|
61
|
+
# * <tt>:add/edit/multi_edit_form_window_config</tt> - additional configuration for the window that wrapps up add/edit/multi_edit form panel
|
60
62
|
#
|
61
63
|
# Additionally supports Netzke::Base config options.
|
62
64
|
#
|
63
|
-
# ==
|
65
|
+
# == Columns
|
64
66
|
# Here's how the GridPanel decides which columns in which sequence and with which configuration to display.
|
65
67
|
# First, the column configs are aquired from this GridPanel's persistent storage, as an array of hashes, each
|
66
68
|
# representing a column configuration, such as:
|
@@ -75,7 +77,7 @@ module Netzke
|
|
75
77
|
# ... which in its turn overrides the defaults provided by persistent storage managed by the AttributesConfigurator
|
76
78
|
# that provides *model-level* (as opposed to a widget-level) configuration of a database model
|
77
79
|
# (which is used by both grids and forms in Netzke).
|
78
|
-
# And lastly, the defaults for AttributesConfigurator are calculated from the database model itself
|
80
|
+
# And lastly, the defaults for AttributesConfigurator are calculated from the database model itself (extended by Netzke).
|
79
81
|
# For example, in the model you can specify virtual attributes and their types that will be picked up by Netzke, the default
|
80
82
|
# order of columns, or excluded columns. For details see <tt>Netzke::ActiveRecord::Attributes</tt>.
|
81
83
|
#
|
@@ -97,7 +99,6 @@ module Netzke
|
|
97
99
|
|
98
100
|
# Code shared between GridPanel, FormPanel, and other widgets that serve as interface to database tables
|
99
101
|
include Netzke::DataAccessor
|
100
|
-
|
101
102
|
|
102
103
|
def self.enforce_config_consistency
|
103
104
|
config[:default_config][:ext_config][:enable_edit_in_form] &&= config[:edit_in_form_available]
|
@@ -139,7 +140,13 @@ module Netzke
|
|
139
140
|
|
140
141
|
# Include extra javascript that we depend on
|
141
142
|
def self.include_js
|
142
|
-
res = []
|
143
|
+
res = ["#{File.dirname(__FILE__)}/grid_panel/javascripts/grid_panel_pre.js"]
|
144
|
+
|
145
|
+
# Optional edit in form functionality
|
146
|
+
res << "#{File.dirname(__FILE__)}/grid_panel/javascripts/edit_in_form.js" if config[:edit_in_form_available]
|
147
|
+
|
148
|
+
# Optional extended search functionality
|
149
|
+
res << "#{File.dirname(__FILE__)}/grid_panel/javascripts/advanced_search.js" if config[:extended_search_available]
|
143
150
|
|
144
151
|
# Checkcolumn
|
145
152
|
ext_examples = Netzke::Base.config[:ext_location] + "/examples/"
|
@@ -173,53 +180,42 @@ module Netzke
|
|
173
180
|
# Edit in form
|
174
181
|
api :create_new_record if config[:edit_in_form_available]
|
175
182
|
|
183
|
+
# Model class
|
176
184
|
# (We can't memoize this method because at some point we extend it, e.g. in Netzke::DataAccessor)
|
177
185
|
def data_class
|
178
186
|
@data_class ||= begin
|
179
187
|
klass = "Netzke::ModelExtensions::#{config[:model]}For#{short_widget_class_name}".constantize rescue nil
|
180
|
-
klass ||
|
181
|
-
::ActiveSupport::Deprecation.warn("data_class_name option is deprecated. Use model instead", caller) if config[:data_class_name]
|
182
|
-
model_name = config[:model] || config[:data_class_name]
|
183
|
-
model_name.nil? ? raise(ArgumentError, "No model specified for widget #{global_id}") : model_name.constantize
|
184
|
-
end
|
188
|
+
klass || original_data_class
|
185
189
|
end
|
186
190
|
end
|
187
191
|
|
192
|
+
# Model class before model extensions are taken into account
|
193
|
+
def original_data_class
|
194
|
+
@original_data_class ||= begin
|
195
|
+
::ActiveSupport::Deprecation.warn("data_class_name option is deprecated. Use model instead", caller) if config[:data_class_name]
|
196
|
+
model_name = config[:model] || config[:data_class_name]
|
197
|
+
model_name.nil? ? raise(ArgumentError, "No model specified for widget #{global_id}") : model_name.constantize
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
188
201
|
def initialize(config = {}, parent = nil)
|
189
202
|
super
|
190
|
-
|
191
203
|
apply_helpers
|
192
204
|
end
|
193
205
|
|
194
|
-
# def data_class
|
195
|
-
# klass = "Netzke::ModelExtensions::#{data_class.name}#{short_widget_class_name}Ext".constantize rescue nil
|
196
|
-
# klass || data_class
|
197
|
-
# end
|
198
|
-
|
199
206
|
# Fields to be displayed in the "General" tab of the configuration panel
|
200
207
|
def self.property_fields
|
201
|
-
|
208
|
+
[
|
202
209
|
{:name => :ext_config__title, :type => :string},
|
203
210
|
{:name => :ext_config__header, :type => :boolean, :default => true},
|
204
211
|
{:name => :ext_config__enable_context_menu, :type => :boolean, :default => true},
|
205
|
-
# {:name => :ext_config__context_menu, :type => :json},
|
206
212
|
{:name => :ext_config__enable_pagination, :type => :boolean, :default => true},
|
207
213
|
{:name => :ext_config__rows_per_page, :type => :integer},
|
208
|
-
# {:name => :ext_config__bbar, :type => :json},
|
209
214
|
{:name => :ext_config__prohibit_create, :type => :boolean},
|
210
215
|
{:name => :ext_config__prohibit_update, :type => :boolean},
|
211
216
|
{:name => :ext_config__prohibit_delete, :type => :boolean},
|
212
217
|
{:name => :ext_config__prohibit_read, :type => :boolean}
|
213
218
|
]
|
214
|
-
|
215
|
-
# res << {:name => :ext_config__enable_extended_search, :type => :boolean} if config[:extended_search_available]
|
216
|
-
# res << {:name => :ext_config__enable_edit_in_form, :type => :boolean} if config[:edit_in_form_available]
|
217
|
-
|
218
|
-
# TODO: a buggy thing
|
219
|
-
# res << {:name => :layout__columns, :type => :json}
|
220
|
-
|
221
|
-
res
|
222
|
-
|
223
219
|
end
|
224
220
|
|
225
221
|
def default_config
|
@@ -298,7 +294,7 @@ module Netzke
|
|
298
294
|
:add_form => {
|
299
295
|
:class_name => "GridPanel::RecordFormWindow",
|
300
296
|
:ext_config => {
|
301
|
-
:title => "Add #{data_class.
|
297
|
+
:title => "Add #{data_class.table_name.singularize.humanize}",
|
302
298
|
:button_align => "right"
|
303
299
|
},
|
304
300
|
:item => {
|
@@ -314,13 +310,13 @@ module Netzke
|
|
314
310
|
:mode => ext_config[:mode]
|
315
311
|
},
|
316
312
|
:record => data_class.new
|
317
|
-
}
|
318
|
-
},
|
313
|
+
}.deep_merge(config[:add_form_config] || {})
|
314
|
+
}.deep_merge(config[:add_form_window_config] || {}),
|
319
315
|
|
320
316
|
:edit_form => {
|
321
317
|
:class_name => "GridPanel::RecordFormWindow",
|
322
318
|
:ext_config => {
|
323
|
-
:title => "Edit #{data_class.
|
319
|
+
:title => "Edit #{data_class.table_name.singularize.humanize}",
|
324
320
|
:button_align => "right"
|
325
321
|
},
|
326
322
|
:item => {
|
@@ -333,13 +329,13 @@ module Netzke
|
|
333
329
|
:header => false,
|
334
330
|
:mode => ext_config[:mode]
|
335
331
|
}
|
336
|
-
}
|
337
|
-
},
|
332
|
+
}.deep_merge(config[:edit_form_config] || {})
|
333
|
+
}.deep_merge(config[:edit_form_window_config] || {}),
|
338
334
|
|
339
335
|
:multi_edit_form => {
|
340
336
|
:class_name => "GridPanel::RecordFormWindow",
|
341
337
|
:ext_config => {
|
342
|
-
:title => "Edit #{data_class.
|
338
|
+
:title => "Edit #{data_class.table_name.humanize}",
|
343
339
|
:button_align => "right"
|
344
340
|
},
|
345
341
|
:item => {
|
@@ -352,8 +348,8 @@ module Netzke
|
|
352
348
|
:header => false,
|
353
349
|
:mode => ext_config[:mode]
|
354
350
|
}
|
355
|
-
}
|
356
|
-
}
|
351
|
+
}.deep_merge(config[:multi_edit_form_config] || {})
|
352
|
+
}.deep_merge(config[:multi_edit_form_window_config] || {})
|
357
353
|
}) if ext_config[:enable_edit_in_form]
|
358
354
|
|
359
355
|
# Extended search
|
@@ -368,7 +364,7 @@ module Netzke
|
|
368
364
|
:bbar => false,
|
369
365
|
:mode => ext_config[:mode]
|
370
366
|
},
|
371
|
-
}
|
367
|
+
}.deep_merge(config[:search_form_config] || {})
|
372
368
|
}) if ext_config[:enable_extended_search]
|
373
369
|
|
374
370
|
res
|