netzke-basepack 0.2.0.1 → 0.2.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.
- data/CHANGELOG +6 -0
- data/Manifest +12 -3
- data/README.rdoc +87 -0
- data/Rakefile +1 -1
- data/generators/netzke_form_panel/netzke_form_panel_generator.rb +7 -0
- data/generators/netzke_form_panel/templates/create_netzke_form_panel_fields.rb +22 -0
- data/generators/{netzke_basepack → netzke_grid_panel}/netzke_grid_panel_generator.rb +0 -0
- data/generators/{netzke_basepack → netzke_grid_panel}/templates/create_netzke_grid_panel_columns.rb +0 -0
- data/javascripts/basepack.js +31 -1
- data/lib/app/models/netzke_form_panel_field.rb +18 -0
- data/lib/app/models/netzke_grid_panel_column.rb +1 -7
- data/lib/netzke/ar_ext.rb +59 -16
- data/lib/netzke/border_layout_panel.rb +18 -29
- data/lib/netzke/column.rb +11 -2
- data/lib/netzke/form_panel.rb +185 -0
- data/lib/netzke/grid_panel.rb +31 -20
- data/lib/netzke/grid_panel_interface.rb +12 -8
- data/netzke-basepack.gemspec +8 -8
- data/test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb +14 -0
- data/test/app_root/db/migrate/20090102223811_create_netzke_grid_panel_columns.rb +21 -0
- data/test/app_root/vendor/plugins/acts_as_list/README +23 -0
- data/test/app_root/vendor/plugins/acts_as_list/init.rb +3 -0
- data/test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
- data/test/ar_ext_test.rb +13 -1
- data/test/border_layout_panel_test.rb +3 -3
- data/test/grid_panel_test.rb +8 -3
- metadata +19 -8
- data/README.mdown +0 -83
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
css/basepack.css
|
3
3
|
generators/netzke_basepack/netzke_basepack_generator.rb
|
4
|
-
generators/netzke_basepack/netzke_grid_panel_generator.rb
|
5
|
-
generators/netzke_basepack/templates/create_netzke_grid_panel_columns.rb
|
6
4
|
generators/netzke_basepack/USAGE
|
5
|
+
generators/netzke_form_panel/netzke_form_panel_generator.rb
|
6
|
+
generators/netzke_form_panel/templates/create_netzke_form_panel_fields.rb
|
7
|
+
generators/netzke_grid_panel/netzke_grid_panel_generator.rb
|
8
|
+
generators/netzke_grid_panel/templates/create_netzke_grid_panel_columns.rb
|
7
9
|
init.rb
|
8
10
|
install.rb
|
9
11
|
javascripts/basepack.js
|
10
12
|
javascripts/filters.js
|
13
|
+
lib/app/models/netzke_form_panel_field.rb
|
11
14
|
lib/app/models/netzke_grid_panel_column.rb
|
12
15
|
lib/netzke/accordion_panel.rb
|
13
16
|
lib/netzke/ar_ext.rb
|
14
17
|
lib/netzke/border_layout_panel.rb
|
15
18
|
lib/netzke/column.rb
|
16
19
|
lib/netzke/container.rb
|
20
|
+
lib/netzke/form_panel.rb
|
17
21
|
lib/netzke/grid_panel.rb
|
18
22
|
lib/netzke/grid_panel_interface.rb
|
19
23
|
lib/netzke/grid_panel_js_builder.rb
|
@@ -26,7 +30,7 @@ lib/netzke-basepack.rb
|
|
26
30
|
LICENSE
|
27
31
|
Manifest
|
28
32
|
Rakefile
|
29
|
-
README.
|
33
|
+
README.rdoc
|
30
34
|
tasks/netzke_basepack_tasks.rake
|
31
35
|
test/app_root/app/controllers/application.rb
|
32
36
|
test/app_root/app/models/book.rb
|
@@ -51,7 +55,12 @@ test/app_root/db/migrate/20081223024935_create_categories.rb
|
|
51
55
|
test/app_root/db/migrate/20081223025635_create_countries.rb
|
52
56
|
test/app_root/db/migrate/20081223025653_create_continents.rb
|
53
57
|
test/app_root/db/migrate/20081223025732_create_cities.rb
|
58
|
+
test/app_root/db/migrate/20090102223630_create_netzke_layouts.rb
|
59
|
+
test/app_root/db/migrate/20090102223811_create_netzke_grid_panel_columns.rb
|
54
60
|
test/app_root/script/console
|
61
|
+
test/app_root/vendor/plugins/acts_as_list/init.rb
|
62
|
+
test/app_root/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb
|
63
|
+
test/app_root/vendor/plugins/acts_as_list/README
|
55
64
|
test/ar_ext_test.rb
|
56
65
|
test/border_layout_panel_test.rb
|
57
66
|
test/column_test.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
= netzke-basepack
|
2
|
+
A pack of basic Rails/Ext JS widgets, as a part of Netzke framework. Live demo/tutorials on http://blog.writelesscode.com
|
3
|
+
|
4
|
+
Note that if you would like to modify this code or experiment with it, you may be better off cloning this project into your app's vendor/plugin directory - it will then behave as a Rails plugin.
|
5
|
+
|
6
|
+
= Prerequisites
|
7
|
+
1. Rails >= 2.2
|
8
|
+
2. Ext JS >= 2.0: its root *must* be accessible as RAILS_ROOT/public/extjs. You may symlink your Ext JS library here like this (from your app folder):
|
9
|
+
cd public && ln -s ~/Developer/extjs/ext-2.2 extjs
|
10
|
+
|
11
|
+
3. acts_as_list plugin must be installed:
|
12
|
+
./script/plugin install git://github.com/rails/acts_as_list.git
|
13
|
+
|
14
|
+
= Installation
|
15
|
+
Install the gem:
|
16
|
+
gem install netzke-basepack
|
17
|
+
|
18
|
+
Include it into environment.rb:
|
19
|
+
config.gem "netzke-basepack"
|
20
|
+
|
21
|
+
Include mapping for Netzke controller providing *.js and *.css (in routes.rb):
|
22
|
+
map.netzke
|
23
|
+
|
24
|
+
= Usage
|
25
|
+
First, run the generators to have the necessary migrations:
|
26
|
+
./script/generate netzke_core
|
27
|
+
./script/generate netzke_grid_panel
|
28
|
+
|
29
|
+
Do the migrations:
|
30
|
+
rake db:migrate
|
31
|
+
|
32
|
+
The following example will provide you with a grid-based scaffold for ActiveRecord-model called Book. You may generate it like this:
|
33
|
+
./script/generate model Book title:string amount:integer
|
34
|
+
(don't forget to run the migrations after it)
|
35
|
+
|
36
|
+
In the controller declare the widget:
|
37
|
+
|
38
|
+
class WelcomeController < ApplicationController
|
39
|
+
netzke :books, :widget_class_name => 'GridPanel', :data_class_name => 'Book'
|
40
|
+
end
|
41
|
+
|
42
|
+
After a widget is declared in the controller, it can be accessed in 3 different ways: 1) loaded by means of an automatically created controller action which will produce a basic HTML-page with the widget (handy for testing), 2) embedded directly into a view (by means of helpers), 3) dynamically loaded by other widgets (usually by the widget of class 'Application', if you want a desktop-like, AJAX-driven web-app).
|
43
|
+
|
44
|
+
== Using automatically created controller action
|
45
|
+
Without writing any more code, you can access the widget by http://localhost:3000/welcome/books_test. That is to say, you simply append _test to your widget's name (as declared in the controller) to get the action name.
|
46
|
+
|
47
|
+
== Embedding a widget into a view
|
48
|
+
netzke-core plugin provides the following 2 helpers to put inside your head-tag (use it in your layout):
|
49
|
+
|
50
|
+
1. netzke_js_include - to include extjs and netzke javascript files
|
51
|
+
2. netzke_css_include - to include the css. This one can take a parameter to specify a color schema you wish for Ext JS, e.g.: netzke_css_include(:gray)
|
52
|
+
|
53
|
+
Declaring a widget in the controller provides you with a couple of helpers that can be used in the view:
|
54
|
+
|
55
|
+
1. books_class_definition will contain the javascript code defining the code for the JS class.
|
56
|
+
2. books_widget_instance will declare a local javascript variable called book.
|
57
|
+
|
58
|
+
Use these helpers inside of the script-tag like the following (in the view):
|
59
|
+
|
60
|
+
<script type="text/javascript" charset="utf-8">
|
61
|
+
<%= books_class_definition %>
|
62
|
+
Ext.onReady(function(){
|
63
|
+
<%= books_widget_instance %>
|
64
|
+
books.render("books");
|
65
|
+
})
|
66
|
+
</script>
|
67
|
+
<div id="books">the widget will be rendered in this div</div>
|
68
|
+
|
69
|
+
If your layout already calls yield :javascripts wrapped in the <script>-tag, you can have all javascript-code in one place on the page:
|
70
|
+
|
71
|
+
<% content_for :javascripts do %>
|
72
|
+
<%= books_class_definition %>
|
73
|
+
Ext.onReady(function(){
|
74
|
+
<%= books_widget_instance %>
|
75
|
+
books.render("books");
|
76
|
+
})
|
77
|
+
<% end %>
|
78
|
+
<p>... your page content here ...</p>
|
79
|
+
<div id="books">the widget will be rendered in this div</div>
|
80
|
+
|
81
|
+
== Dynamic loading of widgets
|
82
|
+
TODO: this part will be covered later
|
83
|
+
|
84
|
+
= Credentials
|
85
|
+
Testing done with the help of http://github.com/pluginaweek/plugin_test_helper
|
86
|
+
|
87
|
+
Copyright (c) 2009 Sergei Kozlov, released under the MIT license
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ Echoe.new("netzke-basepack") do |p|
|
|
5
5
|
p.email = "sergei@writelesscode.com"
|
6
6
|
p.summary = "Base Netzke widgets - grid, form, tree, and more"
|
7
7
|
p.url = "http://writelesscode.com"
|
8
|
-
p.runtime_dependencies = ["searchlogic >=1.6.2", "netzke-core >= 0.2.
|
8
|
+
p.runtime_dependencies = ["searchlogic >=1.6.2", "netzke-core >= 0.2.2"]
|
9
9
|
p.development_dependencies = []
|
10
10
|
p.test_pattern = 'test/**/*_test.rb'
|
11
11
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreateNetzkeFormPanelFields < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :netzke_form_panel_fields do |t|
|
4
|
+
t.string :name
|
5
|
+
t.string :label
|
6
|
+
t.boolean :read_only
|
7
|
+
t.integer :position
|
8
|
+
t.boolean :hidden
|
9
|
+
t.integer :width
|
10
|
+
t.integer :height
|
11
|
+
t.string :editor, :limit => 32
|
12
|
+
|
13
|
+
t.integer :layout_id
|
14
|
+
|
15
|
+
t.timestamps
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.down
|
20
|
+
drop_table :netzke_form_panel_fields
|
21
|
+
end
|
22
|
+
end
|
File without changes
|
data/generators/{netzke_basepack → netzke_grid_panel}/templates/create_netzke_grid_panel_columns.rb
RENAMED
File without changes
|
data/javascripts/basepack.js
CHANGED
@@ -49,4 +49,34 @@ Ext.netzke.filterMap = {
|
|
49
49
|
checkbox:'Boolean',
|
50
50
|
combo_box:'String',
|
51
51
|
date:'Date'
|
52
|
-
}
|
52
|
+
}
|
53
|
+
|
54
|
+
Ext.data.RecordArrayReader = Ext.extend(Ext.data.JsonReader, {
|
55
|
+
/**
|
56
|
+
* Create a data block containing Ext.data.Records from an Array.
|
57
|
+
* @param {Object} o An Array of row objects which represents the dataset.
|
58
|
+
* @return {Object} data A data block which is used by an Ext.data.Store object as
|
59
|
+
* a cache of Ext.data.Records.
|
60
|
+
*/
|
61
|
+
readRecord : function(o){
|
62
|
+
var sid = this.meta ? this.meta.id : null;
|
63
|
+
var recordType = this.recordType, fields = recordType.prototype.fields;
|
64
|
+
var records = [];
|
65
|
+
var root = o;
|
66
|
+
// for(var i = 0; i < root.length; i++){
|
67
|
+
var n = root;
|
68
|
+
var values = {};
|
69
|
+
var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
|
70
|
+
for(var j = 0, jlen = fields.length; j < jlen; j++){
|
71
|
+
var f = fields.items[j];
|
72
|
+
var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
|
73
|
+
var v = n[k] !== undefined ? n[k] : f.defaultValue;
|
74
|
+
v = f.convert(v, n);
|
75
|
+
values[f.name] = v;
|
76
|
+
}
|
77
|
+
var record = new recordType(values, id);
|
78
|
+
record.json = n;
|
79
|
+
// }
|
80
|
+
return record;
|
81
|
+
}
|
82
|
+
});
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class NetzkeFormPanelField < ActiveRecord::Base
|
2
|
+
belongs_to :layout, :class_name => "NetzkeLayout"
|
3
|
+
|
4
|
+
acts_as_list :scope => :layout
|
5
|
+
|
6
|
+
def self.create_layout_for_widget(widget)
|
7
|
+
layout = NetzkeLayout.create(:widget_name => widget.id_name, :items_class => self.name, :user_id => NetzkeLayout.user_id)
|
8
|
+
|
9
|
+
columns = Netzke::Column.default_fields_for_widget(widget)
|
10
|
+
|
11
|
+
for c in columns
|
12
|
+
config_for_create = c.merge(:layout_id => layout.id).stringify_values!
|
13
|
+
create(config_for_create)
|
14
|
+
end
|
15
|
+
|
16
|
+
layout
|
17
|
+
end
|
18
|
+
end
|
@@ -3,14 +3,8 @@ class NetzkeGridPanelColumn < ActiveRecord::Base
|
|
3
3
|
|
4
4
|
acts_as_list :scope => :layout
|
5
5
|
|
6
|
-
# old?
|
7
|
-
# def self.create_with_defaults(column_config, klass)
|
8
|
-
# create(klass.default_column_config(column_config).stringify_values!)
|
9
|
-
# end
|
10
|
-
|
11
6
|
def self.create_layout_for_widget(widget)
|
12
|
-
layout = NetzkeLayout.
|
13
|
-
|
7
|
+
layout = NetzkeLayout.create_with_user(:widget_name => widget.id_name, :items_class => self.name)
|
14
8
|
columns = Netzke::Column.default_columns_for_widget(widget)
|
15
9
|
|
16
10
|
for c in columns
|
data/lib/netzke/ar_ext.rb
CHANGED
@@ -49,7 +49,24 @@ module Netzke
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def to_array(columns)
|
53
|
+
res = []
|
54
|
+
for c in columns
|
55
|
+
method = c.is_a?(Symbol) ? c : c[:name]
|
56
|
+
res << send(method)
|
57
|
+
end
|
58
|
+
res
|
59
|
+
end
|
60
|
+
|
52
61
|
module ActiveRecordClassMethods
|
62
|
+
# next and previous to id records
|
63
|
+
def next(id)
|
64
|
+
find(:first, :conditions => ["#{primary_key} > ?", id])
|
65
|
+
end
|
66
|
+
def previous(id)
|
67
|
+
find(:first, :conditions => ["#{primary_key} < ?", id], :order => "#{primary_key} DESC")
|
68
|
+
end
|
69
|
+
|
53
70
|
# Returns all unique values for a column, filtered by the query
|
54
71
|
def choices_for(column, query = nil)
|
55
72
|
if respond_to?("#{column}_choices", query)
|
@@ -107,18 +124,8 @@ module Netzke
|
|
107
124
|
read_inheritable_attribute(:virtual_columns).keys.include?(column)
|
108
125
|
end
|
109
126
|
|
110
|
-
|
111
|
-
|
112
|
-
#
|
113
|
-
|
114
|
-
DEFAULT_COLUMN_WIDTH = 100
|
115
|
-
|
116
|
-
# Returns default column config understood by Netzke::GridPanel
|
117
|
-
# Argument: column name (as Symbol) or column config
|
118
|
-
def default_column_config(config)
|
119
|
-
config = config.dup
|
120
|
-
# config = config.dup # to not touch the original config
|
121
|
-
config = {:name => config} if config.is_a?(Symbol) # if got a column name
|
127
|
+
def default_dbfield_config(config, mode = :grid)
|
128
|
+
config = config.is_a?(Symbol) ? {:name => config} : config.dup
|
122
129
|
|
123
130
|
# detect ActiveRecord column type (if the column is "real") or fall back to :virtual
|
124
131
|
type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
|
@@ -128,9 +135,12 @@ module Netzke
|
|
128
135
|
:label => config[:label] || config[:name].to_s.gsub('__', '_').humanize,
|
129
136
|
:read_only => config[:name] == :id, # make "id" column read-only by default
|
130
137
|
:hidden => config[:name] == :id, # hide "id" column by default
|
131
|
-
:width => DEFAULT_COLUMN_WIDTH,
|
138
|
+
:width => mode == :grid ? DEFAULT_COLUMN_WIDTH : DEFAULT_FIELD_WIDTH,
|
132
139
|
:editor => ext_editor(type)
|
133
140
|
}
|
141
|
+
|
142
|
+
# for forms fields also set up the height
|
143
|
+
res.merge!(:height => DEFAULT_FIELD_HEIGHT) if mode == :form
|
134
144
|
|
135
145
|
# detect :assoc__method
|
136
146
|
if config[:name].to_s.index('__')
|
@@ -157,13 +167,38 @@ module Netzke
|
|
157
167
|
end
|
158
168
|
|
159
169
|
#
|
160
|
-
# Used by Netzke::
|
170
|
+
# Used by Netzke::GridPanel
|
171
|
+
#
|
172
|
+
|
173
|
+
DEFAULT_COLUMN_WIDTH = 100
|
174
|
+
|
175
|
+
# Returns default column config understood by Netzke::GridPanel
|
176
|
+
# Argument: column name (as Symbol) or column config
|
177
|
+
def default_column_config(config)
|
178
|
+
default_dbfield_config(config, :grid)
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# Used by Netzke::FormPanel
|
161
183
|
#
|
162
184
|
|
163
185
|
DEFAULT_FIELD_WIDTH = 100
|
164
|
-
DEFAULT_FIELD_HEIGHT =
|
186
|
+
DEFAULT_FIELD_HEIGHT = nil
|
165
187
|
def default_field_config(config)
|
166
|
-
#
|
188
|
+
# default_dbfield_config(config, :form)
|
189
|
+
config = config.is_a?(Symbol) ? {:name => config} : config.dup
|
190
|
+
|
191
|
+
# detect ActiveRecord column type (if the column is "real") or fall back to :virtual
|
192
|
+
type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
|
193
|
+
|
194
|
+
res = {
|
195
|
+
:name => config[:name].to_s || "unnamed",
|
196
|
+
:field_label => config[:field_label] || config[:name].to_s.gsub('__', '_').humanize,
|
197
|
+
:disabled => config[:name] == :id, # make "id" column disabled by default
|
198
|
+
# :hidden => config[:name] == :id, # hide "id" column by default
|
199
|
+
:xtype => XTYPE_MAP[type]
|
200
|
+
}
|
201
|
+
|
167
202
|
end
|
168
203
|
|
169
204
|
private
|
@@ -176,6 +211,14 @@ module Netzke
|
|
176
211
|
:string => :text_field
|
177
212
|
}
|
178
213
|
|
214
|
+
XTYPE_MAP = {
|
215
|
+
:integer => :numberfield,
|
216
|
+
:boolean => :textfield,
|
217
|
+
:date => :datefield,
|
218
|
+
:datetime => :datefield,
|
219
|
+
:string => :textfield
|
220
|
+
}
|
221
|
+
|
179
222
|
def ext_editor(type)
|
180
223
|
TYPE_EDITOR_MAP[type] || :text_field # fall back to :text_field
|
181
224
|
end
|
@@ -20,7 +20,7 @@ module Netzke
|
|
20
20
|
Ext.each(['center', 'west', 'east', 'south', 'north'], function(r){
|
21
21
|
var configName = r+'Config';
|
22
22
|
if (config[configName]){
|
23
|
-
var regionConfig = config[
|
23
|
+
var regionConfig = config.regions[r] || {};
|
24
24
|
regionConfig.layout = 'fit';
|
25
25
|
regionConfig.region = r;
|
26
26
|
regionConfig.items = [new Ext.componentCache[config[configName].widgetClassName](config[configName])]
|
@@ -75,39 +75,28 @@ module Netzke
|
|
75
75
|
config[:regions] || {}
|
76
76
|
end
|
77
77
|
|
78
|
-
# def items
|
79
|
-
# res = []
|
80
|
-
# config[:regions].each_pair do |k,v|
|
81
|
-
# width = v.delete(:width)
|
82
|
-
# height = v.delete(:height)
|
83
|
-
# split = v[:split].nil? ? true : v.delete(:split) # split is by default true
|
84
|
-
# region_config = {
|
85
|
-
# :region => k,
|
86
|
-
# :width => @pref["#{k}_width"] || width || 100,
|
87
|
-
# :height => @pref["#{k}_height"] || height || 100,
|
88
|
-
# :split => split,
|
89
|
-
# :layout => v.delete(:layout) || 'fit',
|
90
|
-
# :id => @id_name + "_#{k}_region"
|
91
|
-
# }
|
92
|
-
# region_widget_instance = "Netzke::#{v[:widget_class_name]}".constantize.new(v.merge(:name => "#{id_name}__#{k}"))
|
93
|
-
# region_config.merge!(v)
|
94
|
-
# region_config[:items] = ["new Ext.componentCache['#{v[:widget_class_name]}'](#{region_widget_instance.js_config.to_js})".l]
|
95
|
-
# res << region_config
|
96
|
-
# end
|
97
|
-
# res
|
98
|
-
# end
|
99
|
-
|
100
78
|
def region_aggregatees
|
101
79
|
aggregatees.reject{ |k,v| !REGIONS.include?(k) }
|
102
80
|
end
|
103
81
|
|
104
|
-
|
105
|
-
|
106
|
-
|
82
|
+
def js_config
|
83
|
+
regions = {}
|
84
|
+
REGIONS.each do |r|
|
85
|
+
if region_aggr = aggregatees[r]
|
86
|
+
regions.merge!(r => region_aggr[:region_config] || {})
|
87
|
+
height = persistent_config["#{r}_height"] ||= regions[r][:height] if regions[r][:height]
|
88
|
+
width = persistent_config["#{r}_width"] ||= regions[r][:width] if regions[r][:width]
|
89
|
+
regions[r].merge!(:height => height)
|
90
|
+
regions[r].merge!(:width => width)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
super.merge(:regions => regions)
|
94
|
+
end
|
107
95
|
|
108
|
-
def
|
109
|
-
|
110
|
-
|
96
|
+
def resize_region(params)
|
97
|
+
persistent_config["#{params[:region_name]}_width"] = params[:new_width].to_i if params[:new_width]
|
98
|
+
persistent_config["#{params[:region_name]}_height"] = params[:new_height].to_i if params[:new_height]
|
99
|
+
{}
|
111
100
|
end
|
112
101
|
|
113
102
|
protected
|