datatables 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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +134 -0
- data/Rakefile +2 -0
- data/app/controllers/datatables_controller.rb +19 -0
- data/app/views/datatable/_datatable.html.erb +163 -0
- data/config/routes.rb +5 -0
- data/datatables.gemspec +25 -0
- data/lib/datatables.rb +5 -0
- data/lib/datatables/activerecord_methods.rb +130 -0
- data/lib/datatables/datatable_helpers.rb +31 -0
- data/lib/datatables/engine.rb +9 -0
- data/lib/generators/datatables/install/install_generator.rb +21 -0
- data/vendor/assets/javascripts/jquery.dataTables.min.js +142 -0
- data/vendor/assets/stylesheets/datatable_page.css +93 -0
- data/vendor/assets/stylesheets/datatable_table.css +538 -0
- metadata +94 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2004-2011 Caseproof, LLC
|
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.
|
21
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
= Datatables
|
2
|
+
|
3
|
+
Datatables is a Rails 3 plugin that enables the easy creation of dynamic datatable views on top of any ActiveRecord model. Datatables provides a simple helper that can be utilized in the view to automatically display a dynamic view on top of a model. Datatables handles the entire front end and backend support to do this.
|
4
|
+
|
5
|
+
= Installation
|
6
|
+
|
7
|
+
To install datatables to your rails project, follow these simple steps:
|
8
|
+
|
9
|
+
==== 1. Make sure your project is using the 'jquery-rails' plugin.
|
10
|
+
==== 2. Add the following line to your Gemfile:
|
11
|
+
gem 'datatables', :git => 'git://github.com/Caseproof/datatables.git'
|
12
|
+
==== 3. Run <b>bundle install</b>
|
13
|
+
==== 4. Run <b>rails generate datatables:install</b>
|
14
|
+
==== 5. Add the following lines to your layout file after <b>javascript_include_tag :defaults</b>
|
15
|
+
<%= stylesheet_link_tag "datatable_page" %>
|
16
|
+
<%= stylesheet_link_tag "datatable_table" %>
|
17
|
+
<%= javascript_include_tag 'jquery.dataTables.min' %>
|
18
|
+
==== 6. Add the Datatable helper mixin to your ApplicationHelper (<b>app/helpers/application_helper.rb</b>) like so:
|
19
|
+
module ApplicationHelper
|
20
|
+
include Datatables::Helpers
|
21
|
+
end
|
22
|
+
|
23
|
+
= Example
|
24
|
+
|
25
|
+
With datatables it's easy to add rich datatables to your views that correspond with your active record models.
|
26
|
+
|
27
|
+
There is a lovely helper that you can use to render your datatable that takes in a whole host of options. Unfortunately, there's still quite a bit of work to do with these options to handle every scenario but here's what it support so far:
|
28
|
+
|
29
|
+
== Database table:
|
30
|
+
|
31
|
+
The following examples will use the following database table:
|
32
|
+
|
33
|
+
mysql> desc companies;
|
34
|
+
+-------------+--------------+------+-----+---------+----------------+
|
35
|
+
| Field | Type | Null | Key | Default | Extra |
|
36
|
+
+-------------+--------------+------+-----+---------+----------------+
|
37
|
+
| id | int(11) | NO | PRI | NULL | auto_increment |
|
38
|
+
| name | varchar(255) | YES | MUL | NULL | |
|
39
|
+
| slug | varchar(255) | YES | MUL | NULL | |
|
40
|
+
| domain | varchar(255) | YES | MUL | NULL | |
|
41
|
+
| category_id | int(11) | NO | MUL | NULL | |
|
42
|
+
| created_at | datetime | YES | | NULL | |
|
43
|
+
| updated_at | datetime | YES | | NULL | |
|
44
|
+
+-------------+--------------+------+-----+---------+----------------+
|
45
|
+
|
46
|
+
|
47
|
+
== Standard datatable
|
48
|
+
|
49
|
+
The first argument to the datatable helper is the name of the model or an array of model & scope. The second argument is a hash of column names & options.
|
50
|
+
|
51
|
+
<%= datatable('company', { :name => { :type => 'string',
|
52
|
+
:label => 'Name',
|
53
|
+
:width => '20%' },
|
54
|
+
:slug => { :type => 'string',
|
55
|
+
:label => 'Slug',
|
56
|
+
:width => '15%' },
|
57
|
+
:domain => { :type => 'string',
|
58
|
+
:label => 'Domain',
|
59
|
+
:width => '15%' }
|
60
|
+
}) %>
|
61
|
+
|
62
|
+
== Datatable with a link to edit
|
63
|
+
|
64
|
+
Note that the edit link path utilizes the :id field in the database table to automatically insert the correct id on a row by row basis:
|
65
|
+
|
66
|
+
<%= datatable('company', { :id => { :type => 'hidden' },
|
67
|
+
:name => { :type => 'link',
|
68
|
+
:label => 'Name',
|
69
|
+
:link => edit_admin_company_path(:id),
|
70
|
+
:replace => 'id',
|
71
|
+
:width => '50%' },
|
72
|
+
:slug => { :type => 'string',
|
73
|
+
:label => 'Slug',
|
74
|
+
:width => '25%' },
|
75
|
+
:domain => { :type => 'string',
|
76
|
+
:label => 'Domain',
|
77
|
+
:width => '25%' }
|
78
|
+
}) %>
|
79
|
+
|
80
|
+
== Scoped datatable (now we're using the 'dot_org_domains' that can be found in the Company model):
|
81
|
+
|
82
|
+
<%= datatable(['company','dot_org_domains'], { :id => { :type => 'hidden' },
|
83
|
+
:name => { :type => 'link',
|
84
|
+
:label => 'Name',
|
85
|
+
:link => edit_admin_company_path(:id),
|
86
|
+
:replace => 'id',
|
87
|
+
:width => '50%' },
|
88
|
+
:slug => { :type => 'string',
|
89
|
+
:label => 'Slug',
|
90
|
+
:width => '25%' },
|
91
|
+
:domain => { :type => 'string',
|
92
|
+
:label => 'Domain',
|
93
|
+
:width => '25%' }
|
94
|
+
}) %>
|
95
|
+
|
96
|
+
== Association columns
|
97
|
+
<%= datatable(['company','dot_org_domains'], { :id => { :type => 'hidden' },
|
98
|
+
:name => { :type => 'link',
|
99
|
+
:label => 'Name',
|
100
|
+
:link => edit_admin_company_path(:id),
|
101
|
+
:replace => 'id',
|
102
|
+
:width => '40%' },
|
103
|
+
:slug => { :type => 'string',
|
104
|
+
:label => 'Slug',
|
105
|
+
:width => '20%' },
|
106
|
+
:domain => { :type => 'string',
|
107
|
+
:label => 'Domain',
|
108
|
+
:width => '20%' },
|
109
|
+
:category_name => { :type => 'string',
|
110
|
+
:label => 'Category',
|
111
|
+
:column => 'categories.name',
|
112
|
+
:width => '20%',
|
113
|
+
:class => 'center' }
|
114
|
+
|
115
|
+
}) %>
|
116
|
+
|
117
|
+
= Why use this plugin?
|
118
|
+
|
119
|
+
It is the easiest way to integrate dynamic datatables using the jQuery datatables plugin into your rails app.
|
120
|
+
|
121
|
+
= Version history
|
122
|
+
|
123
|
+
- Version 1.0.0
|
124
|
+
- First Release
|
125
|
+
|
126
|
+
= Contribute
|
127
|
+
|
128
|
+
If you've got some ideas for datatables let me know and, even better, if you've made some enhancements to the code send me a pull request!
|
129
|
+
|
130
|
+
= Support
|
131
|
+
|
132
|
+
Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on 'http://github.com/Caseproof/metafy/issues'. If its urgent, please contact me from my website at 'http://blairwilliams.com/contact'
|
133
|
+
|
134
|
+
Copyright (c) 2004-2011 Caseproof, LLC, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class DatatablesController < ApplicationController
|
2
|
+
#before_filter :authenticate_user!
|
3
|
+
#load_and_authorize_resource
|
4
|
+
respond_to :json
|
5
|
+
|
6
|
+
def dataset
|
7
|
+
begin
|
8
|
+
model_class = params[:model].classify.constantize
|
9
|
+
rescue NameError
|
10
|
+
render :text => 'Model Not Found', :layout => false
|
11
|
+
return
|
12
|
+
end
|
13
|
+
|
14
|
+
output = model_class.datatable(params)
|
15
|
+
|
16
|
+
# Render Encoded JSON
|
17
|
+
render :text => output.to_json, :layout => false
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
<% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%>
|
2
|
+
<div id="rd_buttons">
|
3
|
+
<a id="rd_clear_selections" class="rd_disabled">Clear Selections</a>
|
4
|
+
<% unless @pptions[:selectable_actions].nil? -%>
|
5
|
+
<% @pptions[:selectable_actions].each do |sa| %>
|
6
|
+
<%= sa %>
|
7
|
+
<% end -%>
|
8
|
+
<% end -%>
|
9
|
+
</div>
|
10
|
+
<% end -%>
|
11
|
+
<table cellpadding="0" cellspacing="0" border="0" class="display" id="rdatatable">
|
12
|
+
<thead>
|
13
|
+
<tr>
|
14
|
+
<% @columns.each_pair do |key,col| -%>
|
15
|
+
<th width="<%= col[:width] %>"><%= col[:label] || key.to_s.humanize %></th>
|
16
|
+
<% end -%>
|
17
|
+
</tr>
|
18
|
+
</thead>
|
19
|
+
<tbody>
|
20
|
+
<tr>
|
21
|
+
<td colspan="<%= @columns.length.to_s %>" class="dataTables_empty">Loading...</td>
|
22
|
+
</tr>
|
23
|
+
</tbody>
|
24
|
+
<tfoot>
|
25
|
+
<tr>
|
26
|
+
<% @columns.each_pair do |key,col| -%>
|
27
|
+
<th><input type="text" name="search_<%= key.to_s %>" value="Search <%= col[:label] || key.to_s.humanize %>" class="search_init" rel="<%= @columns.keys.index(key) %>" /></th>
|
28
|
+
<% end -%>
|
29
|
+
</tr>
|
30
|
+
</tfoot>
|
31
|
+
</table>
|
32
|
+
|
33
|
+
<%= javascript_tag :defer => 'defer' do -%>
|
34
|
+
var asInitVals = new Array();
|
35
|
+
|
36
|
+
<% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%>
|
37
|
+
var gaiSelected = [];
|
38
|
+
|
39
|
+
function rd_toggle_buttons() {
|
40
|
+
if( gaiSelected.length > 0 )
|
41
|
+
{
|
42
|
+
jQuery("#rd_buttons a").removeClass('rd_disabled');
|
43
|
+
jQuery("#rd_buttons a").addClass('rd_enabled');
|
44
|
+
}
|
45
|
+
else
|
46
|
+
{
|
47
|
+
jQuery("#rd_buttons a").removeClass('rd_enabled');
|
48
|
+
jQuery("#rd_buttons a").addClass('rd_disabled');
|
49
|
+
}
|
50
|
+
}
|
51
|
+
<% end -%>
|
52
|
+
|
53
|
+
function rd_bulk_edit_users() {
|
54
|
+
if( jQuery('#rd_bulk_edit_users').hasClass('rd_enabled') )
|
55
|
+
{
|
56
|
+
jQuery.prettyPhoto.open('/admin/projects/<%= @id %>/edit_users/' + gaiSelected + '?iframe=true&width=90%&height=90%');
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
jQuery(document).ready(function() {
|
61
|
+
var oTable = jQuery('#rdatatable').dataTable( {
|
62
|
+
|
63
|
+
/* Custom Options */
|
64
|
+
<% @jsoptions.each_pair do |k,v| -%>
|
65
|
+
"<%= k %>": <%= v %>,
|
66
|
+
<% end -%>
|
67
|
+
|
68
|
+
/* Visible / Hidden columns & Formatting */
|
69
|
+
"aoColumnDefs": [
|
70
|
+
<% @columns.each_pair do |name,attrs| -%>
|
71
|
+
<% if attrs[:type] == 'link' -%>
|
72
|
+
/* <%= name.to_s %> */ {
|
73
|
+
"fnRender": function ( oObj ) {
|
74
|
+
return '<a href="' + "<%= attrs[:link] %>".replace( /<%= attrs[:replace] %>/i, oObj.aData[<%= @columns.keys.index( attrs[:replace].to_sym ) %>] ) + '">' + oObj.aData[<%= @columns.keys.index( name.to_sym ) %>] + '</a>';
|
75
|
+
},
|
76
|
+
"aTargets": [ <%= @columns.keys.index( name ) %> ]
|
77
|
+
}<%= "," unless @columns.keys.last == name %>
|
78
|
+
<% elsif attrs[:type] == 'hidden' -%>
|
79
|
+
/* <%= name.to_s %> */ { "bVisible": false, "aTargets": [ <%= @columns.keys.index( name ) %> ] }<%= "," unless @columns.keys.last == name %>
|
80
|
+
<% else -%>
|
81
|
+
/* <%= name.to_s %> */ { "aTargets": [ <%= @columns.keys.index( name ) %> ] }<%= "," unless @columns.keys.last == name %>
|
82
|
+
<% end -%>
|
83
|
+
<% end -%>
|
84
|
+
],
|
85
|
+
|
86
|
+
<% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%>
|
87
|
+
"fnRowCallback": function( nRow, aData, iDisplayIndex ) {
|
88
|
+
if ( jQuery.inArray(aData[0], gaiSelected) != -1 ) {
|
89
|
+
jQuery(nRow).addClass('row_selected');
|
90
|
+
}
|
91
|
+
return nRow;
|
92
|
+
},
|
93
|
+
<% end -%>
|
94
|
+
|
95
|
+
/* Boilerplate Options */
|
96
|
+
"sPaginationType": "full_numbers",
|
97
|
+
"aLengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
|
98
|
+
"bProcessing": true,
|
99
|
+
"bServerSide": true,
|
100
|
+
"sAjaxSource": '/rdtable/<%= @modelname %><%= "/#{@col_str}" %><%= @scope.nil? ? '' : "/#{@scope}" %><%= @id.nil? ? '' : "/#{@id}" %>'
|
101
|
+
} );
|
102
|
+
|
103
|
+
<% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%>
|
104
|
+
jQuery('#rd_clear_selections').click( function () {
|
105
|
+
gaiSelected = [];
|
106
|
+
jQuery("#rdatatable tbody tr").removeClass('row_selected');
|
107
|
+
rd_toggle_buttons();
|
108
|
+
});
|
109
|
+
|
110
|
+
/* Click event handler */
|
111
|
+
jQuery('#rdatatable tbody tr').live('click', function () {
|
112
|
+
var aData = oTable.fnGetData( this );
|
113
|
+
var iId = aData[0];
|
114
|
+
|
115
|
+
if ( jQuery.inArray(iId, gaiSelected) == -1 )
|
116
|
+
{
|
117
|
+
gaiSelected[gaiSelected.length++] = iId;
|
118
|
+
}
|
119
|
+
else
|
120
|
+
{
|
121
|
+
gaiSelected = jQuery.grep(gaiSelected, function(value) {
|
122
|
+
return value != iId;
|
123
|
+
} );
|
124
|
+
}
|
125
|
+
|
126
|
+
jQuery(this).toggleClass('row_selected');
|
127
|
+
rd_toggle_buttons();
|
128
|
+
} );
|
129
|
+
<% end -%>
|
130
|
+
|
131
|
+
jQuery("tfoot input").keyup( function () {
|
132
|
+
/* Filter on the column (the index) of this element */
|
133
|
+
oTable.fnFilter( this.value, jQuery(this).attr('rel') );
|
134
|
+
gaiSelected = []; // clear the selection on filter
|
135
|
+
rd_toggle_buttons();
|
136
|
+
} );
|
137
|
+
|
138
|
+
/*
|
139
|
+
* Support functions to provide a little bit of 'user friendlyness' to the textboxes in
|
140
|
+
* the footer
|
141
|
+
*/
|
142
|
+
jQuery("tfoot input").each( function (i) {
|
143
|
+
asInitVals[i] = this.value;
|
144
|
+
} );
|
145
|
+
|
146
|
+
jQuery("tfoot input").focus( function () {
|
147
|
+
if ( this.className == "search_init" )
|
148
|
+
{
|
149
|
+
this.className = "";
|
150
|
+
this.value = "";
|
151
|
+
}
|
152
|
+
} );
|
153
|
+
|
154
|
+
jQuery("tfoot input").blur( function (i) {
|
155
|
+
if ( this.value == "" )
|
156
|
+
{
|
157
|
+
this.className = "search_init";
|
158
|
+
this.value = asInitVals[jQuery("tfoot input").index(this)];
|
159
|
+
}
|
160
|
+
} );
|
161
|
+
|
162
|
+
} );
|
163
|
+
<% end -%>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
match 'rdtable/:model/:columns' => 'datatables#dataset', :as => 'datatable'
|
3
|
+
match 'rdtable/:model/:columns/:scope' => 'datatables#dataset', :as => 'datatable'
|
4
|
+
match 'rdtable/:model/:columns/:scope/:id' => 'datatables#dataset', :as => 'datatable'
|
5
|
+
end
|
data/datatables.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "datatables"
|
6
|
+
s.version = "1.0.0"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Blair Williams","Brandon Toone"]
|
9
|
+
s.email = ["blair@caseproof.com","btoone@gmail.com"]
|
10
|
+
s.homepage = "http://blairwilliams.com/ruby-on-rails/datatables"
|
11
|
+
s.summary = %q{Datatables is a Rails 3 plugin that enables the easy creation of dynamic datatable views on top of any ActiveRecord model}
|
12
|
+
s.description = %q{Datatables is a Rails 3 plugin that enables the easy creation of dynamic datatable views on top of any ActiveRecord model. Datatables provides a simple helper that can be utilized in the view to automatically display a dynamic view on top of a model. Datatables handles the entire front end and backend support to do this. }
|
13
|
+
|
14
|
+
s.add_dependency('rails','>= 3.0.3')
|
15
|
+
s.add_dependency('jquery-rails')
|
16
|
+
|
17
|
+
s.license = 'MIT'
|
18
|
+
|
19
|
+
s.rubyforge_project = "datatables"
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
#s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
#s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
#s.require_paths = ["app","config","lib"]
|
25
|
+
end
|
data/lib/datatables.rb
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
module Datatables
|
2
|
+
require 'datatables/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
3
|
+
require 'datatables/activerecord_methods' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
4
|
+
require 'datatables/datatable_helpers' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
5
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# Adds the datatable method in ActiveRecord::Base, which sets up the backend for the datatable javascript
|
2
|
+
#
|
3
|
+
class << ActiveRecord::Base
|
4
|
+
def datatable( params )
|
5
|
+
curr_model = self
|
6
|
+
table_name = curr_model.table_name
|
7
|
+
|
8
|
+
if curr_model.metafied?
|
9
|
+
metas = curr_model.metafied_attrs || []
|
10
|
+
else
|
11
|
+
metas = []
|
12
|
+
end
|
13
|
+
|
14
|
+
sql_opts = { :select => [], :limit => "", :order => "", :joins => [], :conditions => "" }
|
15
|
+
columns = []
|
16
|
+
full_columns = []
|
17
|
+
|
18
|
+
dscope = params[:scope] || nil
|
19
|
+
dcols = params[:columns].split(',')
|
20
|
+
did = params[:id]
|
21
|
+
|
22
|
+
dcols.each do |col|
|
23
|
+
col = col.split(':')
|
24
|
+
if col.length > 1 # association (already assumed we're joined within a scope)
|
25
|
+
col_fmt = "`#{col[1].to_s}`.`#{col[2].to_s}`"
|
26
|
+
elsif metas.include? col.first.to_sym
|
27
|
+
col_fmt = "`m_#{col.first.to_s}`.`meta_value`"
|
28
|
+
else
|
29
|
+
col_fmt = "`#{table_name.to_s}`.`#{col.first.to_s}`"
|
30
|
+
end
|
31
|
+
|
32
|
+
columns.push col.first.to_s
|
33
|
+
full_columns.push col_fmt
|
34
|
+
sql_opts[:select].push "#{col_fmt} as #{col.first.to_s}"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Paging
|
38
|
+
if params['iDisplayStart'] and params['iDisplayLength'] != '-1'
|
39
|
+
sql_opts[:limit] = "#{params['iDisplayStart']},#{params['iDisplayLength']}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Ordering
|
43
|
+
if params['iSortCol_0']
|
44
|
+
orders = []
|
45
|
+
i = 0
|
46
|
+
while i < params['iSortingCols'].to_i do
|
47
|
+
if params['bSortable_' + params['iSortCol_' + i.to_s]] == "true"
|
48
|
+
# Make sure the order works for metafied columns and normal columns
|
49
|
+
col = full_columns[ params['iSortCol_' + i.to_s].to_i ]
|
50
|
+
orders.push( "#{col} #{params['sSortDir_' + i.to_s]}" )
|
51
|
+
end
|
52
|
+
i += 1
|
53
|
+
end
|
54
|
+
sql_opts[:order] = orders.join(", ") unless orders.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
# Searching
|
58
|
+
search_str = ""
|
59
|
+
searches = []
|
60
|
+
if params['sSearch'] and !params['sSearch'].empty?
|
61
|
+
full_columns.each_with_index do |col,i|
|
62
|
+
searches.push( "#{col} LIKE '%#{params['sSearch']}%'" )
|
63
|
+
end
|
64
|
+
search_str = searches.join(' OR ') unless searches.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Filtering
|
68
|
+
filter_str = ""
|
69
|
+
filters = []
|
70
|
+
full_columns.each_with_index do |col,i|
|
71
|
+
if params['bSearchable_' + i.to_s] == "true" and !params['sSearch_' + i.to_s].empty?
|
72
|
+
filters.push( "#{col} LIKE '%#{params['sSearch_' + i.to_s]}%'" )
|
73
|
+
end
|
74
|
+
end
|
75
|
+
filter_str = filters.join(' AND ') unless filters.empty?
|
76
|
+
|
77
|
+
# Pull Searching & Filtering into where
|
78
|
+
if !searches.empty? and !filters.empty?
|
79
|
+
sql_opts[:conditions] = "(#{search_str}) AND #{filter_str}"
|
80
|
+
elsif !searches.empty?
|
81
|
+
sql_opts[:conditions] = search_str
|
82
|
+
elsif !filters.empty?
|
83
|
+
sql_opts[:conditions] = filter_str
|
84
|
+
end
|
85
|
+
|
86
|
+
# Query
|
87
|
+
if dscope.nil?
|
88
|
+
# Scope model
|
89
|
+
records = curr_model.select( sql_opts[:select] ).limit( sql_opts[:limit] ).order( sql_opts[:order] ).where( sql_opts[:conditions] ).joins(sql_opts[:joins])
|
90
|
+
# Records Found
|
91
|
+
filtered_total = curr_model.count( :select => "*", :conditions => sql_opts[:conditions], :joins => sql_opts[:joins] )
|
92
|
+
# Total Found
|
93
|
+
total = curr_model.count( :select => "*" )
|
94
|
+
elsif params[:id].nil?
|
95
|
+
# Scope model
|
96
|
+
records = curr_model.send( dscope.to_s ).select( sql_opts[:select] ).limit( sql_opts[:limit] ).order( sql_opts[:order] ).where( sql_opts[:conditions] ).joins(sql_opts[:joins])
|
97
|
+
# Records Found
|
98
|
+
filtered_total = curr_model.send( dscope.to_s ).count( :select => "*", :conditions => sql_opts[:conditions], :joins => sql_opts[:joins] )
|
99
|
+
# Total Found
|
100
|
+
total = curr_model.send( dscope.to_s ).count( :select => "*" )
|
101
|
+
else
|
102
|
+
# Scope model
|
103
|
+
records = curr_model.send( dscope.to_s, params[:id] ).select( sql_opts[:select] ).limit( sql_opts[:limit] ).order( sql_opts[:order] ).where( sql_opts[:conditions] ).joins(sql_opts[:joins])
|
104
|
+
# Records Found
|
105
|
+
filtered_total = curr_model.send( dscope.to_s, params[:id] ).count( :select => "*", :conditions => sql_opts[:conditions], :joins => sql_opts[:joins] )
|
106
|
+
# Total Found
|
107
|
+
total = curr_model.send( dscope.to_s, params[:id] ).count( :select => "*" )
|
108
|
+
end
|
109
|
+
|
110
|
+
# Build Output Data Structure
|
111
|
+
output = { "sEcho" => params['sEcho'],
|
112
|
+
"iTotalRecords" => total,
|
113
|
+
"iTotalDisplayRecords" => filtered_total,
|
114
|
+
"aaData" => [] }
|
115
|
+
|
116
|
+
records.each do |a_row|
|
117
|
+
row = []
|
118
|
+
columns.each_with_index do |col,i|
|
119
|
+
if col == "version" # Special output formatting for version column
|
120
|
+
row.push( a_row[ col ]=="0" ? '-' : a_row[ col ] )
|
121
|
+
elsif col != ' ' # General Output
|
122
|
+
row.push( a_row[ col ])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
output['aaData'].push(row)
|
126
|
+
end
|
127
|
+
|
128
|
+
output
|
129
|
+
end
|
130
|
+
end
|