netzke-basepack 0.7.7 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +15 -10
- data/{CHANGELOG.rdoc → CHANGELOG.md} +146 -110
- data/LICENSE +7 -1
- data/README.md +47 -56
- data/Rakefile +5 -5
- data/config/before-travis.sh +10 -0
- data/javascripts/basepack.js +0 -130
- data/javascripts/netzkeremotecombo.js +59 -0
- data/lib/netzke/basepack.rb +9 -14
- data/lib/netzke/basepack/accordion.rb +45 -0
- data/lib/netzke/basepack/active_record.rb +12 -0
- data/lib/netzke/basepack/active_record/relation_extensions.rb +27 -0
- data/lib/netzke/basepack/columns.rb +309 -0
- data/lib/netzke/basepack/data_accessor.rb +22 -12
- data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +75 -11
- data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +154 -49
- data/lib/netzke/basepack/fields.rb +162 -0
- data/lib/netzke/basepack/form.rb +136 -0
- data/lib/netzke/basepack/{form_panel → form}/javascripts/comma_list_cbg.js +0 -1
- data/lib/netzke/basepack/{form_panel/javascripts/form_panel.js → form/javascripts/form.js} +20 -26
- data/lib/netzke/basepack/{form_panel → form}/javascripts/n_radio_group.js +0 -1
- data/lib/netzke/basepack/{form_panel → form}/javascripts/readonly_mode.js +0 -0
- data/lib/netzke/basepack/form/services.rb +115 -0
- data/lib/netzke/basepack/{form_panel → form}/stylesheets/readonly_mode.css +0 -0
- data/lib/netzke/basepack/grid.rb +355 -0
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/advanced_search.js +1 -1
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/check_column_fix.js +0 -0
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/edit_in_form.js +3 -3
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/event_handling.js +5 -2
- data/lib/netzke/basepack/{grid_panel/javascripts/grid_panel.js → grid/javascripts/grid.js} +120 -132
- data/lib/netzke/basepack/{grid_panel → grid}/javascripts/misc.js +0 -0
- data/lib/netzke/basepack/grid/services.rb +216 -0
- data/lib/netzke/basepack/item_persistence.rb +44 -0
- data/lib/netzke/basepack/item_persistence/events_plugin.rb +47 -0
- data/lib/netzke/basepack/{paging_form_panel.rb → paging_form.rb} +24 -30
- data/lib/netzke/basepack/{paging_form_panel/javascripts/paging_form_panel.js → paging_form/javascripts/paging_form.js} +2 -4
- data/lib/netzke/basepack/query_builder.rb +44 -73
- data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +16 -2
- data/lib/netzke/basepack/record_form_window.rb +67 -0
- data/lib/netzke/basepack/search_panel.rb +22 -24
- data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +2 -2
- data/lib/netzke/basepack/search_window.rb +47 -53
- data/lib/netzke/basepack/simple_app.rb +10 -13
- data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +2 -8
- data/lib/netzke/basepack/tab_panel.rb +5 -4
- data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +5 -5
- data/lib/netzke/basepack/version.rb +2 -2
- data/lib/netzke/basepack/viewport.rb +16 -0
- data/lib/netzke/basepack/window.rb +27 -18
- data/lib/netzke/basepack/window/javascripts/window.js +7 -1
- data/lib/netzke/basepack/wrap_lazy_loaded.rb +18 -18
- data/locales/en.yml +40 -24
- data/netzke-basepack.gemspec +51 -82
- data/stylesheets/basepack.css +0 -41
- data/test/basepack_test_app/Gemfile +9 -46
- data/test/basepack_test_app/Gemfile.lock +61 -96
- data/test/basepack_test_app/app/components/author_form.rb +8 -5
- data/test/basepack_test_app/app/components/author_grid.rb +2 -2
- data/test/basepack_test_app/app/components/book_form.rb +34 -31
- data/test/basepack_test_app/app/components/book_form_with_defaults.rb +6 -7
- data/test/basepack_test_app/app/components/book_form_with_file_upload.rb +10 -0
- data/test/basepack_test_app/app/components/book_form_with_nested_attributes.rb +5 -6
- data/test/basepack_test_app/app/components/book_grid.rb +19 -8
- data/test/basepack_test_app/app/components/book_grid_filtering.rb +4 -7
- data/test/basepack_test_app/app/components/book_grid_loader.rb +28 -15
- data/test/basepack_test_app/app/components/book_grid_with_custom_columns.rb +45 -21
- data/test/basepack_test_app/app/components/book_grid_with_default_values.rb +26 -8
- data/test/basepack_test_app/app/components/book_grid_with_excluded_columns.rb +11 -0
- data/test/basepack_test_app/app/components/book_grid_with_extra_feedback.rb +2 -2
- data/test/basepack_test_app/app/components/book_grid_with_extra_filters.rb +7 -6
- data/test/basepack_test_app/app/components/book_grid_with_mass_assignment_security.rb +9 -0
- data/test/basepack_test_app/app/components/book_grid_with_nested_attributes.rb +9 -9
- data/test/basepack_test_app/app/components/book_grid_with_overridden_columns.rb +5 -3
- data/test/basepack_test_app/app/components/book_grid_with_paging.rb +6 -8
- data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +6 -4
- data/test/basepack_test_app/app/components/book_grid_with_scope.rb +6 -0
- data/test/basepack_test_app/app/components/book_grid_with_scoped_authors.rb +10 -7
- data/test/basepack_test_app/app/components/book_grid_with_virtual_attributes.rb +21 -13
- data/test/basepack_test_app/app/components/book_paging_form.rb +21 -0
- data/test/basepack_test_app/app/components/book_query_builder.rb +7 -6
- data/test/basepack_test_app/app/components/book_with_custom_primary_key_grid.rb +6 -7
- data/test/basepack_test_app/app/components/books_bound_to_author.rb +9 -7
- data/test/basepack_test_app/app/components/border_layout_panel_with_persistence.rb +12 -0
- data/test/basepack_test_app/app/components/double_book_grid.rb +19 -14
- data/test/basepack_test_app/app/components/form_without_model.rb +15 -16
- data/test/basepack_test_app/app/components/grid_with_initial_sorting.rb +7 -0
- data/test/basepack_test_app/app/components/grid_with_inline_data.rb +7 -0
- data/test/basepack_test_app/app/components/paging_form_with_search.rb +2 -2
- data/test/basepack_test_app/app/components/panel_with_persistent_regions.rb +35 -0
- data/test/basepack_test_app/app/components/query_builder.rb +7 -0
- data/test/basepack_test_app/app/components/simple_panel.rb +16 -11
- data/test/basepack_test_app/app/components/simple_window.rb +7 -6
- data/test/basepack_test_app/app/components/some_accordion.rb +18 -0
- data/test/basepack_test_app/app/components/some_auth_app.rb +5 -5
- data/test/basepack_test_app/app/components/some_border_layout.rb +20 -20
- data/test/basepack_test_app/app/components/some_search_panel.rb +6 -0
- data/test/basepack_test_app/app/components/some_simple_app.rb +30 -16
- data/test/basepack_test_app/app/components/some_tab_panel.rb +18 -15
- data/test/basepack_test_app/app/components/user_form.rb +18 -16
- data/test/basepack_test_app/app/components/user_form_with_default_fields.rb +5 -6
- data/test/basepack_test_app/app/components/user_grid.rb +11 -6
- data/test/basepack_test_app/app/components/user_grid_with_customized_form_fields.rb +5 -3
- data/test/basepack_test_app/app/components/window_component_loader.rb +25 -21
- data/test/basepack_test_app/app/models/address.rb +0 -26
- data/test/basepack_test_app/app/models/author.rb +0 -31
- data/test/basepack_test_app/app/models/book.rb +1 -42
- data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +1 -23
- data/test/basepack_test_app/app/models/role.rb +0 -21
- data/test/basepack_test_app/app/models/user.rb +0 -24
- data/test/basepack_test_app/app/views/layouts/components.html.erb +1 -1
- data/test/basepack_test_app/config/application.rb +1 -1
- data/test/basepack_test_app/config/database.yml.travis +2 -6
- data/test/basepack_test_app/config/initializers/netzke.rb +1 -6
- data/test/basepack_test_app/db/schema.rb +14 -14
- data/test/basepack_test_app/features/accordion_panel.feature +2 -2
- data/test/basepack_test_app/features/form_panel.feature +7 -7
- data/test/basepack_test_app/features/grid_panel.feature +93 -39
- data/test/basepack_test_app/features/grid_panel_with_custom_primary_key.feature +2 -1
- data/test/basepack_test_app/features/grid_sorting.feature +30 -6
- data/test/basepack_test_app/features/paging_form_panel.feature +7 -7
- data/test/basepack_test_app/features/persistent_regions.feature +30 -0
- data/test/basepack_test_app/features/search_in_grid.feature +5 -5
- data/test/basepack_test_app/features/simple_app.feature +6 -7
- data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +1 -1
- data/test/basepack_test_app/features/step_definitions/generic_steps.rb +109 -4
- data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +8 -10
- data/test/basepack_test_app/features/step_definitions/window_steps.rb +27 -0
- data/test/basepack_test_app/features/tab_panel.feature +1 -1
- data/test/basepack_test_app/features/window.feature +17 -0
- data/test/unit/accordion_panel_test.rb +2 -2
- data/test/unit/grid_panel_test.rb +4 -4
- metadata +57 -83
- data/TODO.rdoc +0 -8
- data/lib/generators/netzke/basepack_generator.rb +0 -10
- data/lib/generators/netzke/templates/assets/ts-checkbox.gif +0 -0
- data/lib/generators/netzke/templates/create_netzke_field_lists.rb +0 -18
- data/lib/netzke/active_record.rb +0 -20
- data/lib/netzke/active_record/attributes.rb +0 -259
- data/lib/netzke/active_record/combobox_options.rb +0 -16
- data/lib/netzke/active_record/relation_extensions.rb +0 -37
- data/lib/netzke/basepack/accordion_panel.rb +0 -39
- data/lib/netzke/basepack/action_column.rb +0 -68
- data/lib/netzke/basepack/action_column/javascripts/action_column.js +0 -61
- data/lib/netzke/basepack/auth_app.rb +0 -159
- data/lib/netzke/basepack/basic_app.rb +0 -7
- data/lib/netzke/basepack/border_layout_panel.rb +0 -53
- data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +0 -40
- data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +0 -264
- data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +0 -260
- data/lib/netzke/basepack/form_panel.rb +0 -144
- data/lib/netzke/basepack/form_panel/fields.rb +0 -208
- data/lib/netzke/basepack/form_panel/javascripts/misc.js +0 -4
- data/lib/netzke/basepack/form_panel/services.rb +0 -142
- data/lib/netzke/basepack/grid_panel.rb +0 -441
- data/lib/netzke/basepack/grid_panel/columns.rb +0 -400
- data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +0 -281
- data/lib/netzke/basepack/grid_panel/record_form_window.rb +0 -41
- data/lib/netzke/basepack/grid_panel/services.rb +0 -235
- data/lib/netzke/basepack/panel.rb +0 -11
- data/lib/netzke/basepack/wrapper.rb +0 -28
- data/lib/netzke/data_mapper.rb +0 -18
- data/lib/netzke/data_mapper/attributes.rb +0 -273
- data/lib/netzke/data_mapper/combobox_options.rb +0 -11
- data/lib/netzke/data_mapper/relation_extensions.rb +0 -38
- data/lib/netzke/sequel.rb +0 -18
- data/lib/netzke/sequel/attributes.rb +0 -274
- data/lib/netzke/sequel/combobox_options.rb +0 -10
- data/lib/netzke/sequel/relation_extensions.rb +0 -40
- data/locales/zh-cn.yml +0 -79
- data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +0 -21
- data/test/basepack_test_app/app/components/book_grid_with_column_actions.rb +0 -15
- data/test/basepack_test_app/app/components/book_grid_with_defaults.rb +0 -6
- data/test/basepack_test_app/app/components/book_paging_form_panel.rb +0 -22
- data/test/basepack_test_app/app/components/generic_user_form.rb +0 -12
- data/test/basepack_test_app/app/components/simple_accordion.rb +0 -11
- data/test/basepack_test_app/app/components/simple_tab_panel.rb +0 -11
- data/test/basepack_test_app/app/components/simple_wrapper.rb +0 -7
- data/test/basepack_test_app/app/components/some_accordion_panel.rb +0 -22
- data/test/basepack_test_app/app/presenters/forms/generic_user.rb +0 -6
- data/test/basepack_test_app/app/views/components/loadable_window.html.erb +0 -9
- data/test/basepack_test_app/app/views/components/simple_panel.html.erb +0 -1
- data/test/basepack_test_app/features/components_in_view.feature +0 -11
- data/test/basepack_test_app/features/simple_panel.feature +0 -11
- data/test/basepack_test_app/features/validations_in_grid.feature +0 -13
- data/test/basepack_test_app/features/virtual_attributes.feature +0 -16
- data/test/basepack_test_app/spec/components/form_panel_spec.rb +0 -53
- data/test/basepack_test_app/spec/components/grid_panel_spec.rb +0 -10
- data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +0 -68
- data/test/basepack_test_app/spec/data_adapter/attributes_spec.rb +0 -56
- data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +0 -125
- data/test/basepack_test_app/spec/factories.rb +0 -28
- data/test/basepack_test_app/spec/spec_helper.rb +0 -39
@@ -1,142 +0,0 @@
|
|
1
|
-
module Netzke
|
2
|
-
module Basepack
|
3
|
-
class FormPanel < Netzke::Base
|
4
|
-
module Services
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
included do
|
8
|
-
|
9
|
-
#
|
10
|
-
# Endpoints
|
11
|
-
|
12
|
-
# Called when the form gets submitted (e.g. by pressing the Apply button)
|
13
|
-
endpoint :netzke_submit, :pre => true do |params|
|
14
|
-
netzke_submit(params)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Can be called when the form needs to load a record with given ID. E.g.:
|
18
|
-
#
|
19
|
-
# someForm.netzkeLoad({id: 100});
|
20
|
-
endpoint :netzke_load do |params|
|
21
|
-
@record = data_class && data_adapter.find_record(params[:id])
|
22
|
-
{:set_form_values => js_record_data}
|
23
|
-
end
|
24
|
-
|
25
|
-
# Returns options for a combobox
|
26
|
-
endpoint :get_combobox_options do |params|
|
27
|
-
query = params[:query]
|
28
|
-
|
29
|
-
field = fields[params[:column].to_sym]
|
30
|
-
scope = field.to_options[:scope]
|
31
|
-
query = params[:query]
|
32
|
-
{:data => combobox_options_for_column(field, :query => query, :scope => scope, :record_id => params[:id])}
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
# Overriding configuration_panel's get_combobox_options endpoint call
|
38
|
-
def configuration_panel__fields__get_combobox_options(params)
|
39
|
-
query = params[:query]
|
40
|
-
{:data => (default_columns.map{ |c| c[:name].to_s }).grep(/^#{query}/).map{ |n| [n] }}.to_nifty_json
|
41
|
-
end
|
42
|
-
|
43
|
-
# Returns array of form values according to the configured columns
|
44
|
-
# def array_of_values
|
45
|
-
# @record && @record.netzke_array(fields)
|
46
|
-
# end
|
47
|
-
|
48
|
-
def values
|
49
|
-
record && record.netzke_hash(fields)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Implementation for the "netzke_submit" endpoint (for backward compatibility)
|
53
|
-
def netzke_submit(params)
|
54
|
-
data = ActiveSupport::JSON.decode(params[:data])
|
55
|
-
data.each_pair do |k,v|
|
56
|
-
data[k]=nil if v.blank? || v == "null" # Ext JS returns "null" on empty date fields, or "" for not filled optional integer fields, which gives errors when passed to model (at least in DataMapper)
|
57
|
-
end
|
58
|
-
|
59
|
-
# File uploads are in raw params instead of "data" hash, so, mix them in into "data"
|
60
|
-
if config[:file_upload]
|
61
|
-
Netzke::Core.controller.params.each_pair do |k,v|
|
62
|
-
data[k] = v if v.is_a?(ActionDispatch::Http::UploadedFile)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
success = create_or_update_record(data)
|
67
|
-
|
68
|
-
if success
|
69
|
-
{:set_form_values => js_record_data, :set_result => true}
|
70
|
-
else
|
71
|
-
# flash eventual errors
|
72
|
-
data_adapter.errors_array(@record).each do |error|
|
73
|
-
flash :error => error
|
74
|
-
end
|
75
|
-
{:netzke_feedback => @flash, :apply_form_errors => build_form_errors(record)}
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
# Builds the form errors
|
82
|
-
def build_form_errors(record)
|
83
|
-
form_errors = {}
|
84
|
-
foreign_keys = data_adapter.hash_fk_model
|
85
|
-
record.errors.to_hash.map{|field, error|
|
86
|
-
# some ORM return an array for error
|
87
|
-
error = error.join ', ' if error.kind_of? Array
|
88
|
-
# Get the correct field name for the errors on foreign keys
|
89
|
-
if foreign_keys.has_key?(field)
|
90
|
-
fields.each do |k, v|
|
91
|
-
# Hack to stop to_nifty_json from camalizing model__field
|
92
|
-
field = k.to_s.gsub('__', '____') if k.to_s.split('__').first == foreign_keys[field].to_s
|
93
|
-
end
|
94
|
-
end
|
95
|
-
form_errors[field] ||= []
|
96
|
-
form_errors[field] << error
|
97
|
-
}
|
98
|
-
form_errors
|
99
|
-
end
|
100
|
-
|
101
|
-
# Creates/updates a record from hash
|
102
|
-
def create_or_update_record(hsh)
|
103
|
-
hsh.merge!(config[:strong_default_attrs]) if config[:strong_default_attrs]
|
104
|
-
@record ||= data_adapter.find_record hsh.delete(data_class.primary_key.to_s) # only pick up the record specified in the params if it was not provided in the configuration
|
105
|
-
#data_class.find(:first, :conditions => {data_class.primary_key => hsh.delete(data_class.primary_key)})
|
106
|
-
success = true
|
107
|
-
|
108
|
-
@record = data_class.new if @record.nil?
|
109
|
-
|
110
|
-
hsh.each_pair do |k,v|
|
111
|
-
@record.set_value_for_attribute(fields[k.to_sym].nil? ? {:name => k} : fields[k.to_sym], v)
|
112
|
-
end
|
113
|
-
|
114
|
-
#hsh.each_pair do |k,v|
|
115
|
-
#begin
|
116
|
-
#@record.send("#{k}=",v)
|
117
|
-
#rescue StandardError => exc
|
118
|
-
#flash :error => exc.message
|
119
|
-
#success = false
|
120
|
-
#break
|
121
|
-
#end
|
122
|
-
#end
|
123
|
-
|
124
|
-
# did we have complete success?
|
125
|
-
success && data_adapter.save_record(@record)
|
126
|
-
end
|
127
|
-
|
128
|
-
# API handling form load
|
129
|
-
# def load(params)
|
130
|
-
# klass = config[:model].constantize
|
131
|
-
# case params[:neighbour]
|
132
|
-
# when "previous" then @record = klass.previous(params[:id])
|
133
|
-
# when "next" then @record = klass.next(params[:id])
|
134
|
-
# else @record = klass.find(params[:id])
|
135
|
-
# end
|
136
|
-
# {:data => [array_of_values]}
|
137
|
-
# end
|
138
|
-
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
@@ -1,441 +0,0 @@
|
|
1
|
-
require "netzke/basepack/grid_panel/columns"
|
2
|
-
require "netzke/basepack/grid_panel/services"
|
3
|
-
# require "netzke/basepack/plugins/configuration_tool"
|
4
|
-
|
5
|
-
module Netzke
|
6
|
-
module Basepack
|
7
|
-
# Ext.grid.EditorGridPanel-based component with the following features:
|
8
|
-
#
|
9
|
-
# * ActiveRecord-model support with automatic column configuration
|
10
|
-
# * multi-line CRUD operations - get, post, delete, create
|
11
|
-
# * (multe-record) editing and adding records through a form
|
12
|
-
# * persistent column resize, move and hide
|
13
|
-
# * permissions
|
14
|
-
# * sorting
|
15
|
-
# * pagination
|
16
|
-
# * filtering
|
17
|
-
# * advanced search
|
18
|
-
# * rows reordering by drag-n-drop, requires acts_as_list on the model
|
19
|
-
# * virtual attribute support
|
20
|
-
# * (TODO) dynamic configuration of properties and columns
|
21
|
-
#
|
22
|
-
# == Instance configuration
|
23
|
-
# The following config options are supported:
|
24
|
-
# * +model+ - name of the ActiveRecord model that provides data to this GridPanel, e.g. "User"
|
25
|
-
# * +columns+ - an array of columns to be displayed in the grid; each column may be represented by a symbol (representing the model's attribute name), or a hash (when extra configuration is needed). See the "Columns" section below.
|
26
|
-
# * +scope+ - specifies how the data should be filtered.
|
27
|
-
# When it's a symbol, it's used as a scope name.
|
28
|
-
# When it's a string, it's a SQL statement (passed directly to +where+).
|
29
|
-
# When it's a hash, it's a conditions hash (passed directly to +where+).
|
30
|
-
# When it's an array, it's expanded into an SQL statement with arguments (passed directly to +where+), e.g.:
|
31
|
-
#
|
32
|
-
# :scope => ["id > ?", 100])
|
33
|
-
#
|
34
|
-
# When it's a Proc, it's passed the model class, and is expected to return a ActiveRecord::Relation, e.g.:
|
35
|
-
#
|
36
|
-
# :scope => { |rel| rel.where(:id.gt => 100).order(:created_at) }
|
37
|
-
#
|
38
|
-
# * +strong_default_attrs+ - (defaults to {}) a hash of attributes to be merged atop of every created/updated record, e.g. {:role_id => 1}
|
39
|
-
# * +enable_column_filters+ - (defaults to true) enable filters in column's context menu
|
40
|
-
# * +enable_edit_in_form+ - (defaults to true) provide buttons into the toolbar that activate editing/adding records via a form
|
41
|
-
# * +enable_extended_search+ - (defaults to true) provide a button into the toolbar that shows configurable search form
|
42
|
-
# * +enable_context_menu+ - (defaults to true) enable rows context menu
|
43
|
-
# * +context_menu+ - an array of actions (e.g. [:edit.action, "-", :del.action] - see the Actions section) or +false+ to disable the context menu
|
44
|
-
# * +enable_rows_reordering+ - (defaults to false) enable reordering of rows with drag-n-drop; underlying model (specified in +model+) must implement "acts_as_list"-compatible functionality
|
45
|
-
# * +enable_pagination+ - (defaults to true) enable pagination
|
46
|
-
# * +rows_per_page+ - (defaults to 30) number of rows per page (ignored when +enable_pagination+ is set to +false+)
|
47
|
-
# * +load_inline_data+ - (defaults to true) load initial data into the grid right after its instantiation
|
48
|
-
# * (TODO) +mode+ - when set to +config+, GridPanel loads in configuration mode
|
49
|
-
# * <tt>[add|edit|multi_edit]_search_form_config</tt> - additional configuration for add/edit/multi_edit/search form panel
|
50
|
-
# * <tt>[add|edit|multi_edit]_form_window_config</tt> - additional configuration for the window that wrapps up add/edit/multi_edit form panel
|
51
|
-
#
|
52
|
-
# == Columns
|
53
|
-
# Columns are configured by passing an array to the +columns+ option. Each element in the array is either the name of model's (virtual) attribute (in which case the configuration will be fully automatic), or a hash that may contain the following configuration options as keys:
|
54
|
-
#
|
55
|
-
# * +name+ - (required) name of the column, that may correspond to the model's (virtual) attribute
|
56
|
-
# * +read_only+ - a boolean that defines if the cells in the column should be editable
|
57
|
-
# * +editable+ - same as +read_only+, but in reverse (takes precedence over +read_only+)
|
58
|
-
# * +filterable+ - set to false to disable filtering on this column
|
59
|
-
# * +getter+ - a lambda that receives a record as a parameter, and is expected to return a string that will be sent to the cell (can be HTML code), e.g.:
|
60
|
-
#
|
61
|
-
# :getter => lambda {|r| [r.first_name, r.last_name].join }
|
62
|
-
# * +setter+ - a lambda that receives a record as first parameter, and the value passed from the cell as the second parameter, and is expected to modify the record accordingly, e.g.:
|
63
|
-
#
|
64
|
-
# :setter => lambda { |r,v| r.first_name, r.last_name = v.split(" ") }
|
65
|
-
#
|
66
|
-
# * +scope+ - the scope for one-to-many association column. Same syntax applies as for scoping out records for the grid itself. See "One-to-many association support" for details.
|
67
|
-
#
|
68
|
-
# * +sorting_scope+ - the name of the scope used for sorting the column. This can be useful for virtual columns for example. The scope will get one parameter specifying the direction (:asc or :desc). Example:
|
69
|
-
#
|
70
|
-
# columns => [{ :name => "complete_user_name", :sorting_scope => :sort_user_by_full_name }, ...]
|
71
|
-
#
|
72
|
-
# class User < ActiveRecord::Base
|
73
|
-
# scope :sort_user_by_full_name, lambda { |dir|
|
74
|
-
# order("users.first_name #{dir.to_s}, users.last_name #{dir.to_s}")
|
75
|
-
# }
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# * +format+ - the format to display data in case of date and datetime columns, e.g. 'Y-m-d g:i:s'.
|
79
|
-
# * +blank_line+ - the blank line for one-to-many association columns, defaults to "---". Set to false to exclude completely.
|
80
|
-
#
|
81
|
-
# Besides these options, a column can receive any meaningful config option understood by Ext.grid.column.Column.
|
82
|
-
#
|
83
|
-
# == One-to-many association support
|
84
|
-
# If the model bound to a grid +belongs_to+ another model, GridPanel can display an "assocition column" - where the user can select the associated record from a drop-down box. You can specify which method of the association should be used as the display value for the drop-down box options by using the double-underscore notation on the column name, where the association name is separated from the association method by "__" (double underscore). For example, let's say we have a Book that +belongs_to+ model Author, and Author responds to +first_name+. This way, the book grid can have a column defined as follows:
|
85
|
-
#
|
86
|
-
# {:name => "author__first_name"}
|
87
|
-
#
|
88
|
-
# GridPanel will detect it to be an association column, and will use the drop-down box for selecting an author, where the list of authors will be represented by the author's first name.
|
89
|
-
#
|
90
|
-
# In order to scope out the records displayed in the drop-down box, the +scope+ column option can be used, e.g.:
|
91
|
-
#
|
92
|
-
# {:name => "author__first_name", :scope => lambda{|relation| relation.where(:popular => true)}}
|
93
|
-
#
|
94
|
-
# == Add/edit/search forms
|
95
|
-
# The forms will by default display the fields that correspond to the configured columns, taking over meaningful configuration options (e.g. +text+ will be converted into +fieldLabel+).
|
96
|
-
# You may override the default fields displayed in the forms by overriding the +default_fields_for_forms+ method, which should return an array understood by the +items+ config property of the +FormPanel+. If you need to use a custom class instead of +FormPanel+, you may need to go an extra mile overriding the corresponding GridPanel's child component (e.g. "add_form" or "edit_form").
|
97
|
-
#
|
98
|
-
# == Actions
|
99
|
-
# You can override GridPanel's actions to change their text, icons, and tooltips (see http://api.netzke.org/core/Netzke/Actions.html).
|
100
|
-
#
|
101
|
-
# GridPanel implements the following actions:
|
102
|
-
# * +add+ - inline adding of a record
|
103
|
-
# * +del+ - deletion of records
|
104
|
-
# * +edit+ - inline editing of a record
|
105
|
-
# * +apply+ - applying inline changes
|
106
|
-
# * +add_in_form+ - adding a record in a form
|
107
|
-
# * +edit_in_form+ - (multi-record) editing in a forrm
|
108
|
-
# * +search+ - advanced searching
|
109
|
-
#
|
110
|
-
# == Class configuration
|
111
|
-
#
|
112
|
-
# Configuration on this level is effective during the life-time of the application. One place for setting these options are in application.rb, e.g.:
|
113
|
-
#
|
114
|
-
# config.netzke.basepack.grid_panel.column_filters_available = false
|
115
|
-
#
|
116
|
-
# These can also be eventually set directly on the component's class:
|
117
|
-
#
|
118
|
-
# Netzke::Basepack::GridPanel.column_filters_available = false
|
119
|
-
#
|
120
|
-
# Most of these options influence the amount of JavaScript code that is generated for this component's class, in the way that the less functionality is enabled, the less code is generated.
|
121
|
-
#
|
122
|
-
# The following class configuration options are available:
|
123
|
-
# * +column_filters_available+ - (defaults to true) include code for the filters in the column's context menu
|
124
|
-
# * (TODO) +config_tool_available+ - (defaults to true) include code for the configuration tool that launches the configuration panel
|
125
|
-
# * +edit_in_form_available+ - (defaults to true) include code for (multi-record) editing and adding records through a form
|
126
|
-
# * +extended_search_available+ - (defaults to true) include code for extended configurable search
|
127
|
-
class GridPanel < Netzke::Base
|
128
|
-
js_base_class "Ext.grid.Panel"
|
129
|
-
|
130
|
-
class_attribute :columns_attr
|
131
|
-
|
132
|
-
class_attribute :overridden_columns_attr
|
133
|
-
self.overridden_columns_attr = {}
|
134
|
-
|
135
|
-
# Class-level configuration. These options directly influence the amount of generated
|
136
|
-
# javascript code for this component's class. For example, if you don't want filters for the grid,
|
137
|
-
# set column_filters_available to false, and the javascript for the filters won't be included at all.
|
138
|
-
class_config_option :column_filters_available, true
|
139
|
-
|
140
|
-
class_config_option :extended_search_available, true
|
141
|
-
|
142
|
-
class_config_option :edit_in_form_available, true
|
143
|
-
|
144
|
-
class_config_option :rows_reordering_available, false
|
145
|
-
|
146
|
-
class_config_option :config_tool_available, false
|
147
|
-
|
148
|
-
class_config_option :default_instance_config, {
|
149
|
-
:enable_edit_in_form => edit_in_form_available,
|
150
|
-
:enable_extended_search => extended_search_available,
|
151
|
-
:enable_column_filters => column_filters_available,
|
152
|
-
:load_inline_data => true,
|
153
|
-
:enable_rows_reordering => false, # column drag n drop
|
154
|
-
:enable_pagination => true,
|
155
|
-
:rows_per_page => 30,
|
156
|
-
:tools => %w{ refresh }
|
157
|
-
}
|
158
|
-
|
159
|
-
extend ActiveSupport::Memoizable
|
160
|
-
|
161
|
-
include self::Services
|
162
|
-
include self::Columns
|
163
|
-
include Netzke::Basepack::DataAccessor
|
164
|
-
|
165
|
-
js_mixin :grid_panel, :event_handling
|
166
|
-
js_mixin :advanced_search if extended_search_available
|
167
|
-
js_mixin :edit_in_form if edit_in_form_available
|
168
|
-
|
169
|
-
js_translate *%w[are_you_sure confirmation]
|
170
|
-
|
171
|
-
# JavaScript includes
|
172
|
-
ex = Netzke::Core.ext_path.join("examples")
|
173
|
-
|
174
|
-
js_include(ex.join("ux/CheckColumn.js"))
|
175
|
-
js_include :check_column_fix
|
176
|
-
|
177
|
-
# Includes for column filters
|
178
|
-
if column_filters_available
|
179
|
-
[
|
180
|
-
"ux/grid/menu/ListMenu.js",
|
181
|
-
"ux/grid/menu/RangeMenu.js",
|
182
|
-
"ux/grid/FiltersFeature.js"
|
183
|
-
].each{ |path| js_include(ex.join(path)) }
|
184
|
-
|
185
|
-
%w{Boolean Date List Numeric String}.unshift("").each do |f|
|
186
|
-
js_include(ex.join"ux/grid/filter/#{f}Filter.js")
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
# Includes for rows reordering
|
191
|
-
if rows_reordering_available
|
192
|
-
js_include(ex.join("#{File.dirname(__FILE__)}/grid_panel/javascripts/rows-dd.js"))
|
193
|
-
end
|
194
|
-
|
195
|
-
# Allows children classes to simply do
|
196
|
-
#
|
197
|
-
# model "User"
|
198
|
-
delegates_to_dsl :model, :add_form_config, :add_form_window_config, :edit_form_config, :edit_form_window_config, :multi_edit_form_config, :multi_edit_form_window_config
|
199
|
-
|
200
|
-
# Inject some handy DSL methods into the child classes.
|
201
|
-
def self.inherited(base)
|
202
|
-
super
|
203
|
-
|
204
|
-
base.class_eval do
|
205
|
-
class << self
|
206
|
-
def column(name, config = {})
|
207
|
-
columns = self.columns_attr || []
|
208
|
-
columns |= [config.merge(:name => name.to_s)]
|
209
|
-
self.columns_attr = columns
|
210
|
-
end
|
211
|
-
|
212
|
-
def override_column(name, config)
|
213
|
-
columns = self.overridden_columns_attr.dup
|
214
|
-
self.overridden_columns_attr = columns.merge(name.to_sym => config)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def configuration
|
221
|
-
super.tap do |c|
|
222
|
-
c[:columns] ||= self.columns_attr
|
223
|
-
|
224
|
-
# user-passed :override_columns option should get deep_merged with the defaults
|
225
|
-
c[:override_columns] = self.overridden_columns_attr.deep_merge(c[:override_columns] || {})
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def js_config #:nodoc:
|
230
|
-
res = super
|
231
|
-
res.merge({
|
232
|
-
:title => res[:title] || self.class.js_properties[:title] || data_class.name.pluralize,
|
233
|
-
:bbar => config.has_key?(:bbar) ? config[:bbar] : default_bbar,
|
234
|
-
:context_menu => config.has_key?(:context_menu) ? config[:context_menu] : default_context_menu,
|
235
|
-
:columns => columns(:with_meta => true), # columns
|
236
|
-
:columns_order => columns_order,
|
237
|
-
:model => config[:model], # the model name
|
238
|
-
:inline_data => (get_data if config[:load_inline_data]), # inline data (loaded along with the grid panel)
|
239
|
-
:pri => data_class.primary_key # table primary key name
|
240
|
-
})
|
241
|
-
end
|
242
|
-
|
243
|
-
def get_association_values(record) #:nodoc:
|
244
|
-
columns.select{ |c| c[:name].index("__") }.each.inject({}) do |r,c|
|
245
|
-
r.merge(c[:name] => record.value_for_attribute(c, true))
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
def get_default_association_values #:nodoc:
|
250
|
-
columns.select{ |c| c[:name].index("__") && c[:default_value] }.each.inject({}) do |r,c|
|
251
|
-
assoc_name, assoc_method = c[:name].split '__'
|
252
|
-
assoc_class = data_adapter.class_for(assoc_name)
|
253
|
-
assoc_data_adapter = Netzke::Basepack::DataAdapters::AbstractAdapter.adapter_class(assoc_class).new(assoc_class)
|
254
|
-
assoc_instance = assoc_data_adapter.find_record c[:default_value]
|
255
|
-
r.merge(c[:name] => assoc_instance.send(assoc_method))
|
256
|
-
end
|
257
|
-
end
|
258
|
-
memoize :get_default_association_values
|
259
|
-
|
260
|
-
# Override to change the default bottom toolbar
|
261
|
-
def default_bbar
|
262
|
-
res = %w{ add edit apply del }.map(&:to_sym).map(&:action)
|
263
|
-
res << "-" << :add_in_form.action << :edit_in_form.action if config[:enable_edit_in_form]
|
264
|
-
res << "-" << :search.action if config[:enable_extended_search]
|
265
|
-
res
|
266
|
-
end
|
267
|
-
|
268
|
-
# Override to change the default context menu
|
269
|
-
def default_context_menu
|
270
|
-
res = %w{ edit del }.map(&:to_sym).map(&:action)
|
271
|
-
res << "-" << :edit_in_form.action if config[:enable_edit_in_form]
|
272
|
-
res
|
273
|
-
end
|
274
|
-
|
275
|
-
# def configuration_components
|
276
|
-
# res = []
|
277
|
-
# res << {
|
278
|
-
# :persistent_config => true,
|
279
|
-
# :name => 'columns',
|
280
|
-
# :class_name => "FieldsConfigurator",
|
281
|
-
# :active => true,
|
282
|
-
# :owner => self
|
283
|
-
# }
|
284
|
-
# res << {
|
285
|
-
# :name => 'general',
|
286
|
-
# :class_name => "PropertyEditor",
|
287
|
-
# :component => self,
|
288
|
-
# :title => false
|
289
|
-
# }
|
290
|
-
# res
|
291
|
-
# end
|
292
|
-
|
293
|
-
action :add do
|
294
|
-
{
|
295
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.add'),
|
296
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.add'),
|
297
|
-
:disabled => config[:prohibit_create],
|
298
|
-
:handler => "onAddInline", # not following naming conventions here as Ext 4 grid has its own onAdd method
|
299
|
-
:icon => :add
|
300
|
-
}
|
301
|
-
end
|
302
|
-
|
303
|
-
action :edit do
|
304
|
-
{
|
305
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.edit'),
|
306
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.edit'),
|
307
|
-
:disabled => true,
|
308
|
-
:icon => :table_edit
|
309
|
-
}
|
310
|
-
end
|
311
|
-
|
312
|
-
action :del do
|
313
|
-
{
|
314
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.del'),
|
315
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.del'),
|
316
|
-
:disabled => true,
|
317
|
-
:icon => :table_row_delete
|
318
|
-
}
|
319
|
-
end
|
320
|
-
|
321
|
-
action :apply do
|
322
|
-
{
|
323
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.apply'),
|
324
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.apply'),
|
325
|
-
:disabled => config[:prohibit_update] && config[:prohibit_create],
|
326
|
-
:icon => :tick
|
327
|
-
}
|
328
|
-
end
|
329
|
-
|
330
|
-
action :add_in_form do
|
331
|
-
{
|
332
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.add_in_form'),
|
333
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.add_in_form'),
|
334
|
-
:icon => :application_form_add
|
335
|
-
}
|
336
|
-
end
|
337
|
-
|
338
|
-
action :edit_in_form do
|
339
|
-
{
|
340
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.edit_in_form'),
|
341
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.edit_in_form'),
|
342
|
-
:disabled => true,
|
343
|
-
:icon => :application_form_edit
|
344
|
-
}
|
345
|
-
end
|
346
|
-
|
347
|
-
action :search do
|
348
|
-
{
|
349
|
-
:text => I18n.t('netzke.basepack.grid_panel.actions.search'),
|
350
|
-
:tooltip => I18n.t('netzke.basepack.grid_panel.actions.search'),
|
351
|
-
:enable_toggle => true,
|
352
|
-
:icon => :find
|
353
|
-
}
|
354
|
-
end
|
355
|
-
|
356
|
-
component :add_form do
|
357
|
-
form_config = {
|
358
|
-
:class_name => "Netzke::Basepack::FormPanel",
|
359
|
-
:model => config[:model],
|
360
|
-
:persistent_config => config[:persistent_config],
|
361
|
-
:strong_default_attrs => config[:strong_default_attrs],
|
362
|
-
:border => true,
|
363
|
-
:bbar => false,
|
364
|
-
:prevent_header => true,
|
365
|
-
:mode => config[:mode],
|
366
|
-
:record => data_class.new(columns_default_values)
|
367
|
-
}
|
368
|
-
|
369
|
-
# Only provide default form fields when no custom class_name is specified for the form
|
370
|
-
form_config[:items] = default_fields_for_forms unless config[:add_form_config] && config[:add_form_config][:class_name]
|
371
|
-
|
372
|
-
{
|
373
|
-
:lazy_loading => true,
|
374
|
-
:class_name => "Netzke::Basepack::GridPanel::RecordFormWindow",
|
375
|
-
:title => "Add #{data_class.model_name.human}",
|
376
|
-
:button_align => "right",
|
377
|
-
:items => [form_config.deep_merge(config[:add_form_config] || {})]
|
378
|
-
}.deep_merge(config[:add_form_window_config] || {})
|
379
|
-
end
|
380
|
-
|
381
|
-
component :edit_form do
|
382
|
-
form_config = {
|
383
|
-
:class_name => "Netzke::Basepack::FormPanel",
|
384
|
-
:model => config[:model],
|
385
|
-
:persistent_config => config[:persistent_config],
|
386
|
-
:bbar => false,
|
387
|
-
:prevent_header => true,
|
388
|
-
:mode => config[:mode]
|
389
|
-
# :record_id gets assigned by deliver_component dynamically, at the moment of loading
|
390
|
-
}
|
391
|
-
|
392
|
-
# Only provide default form fields when no custom class_name is specified for the form
|
393
|
-
form_config[:items] = default_fields_for_forms unless config[:edit_form_config] && config[:edit_form_config][:class_name]
|
394
|
-
|
395
|
-
{
|
396
|
-
:lazy_loading => true,
|
397
|
-
:class_name => "Netzke::Basepack::GridPanel::RecordFormWindow",
|
398
|
-
:title => "Edit #{data_class.model_name.human}",
|
399
|
-
:button_align => "right",
|
400
|
-
:items => [form_config.deep_merge(config[:edit_form_config] || {})]
|
401
|
-
}.deep_merge(config[:edit_form_window_config] || {})
|
402
|
-
end
|
403
|
-
|
404
|
-
component :multi_edit_form do
|
405
|
-
form_config = {
|
406
|
-
:class_name => "Netzke::Basepack::FormPanel",
|
407
|
-
:multi_edit => true,
|
408
|
-
:model => config[:model],
|
409
|
-
:persistent_config => config[:persistent_config],
|
410
|
-
:bbar => false,
|
411
|
-
:prevent_header => true,
|
412
|
-
:name => "multi_edit_form0", # we detect multi-edit form submission by its name
|
413
|
-
:mode => config[:mode]
|
414
|
-
}
|
415
|
-
|
416
|
-
# Only provide default form fields when no custom class_name is specified for the form
|
417
|
-
form_config[:items] = default_fields_for_forms unless config[:multi_edit_form_config] && config[:multi_edit_form_config][:class_name]
|
418
|
-
|
419
|
-
{
|
420
|
-
:lazy_loading => true,
|
421
|
-
:class_name => "Netzke::Basepack::GridPanel::RecordFormWindow",
|
422
|
-
:title => "Edit #{data_class.model_name.human.pluralize}",
|
423
|
-
:button_align => "right",
|
424
|
-
:items => [form_config.deep_merge(config[:multi_edit_form_config] || {})]
|
425
|
-
}.deep_merge(config[:multi_edit_form_window_config] || {})
|
426
|
-
end
|
427
|
-
|
428
|
-
component :search_form do
|
429
|
-
{
|
430
|
-
:lazy_loading => true,
|
431
|
-
:class_name => "Netzke::Basepack::SearchWindow",
|
432
|
-
:model => config[:model],
|
433
|
-
:fields => default_fields_for_forms
|
434
|
-
}
|
435
|
-
end
|
436
|
-
|
437
|
-
# include ::Netzke::Plugins::ConfigurationTool if config_tool_available # it will load ConfigurationPanel into a modal window
|
438
|
-
|
439
|
-
end
|
440
|
-
end
|
441
|
-
end
|