datatables-net 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +73 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +618 -0
- data/Rakefile +14 -0
- data/lib/ajax-datatables-rails.rb +11 -0
- data/lib/ajax-datatables-rails/base.rb +205 -0
- data/lib/ajax-datatables-rails/config.rb +24 -0
- data/lib/ajax-datatables-rails/datatable/column.rb +106 -0
- data/lib/ajax-datatables-rails/datatable/datatable.rb +69 -0
- data/lib/ajax-datatables-rails/datatable/simple_order.rb +31 -0
- data/lib/ajax-datatables-rails/datatable/simple_search.rb +19 -0
- data/lib/ajax-datatables-rails/orm/active_record.rb +52 -0
- data/lib/ajax-datatables-rails/version.rb +3 -0
- data/lib/generators/datatable/config_generator.rb +17 -0
- data/lib/generators/datatable/templates/ajax_datatables_rails_config.rb +7 -0
- data/lib/generators/rails/datatable_generator.rb +27 -0
- data/lib/generators/rails/templates/datatable.rb +41 -0
- data/spec/ajax-datatables-rails/base_spec.rb +140 -0
- data/spec/ajax-datatables-rails/configuration_spec.rb +43 -0
- data/spec/ajax-datatables-rails/datatable/column_spec.rb +65 -0
- data/spec/ajax-datatables-rails/datatable/datatable_spec.rb +97 -0
- data/spec/ajax-datatables-rails/datatable/simple_order_spec.rb +12 -0
- data/spec/ajax-datatables-rails/datatable/simple_search_spec.rb +16 -0
- data/spec/ajax-datatables-rails/orm/active_record_filter_records_spec.rb +154 -0
- data/spec/ajax-datatables-rails/orm/active_record_paginate_records_spec.rb +51 -0
- data/spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb +42 -0
- data/spec/ajax-datatables-rails/orm/active_record_spec.rb +34 -0
- data/spec/schema.rb +43 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/test_helpers.rb +66 -0
- data/spec/test_models.rb +20 -0
- metadata +202 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 12a1184382aec08a7e808d61beb0340c555407f0
|
4
|
+
data.tar.gz: d62b0eeb7553b308ae4b27018ff8adc06e7eff8e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 83d8f834fcc37eb94a4c64d7410cd693e3c64198222160b1790fb8cf0315f399dc9f4c2e96718f7778fb1252eb2bbd3b63f5ba85bb3c470bcda2aef2d96ebe15
|
7
|
+
data.tar.gz: 208dc31871ca63e64c2f023558aa849549e1cf7cb63cb481273f4e5cdbfd7fbae115fad7877ed394a0314afb5da66ddefccd32c4f9cb2f150b7c189c473c2f23
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## 0.4.0
|
4
|
+
* Supporting ruby 2.0 and later versions. Rails 3.2 and later version.
|
5
|
+
* We have how-to project with special concept on rails_script and coffee_routes gems. https://github.com/ajahongir/ajax-datatables-rails-v-0-4-0-how-to
|
6
|
+
* `Datatable.js` idiom based code changes. Now we dont have variables as `sortable_columns` and `searchable_columns` instead we have a hash based `view_columns` variable to define column options. look at readme to more details.
|
7
|
+
* Support Searching and Ordering out of box. tested on mysql and sqlihgt.
|
8
|
+
|
9
|
+
## 0.3.1
|
10
|
+
* Adds `:oracle` as supported `db_adapter`. Thanks to [lutechspa](https://github.com/lutechspa) for this contribution.
|
11
|
+
|
12
|
+
## 0.3.0
|
13
|
+
* Changes to the `sortable_columns` and `searchable_columns` syntax as it
|
14
|
+
required us to do unnecessary guessing. New syntax is `ModelName.column_name`
|
15
|
+
or `Namespace::ModelName.column_name`. Old syntax of `table_name.column_name`
|
16
|
+
is still available to use, but prints a deprecation warning. Thanks to
|
17
|
+
[M. Saiqul Haq](https://github.com/saiqulhaq) for pointing this.
|
18
|
+
* Adds support to discover from received params if a column should be really
|
19
|
+
considered for sorting purposes. Thanks to [Zachariah Clay](https://github.com/mebezac)
|
20
|
+
for this contribution.
|
21
|
+
* Moves paginator settings to configuration initializer.
|
22
|
+
|
23
|
+
## 0.2.1
|
24
|
+
* Fix count method to work with select statements under Rails 4.1. Thanks to
|
25
|
+
[Jason Mitchell](https://github.com/mitchej123) for the contribution.
|
26
|
+
* Edits to `README` documentation about the `options` hash. Thanks to
|
27
|
+
[Jonathan E Hogue](https://github.com/hoguej) for pointing out that previous
|
28
|
+
documentation was confusing and didn't address its usage properly.
|
29
|
+
* Edits to `README` documentation on complex model queries inside the
|
30
|
+
`get_raw_records` method. A round of applause to [Zoltan Paulovics](https://github.com/zpaulovics)
|
31
|
+
for contributing this awesome piece of documentation. :smile:
|
32
|
+
* Adds typecast step to `search_condition` method, so now we support having
|
33
|
+
non-text columns inside the `searchable_columns` array.
|
34
|
+
* Adds support for multi-column sorting and multi-term search. Thanks to
|
35
|
+
[Zoltan Paulovics](https://github.com/zpaulovics) for contributing this feature.
|
36
|
+
* Adds optional config initializer, so we can have a base to typecast non
|
37
|
+
text-based columns and perform searches depending on the use of `:mysql2`,
|
38
|
+
`:sqlite3` or `:pg`. Thanks to [M. Saiqul Haq](https://github.com/saiqulhaq)
|
39
|
+
for contributing this feature.
|
40
|
+
|
41
|
+
## 0.2.0
|
42
|
+
* This version works with jQuery dataTables ver. 1.10 and it's new API syntax.
|
43
|
+
* Added `legacy` branch to repo. If your project is working with jQuery
|
44
|
+
dataTables ver. 1.9, this is the branch you need to pull, or use the last
|
45
|
+
`0.1.x` version of this gem.
|
46
|
+
|
47
|
+
## 0.1.2
|
48
|
+
* Fixes `where` clause being built even when search term is an empty string.
|
49
|
+
Thanks to [e-fisher](https://github.com/e-fisher) for spotting and fixing this.
|
50
|
+
|
51
|
+
## 0.1.1
|
52
|
+
* Fixes problem on `searchable_columns` where the corresponding model is
|
53
|
+
a composite model name, e.g. `UserData`, `BillingAddress`.
|
54
|
+
Thanks to [iruca3](https://github.com/iruca3) for the fix.
|
55
|
+
|
56
|
+
## 0.1.0
|
57
|
+
* A fresh start. Sets base class name to: `AjaxDatatablesRails::Base`.
|
58
|
+
* Extracts pagination functions to mixable modules.
|
59
|
+
* A user would have the option to stick to the base
|
60
|
+
`AjaxDatatablesRails::Extensions::SimplePaginator` or replace it with
|
61
|
+
`AjaxDatatablesRails::Extensions::Kaminari` or
|
62
|
+
`AjaxDatatablesRails::Extensions::WillPaginate`, depending on what he/she
|
63
|
+
is using to handle record pagination.
|
64
|
+
* Removes dependency to pass in a model name to the generator. This way,
|
65
|
+
the developer has more flexibility to implement whatever datatable feature is
|
66
|
+
required.
|
67
|
+
* Datatable constructor accepts an optional `options` hash to provide
|
68
|
+
more flexibility.
|
69
|
+
See [README](https://github.com/antillas21/ajax-datatables-rails/blob/master/README.mds#options)
|
70
|
+
for examples.
|
71
|
+
* Sets generator inside the `Rails` namespace. To generate an
|
72
|
+
`AjaxDatatablesRails` child class, just execute the
|
73
|
+
generator like this: `$ rails generate datatable NAME`.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Joel Quenneville
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,618 @@
|
|
1
|
+
# ajax-datatables-rails
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/antillas21/ajax-datatables-rails.svg?branch=master)](https://travis-ci.org/antillas21/ajax-datatables-rails)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/ajax-datatables-rails.svg)](http://badge.fury.io/rb/ajax-datatables-rails)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/antillas21/ajax-datatables-rails/badges/gpa.svg)](https://codeclimate.com/github/antillas21/ajax-datatables-rails)
|
6
|
+
|
7
|
+
> __Important__
|
8
|
+
>
|
9
|
+
> [Datatables](http://datatables.net) recently released version 1.10 (which includes a new API and features) and deprecated version 1.9.
|
10
|
+
>
|
11
|
+
> This gem is targeted at Datatables version 1.10 and up.
|
12
|
+
|
13
|
+
|
14
|
+
## Description
|
15
|
+
|
16
|
+
Datatables is a nifty jquery plugin that adds the ability to paginate, sort,
|
17
|
+
and search your html tables. When dealing with large tables
|
18
|
+
(more than a couple hundred rows) however, we run into performance issues.
|
19
|
+
These can be fixed by using server-side pagination, but this breaks some
|
20
|
+
datatables functionality.
|
21
|
+
|
22
|
+
`ajax-datatables-rails` is a wrapper around datatable's ajax methods that allow
|
23
|
+
synchronization with server-side pagination in a rails app. It was inspired by
|
24
|
+
this [Railscast](http://railscasts.com/episodes/340-datatables). I needed to
|
25
|
+
implement a similar solution in a couple projects I was working on, so I
|
26
|
+
extracted a solution into a gem.
|
27
|
+
|
28
|
+
## ORM support
|
29
|
+
|
30
|
+
Currently `AjaxDatatablesRails` only supports `ActiveRecord` as ORM for
|
31
|
+
performing database queries.
|
32
|
+
|
33
|
+
Adding support for `Sequel`, `Mongoid` and `MongoMapper` is a planned feature
|
34
|
+
for this gem. If you'd be interested in contributing to speed development,
|
35
|
+
please [open an issue](https://github.com/antillas21/ajax-datatables-rails/issues/new)
|
36
|
+
and get in touch.
|
37
|
+
|
38
|
+
## Installation
|
39
|
+
|
40
|
+
Add these lines to your application's Gemfile:
|
41
|
+
|
42
|
+
gem 'jquery-datatables-rails'
|
43
|
+
gem 'ajax-datatables-rails'
|
44
|
+
|
45
|
+
And then execute:
|
46
|
+
|
47
|
+
$ bundle
|
48
|
+
|
49
|
+
The `jquery-datatables-rails` gem is listed as a convenience, to ease adding
|
50
|
+
jQuery dataTables to your Rails project. You can always add the plugin assets
|
51
|
+
manually via the assets pipeline. If you decide to use the
|
52
|
+
`jquery-datatables-rails` gem, please refer to its installation instructions
|
53
|
+
[here](https://github.com/rweng/jquery-datatables-rails).
|
54
|
+
|
55
|
+
## Usage (0.3.x)
|
56
|
+
*The following examples assume that we are setting up ajax-datatables-rails for
|
57
|
+
an index page of users from a `User` model, and that we are using postgresql as
|
58
|
+
our db, because you __should be using it__, if not, please refer to the
|
59
|
+
[Searching on non text-based columns](#searching-on-non-text-based-columns)
|
60
|
+
entry in the Additional Notes section.*
|
61
|
+
|
62
|
+
### Generate
|
63
|
+
Run the following command:
|
64
|
+
|
65
|
+
$ rails generate datatable User
|
66
|
+
|
67
|
+
|
68
|
+
This will generate a file named `user_datatable.rb` in `app/datatables`.
|
69
|
+
Open the file and customize in the functions as directed by the comments.
|
70
|
+
|
71
|
+
Take a look [here](#generator-syntax) for an explanation about the generator syntax.
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
### Build the View
|
76
|
+
|
77
|
+
You should always start by the single source of truth, which is your html view. Suppose we need to render a users table and display: first name, last name, and bio for each user.
|
78
|
+
|
79
|
+
Something like this:
|
80
|
+
|
81
|
+
|First Name|Last Name|Brief Bio|
|
82
|
+
|----------|---------|---------|
|
83
|
+
|John|Doe|Is your default user everywhere|
|
84
|
+
|Jane|Doe|Is John's wife|
|
85
|
+
|James|Doe|Is John's brother and best friend|
|
86
|
+
|
87
|
+
|
88
|
+
* Set up an html `<table>` with a `<thead>` and `<tbody>`
|
89
|
+
* Add in your table headers if desired
|
90
|
+
* Don't add any rows to the body of the table, datatables does this automatically
|
91
|
+
* Add a data attribute to the `<table>` tag with the url of the JSON feed, in our case is the `users_path` as we're pointing to the `UsersController#index` action
|
92
|
+
|
93
|
+
|
94
|
+
```html
|
95
|
+
<table id="users-table", data-source="<%= users_path(format: :json) %>">
|
96
|
+
<thead>
|
97
|
+
<tr>
|
98
|
+
<th>First Name</th>
|
99
|
+
<th>Last Name</th>
|
100
|
+
<th>Brief Bio</th>
|
101
|
+
</tr>
|
102
|
+
</thead>
|
103
|
+
<tbody>
|
104
|
+
</tbody>
|
105
|
+
</table>
|
106
|
+
```
|
107
|
+
|
108
|
+
### Customize the generated Datatables class
|
109
|
+
```ruby
|
110
|
+
def view_columns
|
111
|
+
# Declare strings in this format: ModelName.column_name
|
112
|
+
# or in aliased_join_table.column_name format
|
113
|
+
@view_columns ||= {}
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
* In this method, add a list of the model(s) columns mapped to the data you need to present. In this case: `first_name`, `last_name` and `bio`.
|
118
|
+
|
119
|
+
This gives us:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
def view_columns
|
123
|
+
@view_columns ||= {
|
124
|
+
id: { source: "City.id", cond: :eq, searchable: true, orderable: true },
|
125
|
+
name: { source: "City.name", cond: :like },
|
126
|
+
created_at: { source: "City.created_at", cond: :gteq },
|
127
|
+
country_name: { source: "City.country_id", cond: :eq }
|
128
|
+
}
|
129
|
+
end
|
130
|
+
```
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
by default orderable and searchable is true
|
134
|
+
```
|
135
|
+
|
136
|
+
* [See here](#searching-on-non-text-based-columns) for notes about the
|
137
|
+
`view_columns` settings (if using something different from `postgre`).
|
138
|
+
* [Read these notes](#columns-syntax) about
|
139
|
+
considerations for the `view_columns` method.
|
140
|
+
|
141
|
+
### Map data
|
142
|
+
```ruby
|
143
|
+
def data
|
144
|
+
records.map do |record|
|
145
|
+
[
|
146
|
+
# comma separated list of the values for each cell of a table row
|
147
|
+
# example: record.attribute,
|
148
|
+
]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
This method builds a 2D array that is used by datatables to construct the html
|
154
|
+
table. Insert the values you want on each column.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
def data
|
158
|
+
records.map do |record|
|
159
|
+
[
|
160
|
+
record.first_name,
|
161
|
+
record.last_name,
|
162
|
+
record.bio
|
163
|
+
]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
In the example above, we use the same sequence of column declarations as in
|
169
|
+
`sortable_columns`. This ordering is important! And as of 0.3.0, the first
|
170
|
+
column must be a sortable column. For more, see
|
171
|
+
[this issue](https://github.com/antillas21/ajax-datatables-rails/issues/83).
|
172
|
+
|
173
|
+
[See here](#using-view-helpers) if you need to use view helpers in the
|
174
|
+
returned 2D array, like `link_to`, `mail_to`, `resource_path`, etc.
|
175
|
+
|
176
|
+
#### Automatic addition of ID
|
177
|
+
If you want the gem inserts automatically the ID of the record in the `<tr>` element
|
178
|
+
as shown in this [DataTable example](http://www.datatables.net/examples/server_side/ids.html),
|
179
|
+
you have to perform some modifications in both `some_datatable.rb` file and in your javascript.
|
180
|
+
|
181
|
+
Here is an example:
|
182
|
+
```ruby
|
183
|
+
def data
|
184
|
+
records.map do |record|
|
185
|
+
{
|
186
|
+
'0' => record.first_name,
|
187
|
+
'1' => record.last_name,
|
188
|
+
'2' => record.email,
|
189
|
+
'DT_RowId' => record.id
|
190
|
+
}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
and in your javascript file:
|
196
|
+
```javascript
|
197
|
+
$(function() {
|
198
|
+
return $('#table_id').dataTable({
|
199
|
+
processing: true,
|
200
|
+
serverSide: true,
|
201
|
+
ajax: 'ajax_url',
|
202
|
+
columns: [
|
203
|
+
{data: '0' },
|
204
|
+
{data: '1' },
|
205
|
+
{data: '2' }
|
206
|
+
]
|
207
|
+
});
|
208
|
+
});
|
209
|
+
```
|
210
|
+
|
211
|
+
#### Get Raw Records
|
212
|
+
```ruby
|
213
|
+
def get_raw_records
|
214
|
+
# insert query here
|
215
|
+
end
|
216
|
+
```
|
217
|
+
|
218
|
+
This is where your query goes.
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
def get_raw_records
|
222
|
+
# suppose we need all User records
|
223
|
+
# Rails 4+
|
224
|
+
User.all
|
225
|
+
# Rails 3.x
|
226
|
+
# User.scoped
|
227
|
+
end
|
228
|
+
```
|
229
|
+
|
230
|
+
Obviously, you can construct your query as required for the use case the
|
231
|
+
datatable is used. Example: `User.active.with_recent_messages`.
|
232
|
+
|
233
|
+
> __IMPORTANT:__ Make sure to return an `ActiveRecord::Relation` object
|
234
|
+
> as the end product of this method.
|
235
|
+
>
|
236
|
+
> Why? Because the result from this method, will be chained (for now)
|
237
|
+
> to `ActiveRecord` methods for sorting, filtering and pagination.
|
238
|
+
|
239
|
+
#### Associated and nested models
|
240
|
+
The previous example has only one single model. But what about if you have
|
241
|
+
some associated nested models and in a report you want to show fields from
|
242
|
+
these tables.
|
243
|
+
|
244
|
+
Take an example that has an `Event, Course, Coursetype, Allocation, Teacher,
|
245
|
+
Contact, Competency and CompetencyType` models. We want to have a datatables
|
246
|
+
report which has the following column:
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
'coursetypes.name',
|
250
|
+
'courses.name',
|
251
|
+
'events.title',
|
252
|
+
'events.event_start',
|
253
|
+
'events.event_end',
|
254
|
+
'contacts.full_name',
|
255
|
+
'competency_types.name',
|
256
|
+
'events.status'
|
257
|
+
```
|
258
|
+
|
259
|
+
We want to sort and search on all columns of the list. The related definition
|
260
|
+
would be:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
|
264
|
+
def view_columns
|
265
|
+
@view_columns ||= [
|
266
|
+
'Coursetype.name',
|
267
|
+
'Course.name',
|
268
|
+
'Event.title',
|
269
|
+
'Event.event_start',
|
270
|
+
'Event.event_end',
|
271
|
+
'Contact.last_name',
|
272
|
+
'CompetencyType.name',
|
273
|
+
'Event.status'
|
274
|
+
]
|
275
|
+
end
|
276
|
+
|
277
|
+
def get_raw_records
|
278
|
+
Event.joins(
|
279
|
+
{ course: :coursetype },
|
280
|
+
{ allocations: {
|
281
|
+
teacher: [:contact, {competencies: :competency_type}]
|
282
|
+
}
|
283
|
+
}).distinct
|
284
|
+
end
|
285
|
+
```
|
286
|
+
|
287
|
+
__Some comments for the above code:__
|
288
|
+
|
289
|
+
1. In the `get_raw_records` method we have quite a complex query having one to
|
290
|
+
many and may to many associations using the joins ActiveRecord method.
|
291
|
+
The joins will generate INNER JOIN relations in the SQL query. In this case,
|
292
|
+
we do not include all event in the report if we have events which is not
|
293
|
+
associated with any model record from the relation.
|
294
|
+
|
295
|
+
2. To have all event records in the list we should use the `.includes` method,
|
296
|
+
which generate LEFT OUTER JOIN relation of the SQL query.
|
297
|
+
__IMPORTANT:__ Make sure to append `.references(:related_model)` with any
|
298
|
+
associated model. That forces the eager loading of all the associated models
|
299
|
+
by one SQL query, and the search condition for any column works fine.
|
300
|
+
Otherwise the `:recordsFiltered => filter_records(get_raw_records).count(:all)`
|
301
|
+
will generate 2 SQL queries (one for the Event model, and then another for the
|
302
|
+
associated tables). The `:recordsFiltered => filter_records(get_raw_records).count(:all)`
|
303
|
+
will use only the first one to return from the ActiveRecord::Relation object
|
304
|
+
in `get_raw_records` and you will get an error message of __Unknown column
|
305
|
+
'yourtable.yourfield' in 'where clause'__ in case the search field value
|
306
|
+
is not empty.
|
307
|
+
|
308
|
+
So the query using the `.includes()` method is:
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
def get_raw_records
|
312
|
+
Event.includes(
|
313
|
+
{ course: :coursetype },
|
314
|
+
{ allocations: {
|
315
|
+
teacher: [:contact, { competencies: :competency_type }]
|
316
|
+
}
|
317
|
+
}
|
318
|
+
).references(:course).distinct
|
319
|
+
end
|
320
|
+
```
|
321
|
+
|
322
|
+
For more examples of 0.3.0 syntax for complex associations (and an example of
|
323
|
+
the `data` method), read
|
324
|
+
[this](https://github.com/antillas21/ajax-datatables-rails/issues/77).
|
325
|
+
|
326
|
+
### Setup the Controller action
|
327
|
+
|
328
|
+
Set the controller to respond to JSON
|
329
|
+
|
330
|
+
```ruby
|
331
|
+
def index
|
332
|
+
respond_to do |format|
|
333
|
+
format.html
|
334
|
+
format.json { render json: UserDatatable.new(view_context) }
|
335
|
+
end
|
336
|
+
end
|
337
|
+
```
|
338
|
+
|
339
|
+
Don't forget to make sure the proper route has been added to `config/routes.rb`.
|
340
|
+
|
341
|
+
|
342
|
+
* Set up an html `<table>` with a `<thead>` and `<tbody>`
|
343
|
+
* Add in your table headers if desired
|
344
|
+
* Don't add any rows to the body of the table, datatables does this automatically
|
345
|
+
* Add a data attribute to the `<table>` tag with the url of the JSON feed
|
346
|
+
|
347
|
+
The resulting view may look like this:
|
348
|
+
|
349
|
+
```html
|
350
|
+
<table id="users-table" data-source="<%= users_path(format: :json) %>">
|
351
|
+
<thead>
|
352
|
+
<tr>
|
353
|
+
<th>First Name</th>
|
354
|
+
<th>Last Name</th>
|
355
|
+
<th>Brief Bio</th>
|
356
|
+
</tr>
|
357
|
+
</thead>
|
358
|
+
<tbody>
|
359
|
+
</tbody>
|
360
|
+
</table>
|
361
|
+
```
|
362
|
+
|
363
|
+
### Wire up the Javascript
|
364
|
+
Finally, the javascript to tie this all together. In the appropriate `coffee` file:
|
365
|
+
|
366
|
+
```coffeescript
|
367
|
+
# users.coffee
|
368
|
+
|
369
|
+
$ ->
|
370
|
+
$('#users-table').dataTable
|
371
|
+
processing: true
|
372
|
+
serverSide: true
|
373
|
+
ajax: $('#users-table').data('source')
|
374
|
+
pagingType: 'full_numbers'
|
375
|
+
# optional, if you want full pagination controls.
|
376
|
+
# Check dataTables documentation to learn more about
|
377
|
+
# available options.
|
378
|
+
```
|
379
|
+
|
380
|
+
or, if you're using plain javascript:
|
381
|
+
```javascript
|
382
|
+
// users.js
|
383
|
+
|
384
|
+
jQuery(document).ready(function() {
|
385
|
+
$('#users-table').dataTable({
|
386
|
+
"processing": true,
|
387
|
+
"serverSide": true,
|
388
|
+
"ajax": $('#users-table').data('source'),
|
389
|
+
"pagingType": "full_numbers",
|
390
|
+
// optional, if you want full pagination controls.
|
391
|
+
// Check dataTables documentation to learn more about
|
392
|
+
// available options.
|
393
|
+
});
|
394
|
+
});
|
395
|
+
```
|
396
|
+
|
397
|
+
### Additional Notes
|
398
|
+
|
399
|
+
#### Columns syntax
|
400
|
+
|
401
|
+
Since version `0.3.0`, we are implementing a pseudo code way of declaring
|
402
|
+
the array columns to use when querying the database.
|
403
|
+
|
404
|
+
Example. Suppose we have the following models: `User`, `PurchaseOrder`,
|
405
|
+
`Purchase::LineItem` and we need to have several columns from those models
|
406
|
+
available in our datatable to search and sort by.
|
407
|
+
|
408
|
+
```ruby
|
409
|
+
# we use the ModelName.column_name notation to declare our columns
|
410
|
+
|
411
|
+
def view_columns
|
412
|
+
@view_columns ||= [
|
413
|
+
'User.first_name',
|
414
|
+
'User.last_name',
|
415
|
+
'PurchaseOrder.number',
|
416
|
+
'PurchaseOrder.created_at',
|
417
|
+
'Purchase::LineItem.quantity',
|
418
|
+
'Purchase::LineItem.unit_price',
|
419
|
+
'Purchase::LineItem.item_total'
|
420
|
+
]
|
421
|
+
end
|
422
|
+
```
|
423
|
+
|
424
|
+
##### What if the datatable itself is namespaced?
|
425
|
+
Example: what if the datatable is namespaced into an `Admin` module?
|
426
|
+
|
427
|
+
```ruby
|
428
|
+
module Admin
|
429
|
+
class PurchasesDatatable < AjaxDatatablesRails::Base
|
430
|
+
end
|
431
|
+
end
|
432
|
+
```
|
433
|
+
|
434
|
+
Taking the same models and columns, we would define it like this:
|
435
|
+
|
436
|
+
```ruby
|
437
|
+
def view_columns
|
438
|
+
@view_columns ||= [
|
439
|
+
'::User.first_name',
|
440
|
+
'::User.last_name',
|
441
|
+
'::PurchaseOrder.number',
|
442
|
+
'::PurchaseOrder.created_at',
|
443
|
+
'::Purchase::LineItem.quantity',
|
444
|
+
'::Purchase::LineItem.unit_price',
|
445
|
+
'::Purchase::LineItem.item_total'
|
446
|
+
]
|
447
|
+
end
|
448
|
+
```
|
449
|
+
|
450
|
+
Pretty much like you would do it, if you were inside a namespaced controller.
|
451
|
+
|
452
|
+
#### What if I'm using Oracle?
|
453
|
+
|
454
|
+
We have recently merged and released a contribution from [lutechspa](https://github.com/lutechspa) that makes this gem work with Oracle (tested in version 11g). You can [take a look at this sample repo](https://github.com/paoloripamonti/oracle-ajax-datatable) to get an idea on how to set things up.
|
455
|
+
|
456
|
+
#### Searching on non text-based columns
|
457
|
+
|
458
|
+
It always comes the time when you need to add a non-string/non-text based
|
459
|
+
column to the `@view_columns` array, so you can perform searches against
|
460
|
+
these column types (example: numeric, date, time).
|
461
|
+
|
462
|
+
We recently added the ability to (automatically) typecast these column types
|
463
|
+
and have this scenario covered. Please note however, if you are using
|
464
|
+
something different from `postgresql` (with the `:pg` gem), like `oracle`,
|
465
|
+
`mysql` or `sqlite`, then you need to add an initializer in your application's
|
466
|
+
`config/initializers` directory.
|
467
|
+
|
468
|
+
If you don't perform this step (again, if using something different from
|
469
|
+
`postgresql`), your database will complain that it does not understand the
|
470
|
+
default typecast used to enable such searches.
|
471
|
+
|
472
|
+
|
473
|
+
#### Configuration initializer
|
474
|
+
|
475
|
+
You have two options to create this initializer:
|
476
|
+
|
477
|
+
* use the provided (and recommended) generator (and then just edit the file);
|
478
|
+
* create the file from scratch.
|
479
|
+
|
480
|
+
To use the generator, from the terminal execute:
|
481
|
+
|
482
|
+
```
|
483
|
+
$ bundle exec rails generate datatable:config
|
484
|
+
```
|
485
|
+
|
486
|
+
Doing so, will create the `config/initializers/ajax_datatables_rails.rb` file
|
487
|
+
with the following content:
|
488
|
+
|
489
|
+
```ruby
|
490
|
+
AjaxDatatablesRails.configure do |config|
|
491
|
+
# available options for db_adapter are: :pg, :mysql, :mysql2, :sqlite, :sqlite3, :oracle
|
492
|
+
# config.db_adapter = :pg
|
493
|
+
|
494
|
+
# available options for orm are: :active_record, :mongoid
|
495
|
+
# config.orm = :active_record
|
496
|
+
end
|
497
|
+
```
|
498
|
+
|
499
|
+
Uncomment the `config.db_adapter` line and set the corresponding value to your
|
500
|
+
database and gem. This is all you need.
|
501
|
+
|
502
|
+
Uncomment the `config.orm` line to set `active_record or mongoid` if
|
503
|
+
included in your project. It defaults to `active_record`.
|
504
|
+
|
505
|
+
If you want to make the file from scratch, just copy the above code block into
|
506
|
+
a file inside the `config/initializers` directory.
|
507
|
+
|
508
|
+
|
509
|
+
#### Using view helpers
|
510
|
+
|
511
|
+
Sometimes you'll need to use view helper methods like `link_to`, `h`, `mailto`,
|
512
|
+
`edit_resource_path` in the returned JSON representation returned by the `data`
|
513
|
+
method.
|
514
|
+
|
515
|
+
To have these methods available to be used, this is the way to go:
|
516
|
+
|
517
|
+
```ruby
|
518
|
+
class MyCustomDatatable < AjaxDatatablesRails::Base
|
519
|
+
# either define them one-by-one
|
520
|
+
def_delegator :@view, :link_to
|
521
|
+
def_delegator :@view, :h
|
522
|
+
def_delegator :@view, :mail_to
|
523
|
+
|
524
|
+
# or define them in one pass
|
525
|
+
def_delegators :@view, :link_to, :h, :mailto, :edit_resource_path, :other_method
|
526
|
+
|
527
|
+
# now, you'll have these methods available to be used anywhere
|
528
|
+
# example: mapping the 2d jsonified array returned.
|
529
|
+
def data
|
530
|
+
records.map do |record|
|
531
|
+
[
|
532
|
+
link_to(record.fname, edit_resource_path(record)),
|
533
|
+
mail_to(record.email),
|
534
|
+
# other attributes
|
535
|
+
]
|
536
|
+
end
|
537
|
+
end
|
538
|
+
end
|
539
|
+
```
|
540
|
+
|
541
|
+
#### Options
|
542
|
+
|
543
|
+
An `AjaxDatatablesRails::Base` inherited class can accept an options hash at
|
544
|
+
initialization. This provides room for flexibility when required. Example:
|
545
|
+
|
546
|
+
```ruby
|
547
|
+
class UnrespondedMessagesDatatable < AjaxDatatablesRails::Base
|
548
|
+
# customized methods here
|
549
|
+
end
|
550
|
+
|
551
|
+
datatable = UnrespondedMessagesDatatable.new(view_context,
|
552
|
+
{ :foo => { :bar => Baz.new }, :from => 1.month.ago }
|
553
|
+
)
|
554
|
+
```
|
555
|
+
So, now inside your class code, you can use those options like this:
|
556
|
+
|
557
|
+
|
558
|
+
```ruby
|
559
|
+
# let's see an example
|
560
|
+
def from
|
561
|
+
@from ||= options[:from].beginning_of_day
|
562
|
+
end
|
563
|
+
|
564
|
+
def to
|
565
|
+
@to ||= Date.today.end_of_day
|
566
|
+
end
|
567
|
+
|
568
|
+
def get_raw_records
|
569
|
+
Message.unresponded.where(received_at: from..to)
|
570
|
+
end
|
571
|
+
```
|
572
|
+
|
573
|
+
#### Generator Syntax
|
574
|
+
|
575
|
+
Also, a class that inherits from `AjaxDatatablesRails::Base` is not tied to an
|
576
|
+
existing model, module, constant or any type of class in your Rails app.
|
577
|
+
You can pass a name to your datatable class like this:
|
578
|
+
|
579
|
+
|
580
|
+
```
|
581
|
+
$ rails generate datatable users
|
582
|
+
# returns a users_datatable.rb file with a UsersDatatable class
|
583
|
+
|
584
|
+
$ rails generate datatable contact_messages
|
585
|
+
# returns a contact_messages_datatable.rb file with a ContactMessagesDatatable class
|
586
|
+
|
587
|
+
$ rails generate datatable UnrespondedMessages
|
588
|
+
# returns an unresponded_messages_datatable.rb file with an UnrespondedMessagesDatatable class
|
589
|
+
```
|
590
|
+
|
591
|
+
|
592
|
+
In the end, it's up to the developer which model(s), scope(s), relationship(s)
|
593
|
+
(or else) to employ inside the datatable class to retrieve records from the
|
594
|
+
database.
|
595
|
+
|
596
|
+
## Tutorial
|
597
|
+
|
598
|
+
Tutorial for Integrating `ajax-datatable-rails`, on Rails 4.
|
599
|
+
|
600
|
+
__version 0.3.0:__
|
601
|
+
|
602
|
+
[Part-1 The-Installation](https://github.com/antillas21/ajax-datatables-rails/wiki/Part-1----The-Installation)
|
603
|
+
|
604
|
+
[Part 2 The Datatables with ajax functionality](https://github.com/antillas21/ajax-datatables-rails/wiki/Part-2-The-Datatables-with-ajax-functionality)
|
605
|
+
|
606
|
+
The complete project code for this tutorial series is available on [github](https://github.com/trkrameshkumar/simple_app).
|
607
|
+
|
608
|
+
__version 0.4.0:__
|
609
|
+
|
610
|
+
Another sample project [code](https://github.com/ajahongir/ajax-datatables-rails-v-0-4-0-how-to). Its real world example.
|
611
|
+
|
612
|
+
## Contributing
|
613
|
+
|
614
|
+
1. Fork it
|
615
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
616
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
617
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
618
|
+
5. Create new Pull Request
|