netzke-basepack 0.1.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 +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
|