activegrid 1.0.0
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/LICENSE +0 -0
- data/README.md +28 -0
- data/Rakefile +39 -0
- data/app/assets/javascripts/activegrid.js +73 -0
- data/app/assets/stylesheets/activegrid.css +4 -0
- data/app/controllers/active_grid/controller.rb +53 -0
- data/app/lib/active_grid/column.rb +42 -0
- data/app/lib/active_grid/grid.rb +90 -0
- data/app/views/active_grid/update.js.erb +1 -0
- data/lib/activegrid/engine.rb +10 -0
- data/lib/activegrid/version.rb +3 -0
- data/lib/activegrid.rb +4 -0
- data/test/activegrid_test.rb +7 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +4 -0
- data/test/dummy/app/assets/stylesheets/application.css +5 -0
- data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/products_controller.rb +81 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/products_helper.rb +2 -0
- data/test/dummy/app/models/product.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/products/_form.html.erb +33 -0
- data/test/dummy/app/views/products/_grid.html.erb +9 -0
- data/test/dummy/app/views/products/edit.html.erb +6 -0
- data/test/dummy/app/views/products/index.html.erb +7 -0
- data/test/dummy/app/views/products/new.html.erb +5 -0
- data/test/dummy/app/views/products/show.html.erb +25 -0
- data/test/dummy/config/application.rb +18 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +17 -0
- data/test/dummy/config/environment.rb +3 -0
- data/test/dummy/config/environments/development.rb +18 -0
- data/test/dummy/config/environments/production.rb +18 -0
- data/test/dummy/config/environments/test.rb +19 -0
- data/test/dummy/config/initializers/secret_token.rb +1 -0
- data/test/dummy/config/initializers/session_store.rb +1 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +7 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config.ru +2 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20111015173017_create_products.rb +12 -0
- data/test/dummy/db/schema.rb +25 -0
- data/test/dummy/db/seeds.rb +3 -0
- data/test/dummy/log/development.log +13196 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +5 -0
- data/test/dummy/tmp/cache/assets/CC9/CF0/sprockets%2F2c475587282720babaa30bd125046c6d +0 -0
- data/test/dummy/tmp/cache/assets/CF0/1D0/sprockets%2F6fc757c2c8329244ca95d6909865bbc2 +0 -0
- data/test/dummy/tmp/cache/assets/CF2/E30/sprockets%2F9690cd655384cc9f98b5a12689a04cb6 +0 -0
- data/test/dummy/tmp/cache/assets/D11/D20/sprockets%2Fcac21eac42152981882bf9e489316af4 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +0 -0
- data/test/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +0 -0
- data/test/dummy/tmp/cache/assets/D9B/900/sprockets%2F47e1b36aecf9211f751cad5cbd1f7466 +0 -0
- data/test/dummy/tmp/cache/assets/DA1/CB0/sprockets%2Fd873f0f0b7a49a21b56a28e565e7deea +0 -0
- data/test/dummy/tmp/cache/assets/DA4/2A0/sprockets%2Ff78aae8f781bb900e68ba4c9721fbe22 +0 -0
- data/test/dummy/tmp/cache/assets/DAD/F00/sprockets%2Fed0c338098c67fff252ea6f6c279ca4f +0 -0
- data/test/dummy/tmp/cache/assets/DF9/B10/sprockets%2Ffc21b5aee1c95934ed1b41ac05eeee87 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E5B/7A0/sprockets%2F5c84af44bfcbcc581dd75a9b19beeac1 +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/integration/navigation_test.rb +6 -0
- data/test/test_helper.rb +8 -0
- metadata +203 -0
data/LICENSE
ADDED
|
File without changes
|
data/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ActiveGrid
|
|
2
|
+
|
|
3
|
+
ActiveGrid is a gem to allow Rails apps to easily add data grids
|
|
4
|
+
that can be sorted, paginated, filtered and styled.
|
|
5
|
+
|
|
6
|
+
## Description
|
|
7
|
+
|
|
8
|
+
Using the ActiveGrid gem consists of a few steps:
|
|
9
|
+
|
|
10
|
+
1) Add the following to your Gemfile and run "bundle":
|
|
11
|
+
|
|
12
|
+
gem "activegrid"
|
|
13
|
+
|
|
14
|
+
2) Setup your controller to have a collection of ActiveRecord objects. Something like this would be fine:
|
|
15
|
+
|
|
16
|
+
@models = Model.scoped.activegrid_filter_sort_paginate
|
|
17
|
+
|
|
18
|
+
3) In your view, add the activegrid helper
|
|
19
|
+
|
|
20
|
+
<%= activegrid @products, paginate: 10 do |grid, model| %>
|
|
21
|
+
<%= grid.column :name, filter: %W[Blah Gizmo Widget], sortable: true do %>
|
|
22
|
+
<%= link_to model.name, product_path(model) %>
|
|
23
|
+
<% end %>
|
|
24
|
+
|
|
25
|
+
<%= grid.column :description, filter: "string", sortable: true do %>
|
|
26
|
+
<%= model.description %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
data/Rakefile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'rdoc/task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require 'rdoc/rdoc'
|
|
11
|
+
require 'rake/rdoctask'
|
|
12
|
+
RDoc::Task = Rake::RDocTask
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
+
rdoc.title = 'ActiveGrid'
|
|
18
|
+
rdoc.options << '--line-numbers'
|
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
24
|
+
load 'rails/tasks/engine.rake'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Bundler::GemHelper.install_tasks
|
|
28
|
+
|
|
29
|
+
require 'rake/testtask'
|
|
30
|
+
|
|
31
|
+
Rake::TestTask.new(:test) do |t|
|
|
32
|
+
t.libs << 'lib'
|
|
33
|
+
t.libs << 'test'
|
|
34
|
+
t.pattern = 'test/**/*_test.rb'
|
|
35
|
+
t.verbose = false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
task :default => :test
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//= require jquery
|
|
2
|
+
//= require jquery_ujs
|
|
3
|
+
|
|
4
|
+
$(function() {
|
|
5
|
+
$("table[data-activegrid=true]").each(function(index, table) {
|
|
6
|
+
var self = $(table);
|
|
7
|
+
var name = self.attr("data-activegrid-name");
|
|
8
|
+
var page = 1;
|
|
9
|
+
var pages = self.attr("data-activegrid-pages");
|
|
10
|
+
var paginate = self.attr("data-activegrid-paginate");
|
|
11
|
+
var order = null;
|
|
12
|
+
var filterField = null, filterValue = null;
|
|
13
|
+
|
|
14
|
+
var baseURL = function() {
|
|
15
|
+
var url = "?"
|
|
16
|
+
url += encodeURI("activegrid[name]") + "=" + encodeURI(name);
|
|
17
|
+
url += "&" + encodeURI("activegrid[limit]") + "=" + encodeURI(paginate);
|
|
18
|
+
url += "&" + encodeURI("activegrid[offset]") + "=" + encodeURI((page - 1) * paginate);
|
|
19
|
+
return url;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
var updateTable = function() {
|
|
23
|
+
var url = "?"
|
|
24
|
+
url += encodeURI("activegrid[name]") + "=" + encodeURI(name);
|
|
25
|
+
url += "&" + encodeURI("activegrid[limit]") + "=" + encodeURI(paginate);
|
|
26
|
+
url += "&" + encodeURI("activegrid[offset]") + "=" + encodeURI((page - 1) * paginate);
|
|
27
|
+
|
|
28
|
+
if (order) {
|
|
29
|
+
url += "&" + encodeURI("activegrid[order]") + "=" + encodeURI(order);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (filterField) {
|
|
33
|
+
url += "&" + encodeURI("activegrid[filter][field]") + "=" + encodeURI(filterField);
|
|
34
|
+
url += "&" + encodeURI("activegrid[filter][value]") + "=" + encodeURI(filterValue);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
$.ajax({ url: url, dataType: "script" });
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Sorting
|
|
41
|
+
var resetSortDirection = function() {
|
|
42
|
+
var set = $("th[data-activegrid-sort=true]", table);
|
|
43
|
+
set.data("activegrid-sort-direction", null).removeClass("activegrid-sort-asc").removeClass("activegrid-sort-desc");
|
|
44
|
+
};
|
|
45
|
+
$("th[data-activegrid-sort=true]", table).click(function() {
|
|
46
|
+
var self = $(this);
|
|
47
|
+
var field = self.attr("data-activegrid-sort-field");
|
|
48
|
+
var direction = self.data("activegrid-sort-direction");
|
|
49
|
+
var newDirection = direction == "asc" ? "desc" : "asc";
|
|
50
|
+
resetSortDirection();
|
|
51
|
+
|
|
52
|
+
self.data("activegrid-sort-direction", newDirection).addClass("activegrid-sort-" + newDirection);
|
|
53
|
+
order = field + (newDirection == "asc" ? "" : " DESC");
|
|
54
|
+
updateTable();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Filtering
|
|
58
|
+
$(":input[data-activegrid-filter=true]", table).change(function() {
|
|
59
|
+
var self = $(this);
|
|
60
|
+
var field = self.attr("data-activegrid-filter-field");
|
|
61
|
+
|
|
62
|
+
filterField = field;
|
|
63
|
+
filterValue = self.val();
|
|
64
|
+
updateTable();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// TODO: pagination (back and forward buttons, list of pages)
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
function activegrid_update(element, body) {
|
|
72
|
+
$("#" + element + " tbody").html(body);
|
|
73
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module ActiveGrid
|
|
2
|
+
class Controller < ::ApplicationController
|
|
3
|
+
helper do
|
|
4
|
+
attr_accessor :_activegrid
|
|
5
|
+
|
|
6
|
+
def activegrid(name_or_options = {}, &block)
|
|
7
|
+
if name_or_options.is_a?(Hash)
|
|
8
|
+
_activegrid.options.merge!(name_or_options)
|
|
9
|
+
_activegrid.block = block
|
|
10
|
+
else
|
|
11
|
+
if grid = activegrids[name_or_options]
|
|
12
|
+
grid.to_html
|
|
13
|
+
else
|
|
14
|
+
raise "No such activegrid #{name}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
def activegrid(name, scope, partial = "#{name}/grid")
|
|
22
|
+
raise "scope must be an ActiveRecord::Relation" unless scope.is_a?(ActiveRecord::Relation)
|
|
23
|
+
|
|
24
|
+
if params = self.params[:activegrid] and params[:name] == name.to_s
|
|
25
|
+
scope = scope.order(params[:order]) if params[:order]
|
|
26
|
+
scope = scope.limit(params[:limit]) if params[:limit]
|
|
27
|
+
scope = scope.offset(params[:offset]) if params[:offset]
|
|
28
|
+
|
|
29
|
+
if filter = params[:filter]
|
|
30
|
+
table = scope.klass.arel_table
|
|
31
|
+
scope = scope.where(table[filter[:field]].matches("%#{filter[:value]}%"))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@element = "#{name}_grid"
|
|
35
|
+
@grid = ActiveGrid::Grid.new(view_context, name, scope, partial)
|
|
36
|
+
|
|
37
|
+
respond_to do |format|
|
|
38
|
+
format.js { render "active_grid/update" }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
true
|
|
42
|
+
else
|
|
43
|
+
activegrids[name] = ActiveGrid::Grid.new(view_context, name, scope, partial)
|
|
44
|
+
false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def activegrids
|
|
49
|
+
@activegrids ||= {}
|
|
50
|
+
end
|
|
51
|
+
helper_method :activegrids
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module ActiveGrid
|
|
2
|
+
class Column
|
|
3
|
+
attr_reader :block, :name, :options, :view
|
|
4
|
+
|
|
5
|
+
def initialize(view, name, options = {}, &block)
|
|
6
|
+
@view, @name, @options, @block = view, name, options, block
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def header
|
|
10
|
+
# TODO: localization?
|
|
11
|
+
options[:header] || name.to_s.titleize
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def filter
|
|
15
|
+
tag_options = {}
|
|
16
|
+
tag_options["data-activegrid-filter-field"] = name
|
|
17
|
+
tag_options["data-activegrid-filter"] = true
|
|
18
|
+
|
|
19
|
+
case filter = options[:filter]
|
|
20
|
+
when "string"
|
|
21
|
+
view.text_field_tag("activegird_filter_#{name}", nil, tag_options)
|
|
22
|
+
when Array
|
|
23
|
+
view.select_tag("activegrid_filter_#{name}", view.options_for_select(filter), tag_options)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def tag_options
|
|
28
|
+
tag_options = {}
|
|
29
|
+
|
|
30
|
+
if options[:sortable]
|
|
31
|
+
tag_options["class"] = "activegrid-sort"
|
|
32
|
+
tag_options["data-activegrid-sort-field"] = name
|
|
33
|
+
tag_options["data-activegrid-sort"] = options[:sortable]
|
|
34
|
+
end
|
|
35
|
+
tag_options
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def value
|
|
39
|
+
view.capture(&block)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module ActiveGrid
|
|
2
|
+
class Grid
|
|
3
|
+
attr_reader :columns, :name, :options, :partial, :scope, :view
|
|
4
|
+
attr_accessor :block
|
|
5
|
+
|
|
6
|
+
def initialize(view, name, scope, partial, options = {})
|
|
7
|
+
@columns = []
|
|
8
|
+
@view, @name, @scope, @partial, @options = view, name, scope, partial, options
|
|
9
|
+
|
|
10
|
+
self.view._activegrid = self
|
|
11
|
+
self.view.render(partial)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def header
|
|
15
|
+
mode :header do
|
|
16
|
+
view.content_tag(:tr, view.capture(self, nil, &block))
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def filters
|
|
21
|
+
mode :filter do
|
|
22
|
+
view.content_tag(:tr, view.capture(self, nil, &block))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def body
|
|
27
|
+
mode :body do
|
|
28
|
+
models.map do |model|
|
|
29
|
+
view.content_tag(:tr, view.capture(self, model, &block))
|
|
30
|
+
end.reduce(:<<)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def column(name, options = {}, &block)
|
|
35
|
+
column = Column.new(view, name, options, &block)
|
|
36
|
+
|
|
37
|
+
case mode
|
|
38
|
+
when :header
|
|
39
|
+
columns << column
|
|
40
|
+
view.content_tag(:th, column.header, column.tag_options)
|
|
41
|
+
when :filter
|
|
42
|
+
view.content_tag(:th, column.filter)
|
|
43
|
+
when :body
|
|
44
|
+
view.content_tag(:td, column.value)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def mode(value = nil, &block)
|
|
49
|
+
if value
|
|
50
|
+
begin
|
|
51
|
+
old_mode, @mode = @mode, value
|
|
52
|
+
yield
|
|
53
|
+
ensure
|
|
54
|
+
@mode = old_mode
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
@mode
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def models
|
|
62
|
+
if paginate = options[:paginate]
|
|
63
|
+
scope.limit(paginate)
|
|
64
|
+
else
|
|
65
|
+
scope
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def tag_options
|
|
70
|
+
tag_options = {}
|
|
71
|
+
tag_options["id"] = "#{name}_grid"
|
|
72
|
+
tag_options["class"] = "activegrid"
|
|
73
|
+
tag_options["data-activegrid"] = true
|
|
74
|
+
tag_options["data-activegrid-name"] = name
|
|
75
|
+
|
|
76
|
+
if options[:paginate]
|
|
77
|
+
tag_options["data-activegrid-pages"] = (scope.count / options[:paginate].to_f).ceil
|
|
78
|
+
tag_options["data-activegrid-paginate"] = options[:paginate]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
tag_options
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def to_html
|
|
85
|
+
view.content_tag(:table, tag_options) do
|
|
86
|
+
view.content_tag(:thead, header << filters) << view.content_tag(:tbody, body)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
activegrid_update("<%= escape_javascript(@element) %>", "<%= escape_javascript @grid.body %>");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require "rails"
|
|
2
|
+
require "jquery/rails"
|
|
3
|
+
|
|
4
|
+
module ActiveGrid
|
|
5
|
+
class Engine < Rails::Engine
|
|
6
|
+
initializer "activegrid.config.assets.precompile", :before => "sprockets.environment" do |app|
|
|
7
|
+
app.config.assets.precompile.concat %W[activegrid.css activegrid.js]
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
data/lib/activegrid.rb
ADDED
data/test/dummy/Rakefile
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
body { background-color: #fff; color: #333; }
|
|
2
|
+
|
|
3
|
+
body, p, ol, ul, td {
|
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
|
5
|
+
font-size: 13px;
|
|
6
|
+
line-height: 18px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
pre {
|
|
10
|
+
background-color: #eee;
|
|
11
|
+
padding: 10px;
|
|
12
|
+
font-size: 11px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
a { color: #000; }
|
|
16
|
+
a:visited { color: #666; }
|
|
17
|
+
a:hover { color: #fff; background-color:#000; }
|
|
18
|
+
|
|
19
|
+
div.field, div.actions {
|
|
20
|
+
margin-bottom: 10px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#notice {
|
|
24
|
+
color: green;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.field_with_errors {
|
|
28
|
+
padding: 2px;
|
|
29
|
+
background-color: red;
|
|
30
|
+
display: table;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#error_explanation {
|
|
34
|
+
width: 450px;
|
|
35
|
+
border: 2px solid red;
|
|
36
|
+
padding: 7px;
|
|
37
|
+
padding-bottom: 0;
|
|
38
|
+
margin-bottom: 20px;
|
|
39
|
+
background-color: #f0f0f0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#error_explanation h2 {
|
|
43
|
+
text-align: left;
|
|
44
|
+
font-weight: bold;
|
|
45
|
+
padding: 5px 5px 5px 15px;
|
|
46
|
+
font-size: 12px;
|
|
47
|
+
margin: -7px;
|
|
48
|
+
margin-bottom: 0px;
|
|
49
|
+
background-color: #c00;
|
|
50
|
+
color: #fff;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#error_explanation ul li {
|
|
54
|
+
font-size: 12px;
|
|
55
|
+
list-style: square;
|
|
56
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
class ProductsController < ActiveGrid::Controller
|
|
2
|
+
# GET /products
|
|
3
|
+
# GET /products.json
|
|
4
|
+
def index
|
|
5
|
+
@products = Product.scoped
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
activegrid :products, @products
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# GET /products/1
|
|
12
|
+
# GET /products/1.json
|
|
13
|
+
def show
|
|
14
|
+
@product = Product.find(params[:id])
|
|
15
|
+
|
|
16
|
+
respond_to do |format|
|
|
17
|
+
format.html # show.html.erb
|
|
18
|
+
format.json { render json: @product }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# GET /products/new
|
|
23
|
+
# GET /products/new.json
|
|
24
|
+
def new
|
|
25
|
+
@product = Product.new
|
|
26
|
+
|
|
27
|
+
respond_to do |format|
|
|
28
|
+
format.html # new.html.erb
|
|
29
|
+
format.json { render json: @product }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# GET /products/1/edit
|
|
34
|
+
def edit
|
|
35
|
+
@product = Product.find(params[:id])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# POST /products
|
|
39
|
+
# POST /products.json
|
|
40
|
+
def create
|
|
41
|
+
@product = Product.new(params[:product])
|
|
42
|
+
|
|
43
|
+
respond_to do |format|
|
|
44
|
+
if @product.save
|
|
45
|
+
format.html { redirect_to @product, notice: 'Product was successfully created.' }
|
|
46
|
+
format.json { render json: @product, status: :created, location: @product }
|
|
47
|
+
else
|
|
48
|
+
format.html { render action: "new" }
|
|
49
|
+
format.json { render json: @product.errors, status: :unprocessable_entity }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# PUT /products/1
|
|
55
|
+
# PUT /products/1.json
|
|
56
|
+
def update
|
|
57
|
+
@product = Product.find(params[:id])
|
|
58
|
+
|
|
59
|
+
respond_to do |format|
|
|
60
|
+
if @product.update_attributes(params[:product])
|
|
61
|
+
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
|
|
62
|
+
format.json { head :ok }
|
|
63
|
+
else
|
|
64
|
+
format.html { render action: "edit" }
|
|
65
|
+
format.json { render json: @product.errors, status: :unprocessable_entity }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# DELETE /products/1
|
|
71
|
+
# DELETE /products/1.json
|
|
72
|
+
def destroy
|
|
73
|
+
@product = Product.find(params[:id])
|
|
74
|
+
@product.destroy
|
|
75
|
+
|
|
76
|
+
respond_to do |format|
|
|
77
|
+
format.html { redirect_to products_url }
|
|
78
|
+
format.json { head :ok }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<%= form_for(@product) do |f| %>
|
|
2
|
+
<% if @product.errors.any? %>
|
|
3
|
+
<div id="error_explanation">
|
|
4
|
+
<h2><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h2>
|
|
5
|
+
|
|
6
|
+
<ul>
|
|
7
|
+
<% @product.errors.full_messages.each do |msg| %>
|
|
8
|
+
<li><%= msg %></li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
|
|
14
|
+
<div class="field">
|
|
15
|
+
<%= f.label :name %><br />
|
|
16
|
+
<%= f.text_field :name %>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="field">
|
|
19
|
+
<%= f.label :description %><br />
|
|
20
|
+
<%= f.text_area :description %>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="field">
|
|
23
|
+
<%= f.label :price %><br />
|
|
24
|
+
<%= f.text_field :price %>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="field">
|
|
27
|
+
<%= f.label :quantity %><br />
|
|
28
|
+
<%= f.number_field :quantity %>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="actions">
|
|
31
|
+
<%= f.submit %>
|
|
32
|
+
</div>
|
|
33
|
+
<% end %>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<%= activegrid paginate: 10 do |grid, model| %>
|
|
2
|
+
<%= grid.column :name, filter: %W[blah Gizmo Widget], sortable: true do %>
|
|
3
|
+
<%= link_to model.name, product_path(model) %>
|
|
4
|
+
<% end %>
|
|
5
|
+
|
|
6
|
+
<%= grid.column :description, filter: "string", sortable: true do %>
|
|
7
|
+
<%= model.description %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% end %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<b>Name:</b>
|
|
5
|
+
<%= @product.name %>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p>
|
|
9
|
+
<b>Description:</b>
|
|
10
|
+
<%= @product.description %>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p>
|
|
14
|
+
<b>Price:</b>
|
|
15
|
+
<%= @product.price %>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p>
|
|
19
|
+
<b>Quantity:</b>
|
|
20
|
+
<%= @product.quantity %>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
<%= link_to 'Edit', edit_product_path(@product) %> |
|
|
25
|
+
<%= link_to 'Back', products_path %>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'rails/all'
|
|
4
|
+
|
|
5
|
+
Bundler.require
|
|
6
|
+
require "activegrid"
|
|
7
|
+
|
|
8
|
+
module Dummy
|
|
9
|
+
class Application < Rails::Application
|
|
10
|
+
config.encoding = "utf-8"
|
|
11
|
+
|
|
12
|
+
config.filter_parameters += [:password]
|
|
13
|
+
|
|
14
|
+
config.assets.enabled = true
|
|
15
|
+
config.assets.version = '1.0'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|