netzke-basepack 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +18 -0
- data/LICENSE +20 -0
- data/Manifest +64 -0
- data/README.mdown +74 -0
- data/Rakefile +14 -0
- data/generators/netzke_basepack/USAGE +8 -0
- data/generators/netzke_basepack/netzke_basepack_generator.rb +8 -0
- data/generators/netzke_basepack/netzke_grid_generator.rb +7 -0
- data/generators/netzke_basepack/templates/create_netzke_grid_columns.rb +21 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/javascripts/basepack.js +52 -0
- data/javascripts/filters.js +7 -0
- data/lib/app/models/netzke_grid_column.rb +23 -0
- data/lib/netzke-basepack.rb +28 -0
- data/lib/netzke/accordion.rb +11 -0
- data/lib/netzke/ar_ext.rb +163 -0
- data/lib/netzke/column.rb +43 -0
- data/lib/netzke/container.rb +81 -0
- data/lib/netzke/grid.rb +120 -0
- data/lib/netzke/grid_interface.rb +156 -0
- data/lib/netzke/grid_js_builder.rb +276 -0
- data/lib/netzke/preference_grid.rb +43 -0
- data/lib/netzke/properties_tool.rb +66 -0
- data/lib/netzke/property_grid.rb +60 -0
- data/netzke-basepack.gemspec +38 -0
- data/tasks/netzke_basepack_tasks.rake +4 -0
- data/test/app_root/app/controllers/application.rb +2 -0
- data/test/app_root/app/models/book.rb +9 -0
- data/test/app_root/app/models/category.rb +2 -0
- data/test/app_root/app/models/city.rb +3 -0
- data/test/app_root/app/models/continent.rb +2 -0
- data/test/app_root/app/models/country.rb +3 -0
- data/test/app_root/app/models/genre.rb +3 -0
- data/test/app_root/config/boot.rb +114 -0
- data/test/app_root/config/database.yml +21 -0
- data/test/app_root/config/environment.rb +13 -0
- data/test/app_root/config/environments/in_memory.rb +0 -0
- data/test/app_root/config/environments/mysql.rb +0 -0
- data/test/app_root/config/environments/postgresql.rb +0 -0
- data/test/app_root/config/environments/sqlite.rb +0 -0
- data/test/app_root/config/environments/sqlite3.rb +0 -0
- data/test/app_root/config/routes.rb +4 -0
- data/test/app_root/db/migrate/20081222033343_create_books.rb +15 -0
- data/test/app_root/db/migrate/20081222033440_create_genres.rb +14 -0
- data/test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb +18 -0
- data/test/app_root/db/migrate/20081223024935_create_categories.rb +13 -0
- data/test/app_root/db/migrate/20081223025635_create_countries.rb +14 -0
- data/test/app_root/db/migrate/20081223025653_create_continents.rb +13 -0
- data/test/app_root/db/migrate/20081223025732_create_cities.rb +15 -0
- data/test/app_root/script/console +7 -0
- data/test/ar_ext_test.rb +39 -0
- data/test/column_test.rb +27 -0
- data/test/console_with_fixtures.rb +4 -0
- data/test/fixtures/books.yml +9 -0
- data/test/fixtures/categories.yml +7 -0
- data/test/fixtures/cities.yml +21 -0
- data/test/fixtures/continents.yml +7 -0
- data/test/fixtures/countries.yml +9 -0
- data/test/fixtures/genres.yml +9 -0
- data/test/grid_test.rb +43 -0
- data/test/netzke_basepack_test.rb +8 -0
- data/test/schema.rb +10 -0
- data/test/test_helper.rb +20 -0
- data/uninstall.rb +1 -0
- metadata +162 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
v0.1.2
|
2
|
+
Updated README with an example of stand-alone widget usage
|
3
|
+
Meta: updated netzke-core version (dependency)
|
4
|
+
|
5
|
+
v0.1.1.2
|
6
|
+
Meta: updated netzke-core version (dependency)
|
7
|
+
|
8
|
+
v0.1.1.1
|
9
|
+
Meta: github gem naming convention
|
10
|
+
|
11
|
+
v0.1.1
|
12
|
+
Cleaner exception handling while loading data to grid
|
13
|
+
Column resize & move functionality enabled by default
|
14
|
+
Column filters added
|
15
|
+
|
16
|
+
v0.1.0.1 Meta work: replacing underscore with dash in the name
|
17
|
+
|
18
|
+
v0.1.0 Initial release
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Sergei Kozlov
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
generators/netzke_basepack/netzke_basepack_generator.rb
|
3
|
+
generators/netzke_basepack/netzke_grid_generator.rb
|
4
|
+
generators/netzke_basepack/templates/create_netzke_grid_columns.rb
|
5
|
+
generators/netzke_basepack/USAGE
|
6
|
+
init.rb
|
7
|
+
install.rb
|
8
|
+
javascripts/basepack.js
|
9
|
+
javascripts/filters.js
|
10
|
+
lib/app/models/netzke_grid_column.rb
|
11
|
+
lib/netzke/accordion.rb
|
12
|
+
lib/netzke/ar_ext.rb
|
13
|
+
lib/netzke/column.rb
|
14
|
+
lib/netzke/container.rb
|
15
|
+
lib/netzke/grid.rb
|
16
|
+
lib/netzke/grid_interface.rb
|
17
|
+
lib/netzke/grid_js_builder.rb
|
18
|
+
lib/netzke/preference_grid.rb
|
19
|
+
lib/netzke/properties_tool.rb
|
20
|
+
lib/netzke/property_grid.rb
|
21
|
+
lib/netzke-basepack.rb
|
22
|
+
LICENSE
|
23
|
+
Manifest
|
24
|
+
Rakefile
|
25
|
+
README.mdown
|
26
|
+
tasks/netzke_basepack_tasks.rake
|
27
|
+
test/app_root/app/controllers/application.rb
|
28
|
+
test/app_root/app/models/book.rb
|
29
|
+
test/app_root/app/models/category.rb
|
30
|
+
test/app_root/app/models/city.rb
|
31
|
+
test/app_root/app/models/continent.rb
|
32
|
+
test/app_root/app/models/country.rb
|
33
|
+
test/app_root/app/models/genre.rb
|
34
|
+
test/app_root/config/boot.rb
|
35
|
+
test/app_root/config/database.yml
|
36
|
+
test/app_root/config/environment.rb
|
37
|
+
test/app_root/config/environments/in_memory.rb
|
38
|
+
test/app_root/config/environments/mysql.rb
|
39
|
+
test/app_root/config/environments/postgresql.rb
|
40
|
+
test/app_root/config/environments/sqlite.rb
|
41
|
+
test/app_root/config/environments/sqlite3.rb
|
42
|
+
test/app_root/config/routes.rb
|
43
|
+
test/app_root/db/migrate/20081222033343_create_books.rb
|
44
|
+
test/app_root/db/migrate/20081222033440_create_genres.rb
|
45
|
+
test/app_root/db/migrate/20081222035855_create_netzke_preferences.rb
|
46
|
+
test/app_root/db/migrate/20081223024935_create_categories.rb
|
47
|
+
test/app_root/db/migrate/20081223025635_create_countries.rb
|
48
|
+
test/app_root/db/migrate/20081223025653_create_continents.rb
|
49
|
+
test/app_root/db/migrate/20081223025732_create_cities.rb
|
50
|
+
test/app_root/script/console
|
51
|
+
test/ar_ext_test.rb
|
52
|
+
test/column_test.rb
|
53
|
+
test/console_with_fixtures.rb
|
54
|
+
test/fixtures/books.yml
|
55
|
+
test/fixtures/categories.yml
|
56
|
+
test/fixtures/cities.yml
|
57
|
+
test/fixtures/continents.yml
|
58
|
+
test/fixtures/countries.yml
|
59
|
+
test/fixtures/genres.yml
|
60
|
+
test/grid_test.rb
|
61
|
+
test/netzke_basepack_test.rb
|
62
|
+
test/schema.rb
|
63
|
+
test/test_helper.rb
|
64
|
+
uninstall.rb
|
data/README.mdown
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# netzke-basepack
|
2
|
+
A pack of basic Rails/ExtJS widgets, as a part of Netzke framework.
|
3
|
+
|
4
|
+
# Prerequisites
|
5
|
+
1. Rails >= 2.2
|
6
|
+
2. ExtJS >= 2.0: its root *must* be accessible as RAILS_ROOT/public/extjs (you may symlink your ExtJS library here)
|
7
|
+
|
8
|
+
# Installation
|
9
|
+
gem install skozlov-netzke-basepack --source http://gems.github.com
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
# Usage
|
14
|
+
First, run the generators to have the necessary migrations (if not done so already):
|
15
|
+
|
16
|
+
`./script/generate netzke_core`
|
17
|
+
|
18
|
+
`./script/generate netzke_grid`
|
19
|
+
|
20
|
+
Do the migrations:
|
21
|
+
|
22
|
+
`rake db:migrate`
|
23
|
+
|
24
|
+
This example will provide you with a grid-based scaffold for ActiveRecord-model called `Book`. If you don't have it already, you may generate it like this:
|
25
|
+
|
26
|
+
`./script/generate model Book title:string amount:integer`
|
27
|
+
(don't forget to do the migrations after this)
|
28
|
+
|
29
|
+
In the controller declare the widget:
|
30
|
+
|
31
|
+
`class WelcomeController < ApplicationController
|
32
|
+
netzke_widget :books, :widget_class_name => 'Grid', :data_class_name => 'Book'
|
33
|
+
end`
|
34
|
+
|
35
|
+
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).
|
36
|
+
|
37
|
+
## Using automatically created controller action
|
38
|
+
Without writing any more code, you can access the widget by `http://yourhost/welcome/book_test`. That is to say, you append `_test` to your widget's name (as declared in the controller) to get the action name.
|
39
|
+
|
40
|
+
## Embedding a widget into a view
|
41
|
+
Declaring a widget in the controller provides you with a couple of helpers that can be used in the view:
|
42
|
+
|
43
|
+
1. `books_class_definition` will contain the javascript code defining the code for the JS class.
|
44
|
+
2. `books_widget_instance` will declare a local javascript variable called `book`.
|
45
|
+
|
46
|
+
Use these helpers inside of the `<script>`-tag like the following (in the view):
|
47
|
+
|
48
|
+
`<script type="text/javascript" charset="utf-8">
|
49
|
+
<%= books_class_definition %>
|
50
|
+
Ext.onReady(function(){
|
51
|
+
<%= books_widget_instance %>
|
52
|
+
books.render("books");
|
53
|
+
})
|
54
|
+
</script>
|
55
|
+
<div id="books">the widget will be rendered in this div</div>`
|
56
|
+
|
57
|
+
If your layout already calls `yield :javascripts` wrapped in the `<script>`-tag, you can have all javascript-code in one place on the page:
|
58
|
+
|
59
|
+
`<% content_for :javascripts do %>
|
60
|
+
<%= books_class_definition %>
|
61
|
+
Ext.onReady(function(){
|
62
|
+
<%= books_widget_instance %>
|
63
|
+
books.render("books");
|
64
|
+
})
|
65
|
+
<% end %>
|
66
|
+
<div id="books">the widget will be rendered in this div</div>`
|
67
|
+
|
68
|
+
## Dynamic loading of widgets
|
69
|
+
TODO: will be covered later
|
70
|
+
|
71
|
+
# Credentials
|
72
|
+
Testing done with the help of `http://github.com/pluginaweek/plugin_test_helper`
|
73
|
+
|
74
|
+
Copyright (c) 2008 Sergei Kozlov, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
|
3
|
+
Echoe.new("netzke-basepack") do |p|
|
4
|
+
p.author = "Sergei Kozlov"
|
5
|
+
p.email = "sergei@writelesscode.com"
|
6
|
+
p.summary = "Base Netzke widgets - grid, form, tree, and more"
|
7
|
+
p.url = "http://writelesscode.com"
|
8
|
+
p.runtime_dependencies = ["searchlogic >=1.6.2", "netzke-core >= 0.1.1.1"]
|
9
|
+
p.development_dependencies = []
|
10
|
+
p.test_pattern = 'test/**/*_test.rb'
|
11
|
+
|
12
|
+
# fixing the problem with lib/*-* files being removed while doing manifest
|
13
|
+
p.clean_pattern = ["pkg", "doc", 'build/*', '**/coverage', '**/*.o', '**/*.so', '**/*.a', '**/*.log', "{ext,lib}/*.{bundle,so,obj,pdb,lib,def,exp}", "ext/Makefile", "{ext,lib}/**/*.{bundle,so,obj,pdb,lib,def,exp}", "ext/**/Makefile", "pkg", "*.gem", ".config"]
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateNetzkeGridColumns < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :netzke_grid_columns 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.string :shows_as, :limit => 32
|
11
|
+
|
12
|
+
t.integer :layout_id
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :netzke_grid_columns
|
20
|
+
end
|
21
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# require 'netzke-basepack'
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
@@ -0,0 +1,52 @@
|
|
1
|
+
// Editors for grid cells and form fields
|
2
|
+
Ext.netzke.editors = {
|
3
|
+
combo_box: function(c, config){
|
4
|
+
var row = Ext.data.Record.create([{name:'id'}])
|
5
|
+
var store = new Ext.data.Store({
|
6
|
+
proxy: new Ext.data.HttpProxy({url:config.interface.getCbChoices, jsonData:{column:c.name}}),
|
7
|
+
reader: new Ext.data.ArrayReader({root:'data', id:0}, row)
|
8
|
+
})
|
9
|
+
return new Ext.form.ComboBox({
|
10
|
+
mode: 'remote',
|
11
|
+
displayField:'id',
|
12
|
+
valueField:'id',
|
13
|
+
triggerAction:'all',
|
14
|
+
store: store
|
15
|
+
})
|
16
|
+
},
|
17
|
+
|
18
|
+
text_field: function(c, config){
|
19
|
+
return new Ext.form.TextField({
|
20
|
+
selectOnFocus:true
|
21
|
+
})
|
22
|
+
},
|
23
|
+
|
24
|
+
checkbox: function(c, config){
|
25
|
+
return new Ext.form.TextField({
|
26
|
+
selectOnFocus:true
|
27
|
+
})
|
28
|
+
},
|
29
|
+
|
30
|
+
number_field: function(c, config){
|
31
|
+
return new Ext.form.NumberField({
|
32
|
+
selectOnFocus:true
|
33
|
+
})
|
34
|
+
},
|
35
|
+
|
36
|
+
// TODO: it's simply a text field for now
|
37
|
+
datetime: function(c, config){
|
38
|
+
return new Ext.form.TextField({
|
39
|
+
selectOnFocus:true
|
40
|
+
})
|
41
|
+
}
|
42
|
+
};
|
43
|
+
|
44
|
+
// Mapping of showsAs field to grid filters
|
45
|
+
Ext.netzke.filterMap = {
|
46
|
+
number_field:'Numeric',
|
47
|
+
text_field:'String',
|
48
|
+
datetime:'String',
|
49
|
+
checkbox:'Boolean',
|
50
|
+
combo_box:'String',
|
51
|
+
date:'Date'
|
52
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Ext.menu.RangeMenu.prototype.icons = {
|
2
|
+
gt: '/extjs/examples/grid-filtering/img/greater_then.png',
|
3
|
+
lt: '/extjs/examples/grid-filtering/img/less_then.png',
|
4
|
+
eq: '/extjs/examples/grid-filtering/img/equals.png'
|
5
|
+
};
|
6
|
+
|
7
|
+
Ext.grid.filter.StringFilter.prototype.icon = '/extjs/examples/grid-filtering/img/find.png';
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class NetzkeGridColumn < ActiveRecord::Base
|
2
|
+
belongs_to :layout, :class_name => "NetzkeLayout"
|
3
|
+
|
4
|
+
acts_as_list :scope => :layout
|
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
|
+
def self.create_layout_for_widget(widget)
|
12
|
+
layout = NetzkeLayout.create(:widget_name => widget.id_name, :items_class => self.name, :user_id => NetzkeLayout.user_id)
|
13
|
+
|
14
|
+
columns = Netzke::Column.default_columns_for_widget(widget)
|
15
|
+
|
16
|
+
for c in columns
|
17
|
+
config_for_create = c.merge(:layout_id => layout.id).stringify_values!
|
18
|
+
create(config_for_create)
|
19
|
+
end
|
20
|
+
|
21
|
+
layout
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# External dependencies
|
2
|
+
require 'netzke-core'
|
3
|
+
require 'searchlogic'
|
4
|
+
|
5
|
+
require 'netzke/ar_ext'
|
6
|
+
|
7
|
+
%w{ models }.each do |dir|
|
8
|
+
path = File.join(File.dirname(__FILE__), 'app', dir)
|
9
|
+
$LOAD_PATH << path
|
10
|
+
ActiveSupport::Dependencies.load_paths << path
|
11
|
+
ActiveSupport::Dependencies.load_once_paths.delete(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Include the javascript
|
15
|
+
Netzke::Base.config[:javascripts] << "#{File.dirname(__FILE__)}/../javascripts/basepack.js"
|
16
|
+
|
17
|
+
# TODO: implement configurable loading of JS, to spare the traffic at the initial loading
|
18
|
+
extjs_dir = "#{File.dirname(RAILS_ROOT)}/netzke_tutorial/public/extjs"
|
19
|
+
Netzke::Base.config[:javascripts] << "#{extjs_dir}/examples/grid-filtering/menu/EditableItem.js"
|
20
|
+
Netzke::Base.config[:javascripts] << "#{extjs_dir}/examples/grid-filtering/menu/RangeMenu.js"
|
21
|
+
Netzke::Base.config[:javascripts] << "#{extjs_dir}/examples/grid-filtering/grid/GridFilters.js"
|
22
|
+
%w{Boolean Date List Numeric String}.unshift("").each do |f|
|
23
|
+
Netzke::Base.config[:javascripts] << "#{extjs_dir}/examples/grid-filtering/grid/filter/#{f}Filter.js"
|
24
|
+
end
|
25
|
+
Netzke::Base.config[:javascripts] << "#{File.dirname(__FILE__)}/../javascripts/filters.js"
|
26
|
+
|
27
|
+
# Make this plugin reloadable for easier development
|
28
|
+
ActiveSupport::Dependencies.load_once_paths.delete(File.join(File.dirname(__FILE__)))
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module Netzke
|
2
|
+
module ActiveRecordExtensions
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ActiveRecordClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
#
|
8
|
+
# Allow nested association acces (assocs separated by "." or "__"), e.g.: proxy_service.send('asset__gui_folder__name')
|
9
|
+
# Example:
|
10
|
+
# b = Book.first
|
11
|
+
# b.genre__name = 'Fantasy' => b.genre = Genre.find_by_name('Fantasy')
|
12
|
+
# NOT IMPLEMENTED: ANY USE? b.genre__catalog__name = 'Best sellers' => b.genre_id = b.genre.find_by_catalog_id(Catalog.find_by_name('Best sellers')).id
|
13
|
+
#
|
14
|
+
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
# if refering to a column, just pass it to the originar method_missing
|
17
|
+
return super if self.class.column_names.include?(method.to_s)
|
18
|
+
|
19
|
+
split = method.to_s.split(/\.|__/)
|
20
|
+
if split.size > 1
|
21
|
+
if split.last =~ /=$/
|
22
|
+
if split.size == 2
|
23
|
+
# search for association and assign it to self
|
24
|
+
assoc = self.class.reflect_on_association(split.first.to_sym)
|
25
|
+
assoc_method = split.last.chop
|
26
|
+
if assoc
|
27
|
+
assoc_instance = assoc.klass.send("find_by_#{assoc_method}", *args)
|
28
|
+
raise ArgumentError, "Couldn't find association #{split.first} by #{assoc_method} '#{args.first}'" unless assoc_instance
|
29
|
+
self.send("#{split.first}=", assoc_instance)
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
else
|
37
|
+
res = self
|
38
|
+
split.each do |m|
|
39
|
+
if res.respond_to?(m)
|
40
|
+
res = res.send(m) unless res.nil?
|
41
|
+
else
|
42
|
+
res.nil? ? nil : super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
res
|
46
|
+
end
|
47
|
+
else
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
module ActiveRecordClassMethods
|
54
|
+
def choices_for(column, query = nil)
|
55
|
+
if respond_to?("#{column}_choices", query)
|
56
|
+
# AR class provides the choices itself
|
57
|
+
send("#{column}_choices")
|
58
|
+
else
|
59
|
+
if (assoc_name, *assoc_method = column.split('__')).size > 1
|
60
|
+
# column is an association column
|
61
|
+
assoc_method = assoc_method.join('__') # in case we get something like country__continent__name
|
62
|
+
association = reflect_on_association(assoc_name.to_sym) || raise(NameError, "Association #{assoc_name} not known for class #{name}")
|
63
|
+
association.klass.choices_for(assoc_method, query)
|
64
|
+
else
|
65
|
+
column = assoc_name
|
66
|
+
if self.column_names.include?(column)
|
67
|
+
# it's just a column
|
68
|
+
records = query.nil? ? find_by_sql("select distinct #{column} from #{table_name}") : find_by_sql("select distinct #{column} from #{table_name} where #{column} like '#{query}%'")
|
69
|
+
records.map{|r| r.send(column)}
|
70
|
+
else
|
71
|
+
# it's a "virtual" column - the least effective search
|
72
|
+
records = self.find(:all).map{|r| r.send(column)}.uniq
|
73
|
+
query.nil? ? records : records.select{|r| r.send(column).index(/^#{query}/)}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# which columns are to be picked up by grids and forms
|
80
|
+
def expose_columns(columns, *args)
|
81
|
+
if columns == :all
|
82
|
+
write_inheritable_attribute(:exposed_columns, self.column_names.map(&:to_sym))
|
83
|
+
else
|
84
|
+
write_inheritable_attribute(:exposed_columns, columns)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def exposed_columns
|
89
|
+
read_inheritable_attribute(:exposed_columns) || write_inheritable_attribute(:exposed_columns, expose_columns(:all) + virtual_columns)
|
90
|
+
end
|
91
|
+
|
92
|
+
# virtual "columns" that simply correspond to instance methods of an ActiveRecord class
|
93
|
+
def virtual_column(config)
|
94
|
+
if config.is_a?(Symbol)
|
95
|
+
config = {:name => config}
|
96
|
+
else
|
97
|
+
config = {:name => config.keys.first}.merge(config.values.first)
|
98
|
+
end
|
99
|
+
write_inheritable_attribute(:virtual_columns, (read_inheritable_attribute(:virtual_columns) || []) << config)
|
100
|
+
end
|
101
|
+
|
102
|
+
def virtual_columns
|
103
|
+
read_inheritable_attribute(:virtual_columns) || []
|
104
|
+
end
|
105
|
+
|
106
|
+
def is_virtual_column?(column)
|
107
|
+
read_inheritable_attribute(:virtual_columns).keys.include?(column)
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Used by Netzke::Grid
|
112
|
+
#
|
113
|
+
|
114
|
+
DEFAULT_COLUMN_WIDTH = 100
|
115
|
+
|
116
|
+
def default_column_config(config)
|
117
|
+
config = {:name => config} if config.is_a?(Symbol) # optionally we may get only a column name (as Symbol)
|
118
|
+
type = (columns_hash[config[:name].to_s] && columns_hash[config[:name].to_s].type) || :virtual
|
119
|
+
|
120
|
+
# general config
|
121
|
+
res = {
|
122
|
+
:name => config[:name].to_s || "unnamed",
|
123
|
+
:label => config[:label] || config[:name].to_s.humanize,
|
124
|
+
:read_only => config[:name] == :id, # make "id" column read-only by default
|
125
|
+
:hidden => config[:name] == :id, # hide "id" column by default
|
126
|
+
:width => DEFAULT_COLUMN_WIDTH,
|
127
|
+
:shows_as => :text_field
|
128
|
+
}
|
129
|
+
|
130
|
+
case type
|
131
|
+
when :integer
|
132
|
+
res[:shows_as] = :number_field
|
133
|
+
when :boolean
|
134
|
+
res[:shows_as] = :checkbox
|
135
|
+
res[:width] = 50
|
136
|
+
when :date
|
137
|
+
res[:shows_as] = :date_field
|
138
|
+
when :datetime
|
139
|
+
res[:shows_as] = :datetime
|
140
|
+
when :string
|
141
|
+
res[:shows_as] = :text_field
|
142
|
+
end
|
143
|
+
|
144
|
+
res.merge(config) # merge with custom confg (it has the priority)
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Used by Netzke::Form
|
149
|
+
#
|
150
|
+
|
151
|
+
DEFAULT_FIELD_WIDTH = 100
|
152
|
+
DEFAULT_FIELD_HEIGHT = 50
|
153
|
+
def default_field_config(config)
|
154
|
+
# TODO
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
ActiveRecord::Base.class_eval do
|
162
|
+
include Netzke::ActiveRecordExtensions
|
163
|
+
end
|