effective_datatables 4.8.0 → 4.8.16
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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +199 -24
- data/app/assets/javascripts/effective_datatables/flash.js.coffee +1 -1
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +9 -4
- data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +42 -13
- data/app/assets/javascripts/effective_datatables/reorder.js.coffee +8 -2
- data/app/assets/javascripts/vendor/jquery.delayedChange.js +1 -1
- data/app/assets/stylesheets/dataTables/dataTables.bootstrap4.scss +1 -3
- data/app/helpers/effective_datatables_helper.rb +3 -1
- data/app/helpers/effective_datatables_private_helper.rb +12 -8
- data/app/models/effective/datatable.rb +28 -2
- data/app/models/effective/datatable_value_tool.rb +0 -6
- data/app/models/effective/effective_datatable/attributes.rb +1 -0
- data/app/models/effective/effective_datatable/compute.rb +1 -0
- data/app/models/effective/effective_datatable/cookie.rb +2 -0
- data/app/models/effective/effective_datatable/dsl/filters.rb +1 -1
- data/app/models/effective/effective_datatable/format.rb +9 -9
- data/app/models/effective/effective_datatable/params.rb +5 -0
- data/app/models/effective/effective_datatable/resource.rb +10 -9
- data/app/models/effective/effective_datatable/state.rb +1 -1
- data/app/views/effective/datatables/_active_storage_column.html.haml +1 -1
- data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +3 -2
- data/config/effective_datatables.rb +5 -1
- data/config/locales/en.yml +3 -1
- data/config/locales/es.yml +3 -1
- data/config/locales/nl.yml +3 -1
- data/lib/effective_datatables/version.rb +1 -1
- data/lib/effective_datatables.rb +4 -0
- metadata +6 -9
- data/app/datatables/effective_style_guide_datatable.rb +0 -45
- data/app/models/effective/access_denied.rb +0 -17
- data/app/views/effective/style_guide/_effective_datatables.html.haml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb1dc8f3ac21b885c37e56552192568b059350efcdcd7bd79784d87d91a4bee3
|
4
|
+
data.tar.gz: 46094ee0a00e9246b8dde73c2c9ab4f531c84a287f2cd7db7da467cc0dab6d92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51f91cf414121df572748ce03da5732b53011ad113db667b95284276f9ec628ec12ff0f8f614567ab88c770f9fa674059c6b8ca9a1ab1a5701e4dd8dbd509c2f
|
7
|
+
data.tar.gz: 1fbacd63b25ba9ba0556ccfec605a07ff5a3c6e5ddfc8da6dc723e66bfc4a72cb0d9c97d796a4acdb419e7fa5d1a2c8b8ec760bb4df77dbcee9b79708fce235d
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Does the right thing with searching sql columns as well as computed values from
|
|
8
8
|
|
9
9
|
Displays links to associated edit/show/destroy actions based on `current_user` authorized actions.
|
10
10
|
|
11
|
-
Other features include aggregate (total/average) footer rows, bulk actions, show/hide columns, responsive collapsing columns and
|
11
|
+
Other features include aggregate (total/average) footer rows, bulk actions, show/hide columns, responsive collapsing columns, google charts, and inline crud.
|
12
12
|
|
13
13
|
This gem includes the jQuery DataTables assets.
|
14
14
|
|
@@ -54,7 +54,8 @@ Please check out [Effective Datatables 3.x](https://github.com/code-and-effect/e
|
|
54
54
|
* [bulk_action](#bulk_action_divider)
|
55
55
|
* [bulk_download](#bulk_download)
|
56
56
|
* [bulk_action_content](#bulk_action_content)
|
57
|
-
* [
|
57
|
+
* [Charts](#charts)
|
58
|
+
* [Inline](#inline)
|
58
59
|
* [Extras](#extras)
|
59
60
|
* [Advanced Search and Sort](#advanced-search-and-sort)
|
60
61
|
* [Addtional Functionality](#additional-functionality)
|
@@ -453,7 +454,7 @@ The `datatable do ... end` block configures a table of data.
|
|
453
454
|
|
454
455
|
Initialize the datatable in your controller or view, `@datatable = PostsDatatable.new(self)`, and render it in your view `<%= render_datatable(@datatable) %>`
|
455
456
|
|
456
|
-
|
457
|
+
## col
|
457
458
|
|
458
459
|
This is the main DSL method that you will interact with.
|
459
460
|
|
@@ -526,7 +527,7 @@ You can also use the joined syntax, `col 'user.email'` to create a column for ju
|
|
526
527
|
|
527
528
|
This feature is only working with `belongs_to` and you need to add the `.joins(:user)` to the collection do ... end block yourself.
|
528
529
|
|
529
|
-
|
530
|
+
## val
|
530
531
|
|
531
532
|
Shorthand for value, this command also creates a column on the datatable.
|
532
533
|
|
@@ -548,7 +549,7 @@ This is implemented as a full Array search/sort and is much slower for large dat
|
|
548
549
|
|
549
550
|
The `.format do ... end` block can then be used to apply custom formatting.
|
550
551
|
|
551
|
-
|
552
|
+
## bulk_actions_col
|
552
553
|
|
553
554
|
Creates a column of checkboxes for use with the `bulk_actions` section.
|
554
555
|
|
@@ -558,7 +559,7 @@ Use these checkboxes to select all / none / one or more rows for the `bulk_actio
|
|
558
559
|
|
559
560
|
You can only have one `bulk_actions_col` per datatable.
|
560
561
|
|
561
|
-
|
562
|
+
## actions_col
|
562
563
|
|
563
564
|
When working with an ActiveRecord based collection, this column will consider the `current_user`'s authorization, and generate links to edit, show and destroy actions for any collection class.
|
564
565
|
|
@@ -596,7 +597,7 @@ Any `data-remote` actions will be hijacked and performed as inline ajax by datat
|
|
596
597
|
|
597
598
|
If you'd like to opt-out of this behavior, use `actions_col(inline: false)` or add `data-inline: false` to your action link.
|
598
599
|
|
599
|
-
|
600
|
+
## length
|
600
601
|
|
601
602
|
Sets the default number of rows per page. Valid lengths are `5`, `10`, `25`, `50`, `100`, `250`, `500`, `:all`
|
602
603
|
|
@@ -606,7 +607,7 @@ When not specified, effective_datatables uses the default as per the `config/ini
|
|
606
607
|
length 100
|
607
608
|
```
|
608
609
|
|
609
|
-
|
610
|
+
## order
|
610
611
|
|
611
612
|
Sets the default order of table rows. The first argument is the column, the second the direction.
|
612
613
|
|
@@ -618,7 +619,7 @@ When not specified, effective_datatables will sort by the first defined column.
|
|
618
619
|
order :created_at, :asc|:desc
|
619
620
|
```
|
620
621
|
|
621
|
-
|
622
|
+
## reorder
|
622
623
|
|
623
624
|
Enables drag-and-drop row re-ordering.
|
624
625
|
|
@@ -636,7 +637,7 @@ reorder :position
|
|
636
637
|
|
637
638
|
Using `reorder` will sort the collection by this field and disable all other column sorting.
|
638
639
|
|
639
|
-
|
640
|
+
## aggregate
|
640
641
|
|
641
642
|
The `aggregate` command inserts a row in the table's `tfoot`.
|
642
643
|
|
@@ -681,7 +682,7 @@ The form is submitted by an AJAX POST action, or, in some advanced circumstances
|
|
681
682
|
|
682
683
|
Initialize the datatable in your controller or view, `@datatable = PostsDatatable.new(self)`, and render its filters anywhere with `<%= render_datatable_filters(@datatable) %>`.
|
683
684
|
|
684
|
-
|
685
|
+
## scope
|
685
686
|
|
686
687
|
All defined scopes are rendered as a single radio button form field. Works great with the [effective_form_inputs](https://github.com/code-and-effect/effective_form_inputs) gem.
|
687
688
|
|
@@ -705,7 +706,7 @@ class Post < ApplicationRecord | ActiveRecord::Base
|
|
705
706
|
end
|
706
707
|
```
|
707
708
|
|
708
|
-
|
709
|
+
## filter
|
709
710
|
|
710
711
|
Each filter has a name and a default/fallback value. If the form is submitted blank, the default values are used.
|
711
712
|
|
@@ -758,7 +759,7 @@ Creates a single dropdown menu with a link to each action, download or content.
|
|
758
759
|
|
759
760
|
Along with this section, you must put a `bulk_actions_col` somewhere in your `datatable do ... end` section.
|
760
761
|
|
761
|
-
|
762
|
+
## bulk_action
|
762
763
|
|
763
764
|
Creates a link that becomes clickable when one or more checkbox/rows are selected as per the `bulk_actions_col` column.
|
764
765
|
|
@@ -814,11 +815,11 @@ def approve!
|
|
814
815
|
end
|
815
816
|
```
|
816
817
|
|
817
|
-
|
818
|
+
## bulk_action_divider
|
818
819
|
|
819
820
|
Inserts a menu divider `<li class='divider' role='separator'></li>`
|
820
821
|
|
821
|
-
|
822
|
+
## bulk_download
|
822
823
|
|
823
824
|
So it turns out there are some http issues with using an AJAX action to download a file.
|
824
825
|
|
@@ -859,7 +860,7 @@ def bulk_export_report
|
|
859
860
|
end
|
860
861
|
```
|
861
862
|
|
862
|
-
|
863
|
+
## bulk_action_content
|
863
864
|
|
864
865
|
Blindly inserts content into the dropdown.
|
865
866
|
|
@@ -873,7 +874,7 @@ end
|
|
873
874
|
|
874
875
|
Don't actually use this.
|
875
876
|
|
876
|
-
|
877
|
+
# Charts
|
877
878
|
|
878
879
|
Create a [Google Chart](https://developers.google.com/chart/interactive/docs/quick_start) based on your searched collection, filters and attributes.
|
879
880
|
|
@@ -930,11 +931,169 @@ All options passed to `chart` are used to initialize the chart javascript.
|
|
930
931
|
|
931
932
|
By default, the only package that is loaded is `corechart`, see the `config/initializers/effective_datatables.rb` file to add more packages.
|
932
933
|
|
933
|
-
|
934
|
+
# Inline
|
935
|
+
|
936
|
+
Any datatable can be used as an inline datatable, to create, update and destroy resources without leaving the current page.
|
937
|
+
|
938
|
+
If your datatable is already working with `actions_col` and being rendered from an `Effective::CrudController` controller, all you need to do is change your view from `render_datatable(@datatable)` to `render_datatable(@datatable, inline: true)`.
|
939
|
+
|
940
|
+
Click here for a [Inline Live Demo](https://effective-datatables-demo.herokuapp.com/things) and here for an [Inline Code Example](https://github.com/code-and-effect/effective_datatables_demo)
|
941
|
+
(only the `thing` data model and `things_datatable` are being used inline)
|
942
|
+
|
943
|
+
To use effective_datatables as an inline CRUD builder, you will be relying heavily on [effective_resources](https://github.com/code-and-effect/effective_resources) which is a dependency of this gem. I would also recommend you install [effective_developer](https://github.com/code-and-effect/effective_developer) to get access to some scaffolds and generators. It's not required but I'm gonna use them in this example.
|
944
|
+
|
945
|
+
Here is how I build rails models for inline datatable CRUD operations:
|
946
|
+
|
947
|
+
1. Create a new model file `app/models/thing.rb`:
|
948
|
+
|
949
|
+
```ruby
|
950
|
+
class Thing < ApplicationRecord
|
951
|
+
belongs_to :user
|
952
|
+
|
953
|
+
effective_resource do
|
954
|
+
title :string
|
955
|
+
description :text
|
956
|
+
timestamps
|
957
|
+
end
|
958
|
+
|
959
|
+
scope :deep, -> { includes(:user) }
|
960
|
+
scope :sorted, -> { order(:title) }
|
961
|
+
|
962
|
+
def to_s
|
963
|
+
title
|
964
|
+
end
|
965
|
+
end
|
966
|
+
```
|
967
|
+
|
968
|
+
The `effective_resource do` block comes from the [effective_resources](https://github.com/code-and-effect/effective_resources) gem and is used to build any permitted_params.
|
969
|
+
|
970
|
+
2. Generate a migration. Run `rails generate effective:migration things` to create a migration based off the model file then `rails db:migrate`.
|
971
|
+
|
972
|
+
3. Scaffold the rest. Run `rails generate effective:scaffold_controller things` which will create:
|
973
|
+
|
974
|
+
- A controller `app/controllers/things_controller.rb`:
|
975
|
+
|
976
|
+
```ruby
|
977
|
+
class ThingsController < ApplicationController
|
978
|
+
include Effective::CrudController
|
979
|
+
end
|
980
|
+
```
|
981
|
+
|
982
|
+
The Effective::CrudController comes from [effective_resources](https://github.com/code-and-effect/effective_resources) gem and handles the standard 7 CRUD actions and member and collection actions. It is opinionated code that follows rails conventions. It considers the `routes.rb` and `ability.rb` or other authorization, to find all available actions.
|
983
|
+
|
984
|
+
- A datatable `app/datatables/things_datatable.rb`:
|
985
|
+
|
986
|
+
```ruby
|
987
|
+
class ThingsDatatable < Effective::Datatable
|
988
|
+
datatable do
|
989
|
+
col :title
|
990
|
+
col :description
|
991
|
+
actions_col
|
992
|
+
end
|
993
|
+
|
994
|
+
collection do
|
995
|
+
Thing.deep.all
|
996
|
+
end
|
997
|
+
end
|
998
|
+
```
|
999
|
+
|
1000
|
+
This is an ordinary datatable. As long as it's an ActiveRecord collection, inline crud will work.
|
1001
|
+
|
1002
|
+
- A view partial `app/views/things/_thing.html.haml`:
|
1003
|
+
|
1004
|
+
```ruby
|
1005
|
+
%table.table
|
1006
|
+
%tbody
|
1007
|
+
%tr
|
1008
|
+
%th Title
|
1009
|
+
%td= thing.title
|
1010
|
+
%tr
|
1011
|
+
%th Description
|
1012
|
+
%td= thing.description
|
1013
|
+
```
|
1014
|
+
|
1015
|
+
This file is what rails uses when you call `render(thing)` and what datatables uses for the inline `show` action. It's important that its called `_thing.html`.
|
1016
|
+
|
1017
|
+
- A form partial `app/views/things/_form.html.haml`:
|
1018
|
+
|
1019
|
+
```ruby
|
1020
|
+
= effective_form_with(model: thing) do |f|
|
1021
|
+
= f.text_field :title
|
1022
|
+
= f.text_area :description
|
1023
|
+
= f.submit
|
1024
|
+
```
|
1025
|
+
|
1026
|
+
The `effective_form_with` comes from [effective_bootstrap](https://github.com/code-and-effect/effective_bootstrap) gem and is a drop-in replacement for the newer `form_with` syntax. It's really good, you should use it, but an ordinary `form_with` will work here just fine.
|
1027
|
+
|
1028
|
+
This `_form.html` is an effective gems convention. This file must exist for your resource.
|
1029
|
+
|
1030
|
+
- A resources entry in `config/routes.rb`:
|
1031
|
+
|
1032
|
+
```ruby
|
1033
|
+
Rails.application.routes.draw do
|
1034
|
+
resources :things do
|
1035
|
+
post :approve, on: :member
|
1036
|
+
post :reject, on: :member
|
1037
|
+
end
|
1038
|
+
end
|
1039
|
+
```
|
1040
|
+
|
1041
|
+
Above we have `resources :things` for the 7 crud actions. And we add two more member actions, which datatables will call `approve!` or `reject!` on thing.
|
1042
|
+
|
1043
|
+
|
1044
|
+
4. Render in the view. Create an `app/views/things/index.html.haml` and call `render_datatable(@datatable, inline: true)` or `render_inline_datatable(@datatable).
|
1045
|
+
|
1046
|
+
```ruby
|
1047
|
+
= render_datatable(@datatable, inline: true)
|
1048
|
+
```
|
1049
|
+
|
1050
|
+
Your datatable should now have New, Show, Edit, Approve and Reject buttons. Click them for inline functionality.
|
1051
|
+
|
1052
|
+
## Troubleshooting Inline
|
1053
|
+
|
1054
|
+
If things aren't working, try the following:
|
1055
|
+
|
1056
|
+
- Double check your javascripts:
|
1057
|
+
|
1058
|
+
```ruby
|
1059
|
+
//= require jquery3
|
1060
|
+
//= require popper
|
1061
|
+
//= require bootstrap
|
1062
|
+
//= require effective_bootstrap
|
1063
|
+
//= require effective_datatables
|
1064
|
+
//= require jquery_ujs
|
1065
|
+
```
|
1066
|
+
|
1067
|
+
The inline functionality requires one of sprockets jquery_ujs, sprockets rails_ujs or webpack @rails/ujs libraries.
|
1068
|
+
|
1069
|
+
- Double check your stylesheets:
|
1070
|
+
|
1071
|
+
```ruby
|
1072
|
+
@import 'bootstrap';
|
1073
|
+
@import 'effective_bootstrap';
|
1074
|
+
@import 'effective_datatables';
|
1075
|
+
```
|
1076
|
+
|
1077
|
+
- Make sure your datatable is not being rendered inside a `<form>...</form>` tag. It will display a javascript console error and won't work.
|
1078
|
+
|
1079
|
+
- Double check your `resources :things` are in `routes.rb` in the same namespace as the controller, and that you have authorization for those actions in `ability.rb` or whatever your `config/initializers/effective_datatables.rb` `config.authorization_method` returns.
|
1080
|
+
|
1081
|
+
## A note on how it works
|
1082
|
+
|
1083
|
+
We use good old `rails_ujs` for all inline actions.
|
1084
|
+
|
1085
|
+
When inline, any of the actions_col actions, as well as the New button, will be changed into `data-remote: true` actions.
|
1086
|
+
|
1087
|
+
The [inline_crud javascript](https://github.com/code-and-effect/effective_datatables/blob/master/app/assets/javascripts/effective_datatables/inline_crud.js.coffee) handles fetching the form, or view partial and expanding/collapsing the appropriate row of the datatable.
|
1088
|
+
|
1089
|
+
When an inline action is clicked, effective_datatables will make an AJAX request to the server, which could be received by an `Effective::CrudController` that will handle the `.js` format, and respond_with the appropriate [rails_ujs .js.erb views](https://github.com/code-and-effect/effective_resources/tree/master/app/views/application).
|
1090
|
+
|
1091
|
+
|
1092
|
+
# Extras
|
934
1093
|
|
935
1094
|
The following commands don't quite fit into the DSL, but are present nonetheless.
|
936
1095
|
|
937
|
-
|
1096
|
+
## simple
|
938
1097
|
|
939
1098
|
To render a simple table, without pagination, sorting, filtering, export buttons, per page, and default visibility:
|
940
1099
|
|
@@ -942,7 +1101,7 @@ To render a simple table, without pagination, sorting, filtering, export buttons
|
|
942
1101
|
<%= render_datatable(@datatable, simple: true) %>
|
943
1102
|
```
|
944
1103
|
|
945
|
-
|
1104
|
+
## index
|
946
1105
|
|
947
1106
|
If you just want to render a datatable and nothing else, there is a quick way to skip creating a view:
|
948
1107
|
|
@@ -956,13 +1115,13 @@ end
|
|
956
1115
|
|
957
1116
|
will render `views/effective/datatables/index` with the assigned datatable.
|
958
1117
|
|
959
|
-
|
1118
|
+
# Advanced Search and Sort
|
960
1119
|
|
961
1120
|
The built-in search and ordering can be overridden on a per-column basis.
|
962
1121
|
|
963
1122
|
The only gotcha here is that you must be aware of the type of collection.
|
964
1123
|
|
965
|
-
|
1124
|
+
## With ActiveRecord collection
|
966
1125
|
|
967
1126
|
In the case of a `col` and an ActiveRecord collection:
|
968
1127
|
|
@@ -994,7 +1153,7 @@ If `column[:sql_column].blank?` then this `col` has fallen back to being a `val`
|
|
994
1153
|
|
995
1154
|
Try adding `col :post_category, sql_column: 'post_categories.title'`
|
996
1155
|
|
997
|
-
|
1156
|
+
## With Array collection
|
998
1157
|
|
999
1158
|
And in the case of a `col` with an Array collection, or any `val`:
|
1000
1159
|
|
@@ -1033,7 +1192,7 @@ end
|
|
1033
1192
|
|
1034
1193
|
The search and sort for each column will be merged together to form the final results.
|
1035
1194
|
|
1036
|
-
|
1195
|
+
## Default search collection
|
1037
1196
|
|
1038
1197
|
When using a `col :comments` type belongs_to or has_many column, a search collection for that class will be loaded.
|
1039
1198
|
|
@@ -1155,6 +1314,22 @@ def finalize(collection)
|
|
1155
1314
|
end
|
1156
1315
|
```
|
1157
1316
|
|
1317
|
+
## Render outside of view
|
1318
|
+
|
1319
|
+
You can render a datatable outside the view.
|
1320
|
+
|
1321
|
+
Anything you pass to the `rendered` method is treated as view/request params.
|
1322
|
+
|
1323
|
+
You can test filters and scopes by passing them here.
|
1324
|
+
|
1325
|
+
```
|
1326
|
+
post = Post.create!
|
1327
|
+
datatable = PostsDatatable.new.rendered(end_date: Time.zone.now+2.days, current_user_id: 1)
|
1328
|
+
|
1329
|
+
assert_equal 1, datatable.collection.count
|
1330
|
+
assert_equal [post], datatable.collection
|
1331
|
+
```
|
1332
|
+
|
1158
1333
|
## Authorization
|
1159
1334
|
|
1160
1335
|
All authorization checks are handled via the config.authorization_method found in the `config/initializers/effective_datatables.rb` file.
|
@@ -16,7 +16,7 @@ flash = (message, status = '') ->
|
|
16
16
|
timeout = $processing.data('timeout')
|
17
17
|
clearTimeout(timeout) if timeout
|
18
18
|
|
19
|
-
delay = (if status == 'danger' then 4000 else
|
19
|
+
delay = (if status == 'danger' then 4000 else 1000)
|
20
20
|
|
21
21
|
$processing.html(message).data('timeout', setTimeout( =>
|
22
22
|
$processing.html('Processing...')
|
@@ -5,6 +5,9 @@ initializeDataTables = (target) ->
|
|
5
5
|
buttons_export_columns = options['buttons_export_columns'] || ':not(.col-actions)'
|
6
6
|
reorder = datatable.data('reorder')
|
7
7
|
|
8
|
+
if datatable.data('inline') && datatable.closest('form').length > 0
|
9
|
+
console.error('inline datatable cannot work inside a form')
|
10
|
+
|
8
11
|
if options['buttons'] == false
|
9
12
|
options['buttons'] = []
|
10
13
|
|
@@ -49,7 +52,7 @@ initializeDataTables = (target) ->
|
|
49
52
|
displayStart: datatable.data('display-start')
|
50
53
|
iDisplayLength: datatable.data('display-length')
|
51
54
|
language: datatable.data('language')
|
52
|
-
lengthMenu: [[5, 10, 25, 50, 100, 250, 500, 9999999], ['5', '10', '25', '50', '100', '250', '500', '
|
55
|
+
lengthMenu: [[5, 10, 25, 50, 100, 250, 500, 9999999], ['5', '10', '25', '50', '100', '250', '500', datatable.data('all-label')]]
|
53
56
|
order: datatable.data('display-order')
|
54
57
|
processing: true
|
55
58
|
responsive: true
|
@@ -77,7 +80,7 @@ initializeDataTables = (target) ->
|
|
77
80
|
filter_name = name.replace('filters[', '').substring(0, name.length-9)
|
78
81
|
|
79
82
|
params['filter'][filter_name] = $form.find("input[name='#{name}']:checked").val()
|
80
|
-
|
83
|
+
|
81
84
|
else if $input.attr('id')
|
82
85
|
filter_name = $input.attr('id').replace('filters_', '')
|
83
86
|
params['filter'][filter_name] = $input.val()
|
@@ -162,7 +165,6 @@ initializeDataTables = (target) ->
|
|
162
165
|
$input.on 'change', (event) -> dataTableSearch($(event.currentTarget))
|
163
166
|
else if $input.is('input')
|
164
167
|
$input.delayedChange ($input) -> dataTableSearch($input)
|
165
|
-
$input.on('paste', -> dataTableSearch($input))
|
166
168
|
|
167
169
|
# Do the actual search
|
168
170
|
dataTableSearch = ($input) -> # This is the function called by a select or input to run the search
|
@@ -172,7 +174,9 @@ initializeDataTables = (target) ->
|
|
172
174
|
|
173
175
|
value = $input.val()
|
174
176
|
|
175
|
-
if
|
177
|
+
if Array.isArray(value)
|
178
|
+
# Nothing
|
179
|
+
else if value.startsWith('"') && value.endsWith('"')
|
176
180
|
value = value.substring(1, value.length-1)
|
177
181
|
else
|
178
182
|
value = $.trim(value)
|
@@ -196,6 +200,7 @@ initializeDataTables = (target) ->
|
|
196
200
|
|
197
201
|
table.addClass('initialized')
|
198
202
|
table.children('thead').trigger('effective-bootstrap:initialize')
|
203
|
+
table.children('thead').find('input[autofocus]').first().focus()
|
199
204
|
true
|
200
205
|
|
201
206
|
destroyDataTables = ->
|
@@ -1,15 +1,34 @@
|
|
1
1
|
# To achieve inline crud, we use rails' data-remote links, and override their behaviour when inside a datatable
|
2
2
|
# This works with EffectiveForm.remote_form which is part of the effective_bootstrap gem.
|
3
3
|
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# https://github.com/rails/jquery-ujs/wiki/ajax
|
5
|
+
# https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
|
6
|
+
|
7
|
+
$(document).on 'ajax:before', '.dataTables_wrapper .col-actions', (event) ->
|
8
|
+
$action = $(event.target)
|
9
|
+
$table = $(event.target).closest('table')
|
8
10
|
|
9
11
|
return true if ('' + $action.data('inline')) == 'false'
|
10
12
|
|
11
|
-
$params = $.param(
|
12
|
-
|
13
|
+
$params = $.param(
|
14
|
+
{
|
15
|
+
_datatable_id: $table.attr('id'),
|
16
|
+
_datatable_attributes: $table.data('attributes'),
|
17
|
+
_datatable_action: true
|
18
|
+
}
|
19
|
+
)
|
20
|
+
|
21
|
+
$action.attr('data-params', $params)
|
22
|
+
true
|
23
|
+
|
24
|
+
# We click the New/Edit/Action button from the col-actions
|
25
|
+
$(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-actions', (event, xhr, settings) ->
|
26
|
+
[xhr, settings] = event.detail if event.detail # rails/ujs
|
27
|
+
|
28
|
+
$action = $(event.target)
|
29
|
+
$table = $(event.target).closest('table')
|
30
|
+
|
31
|
+
return true if ('' + $action.data('inline')) == 'false'
|
13
32
|
|
14
33
|
if $action.closest('.effective-datatables-inline-row,table.dataTable').hasClass('effective-datatables-inline-row')
|
15
34
|
# Nothing.
|
@@ -22,6 +41,8 @@ $(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-actions', (e, xhr, s
|
|
22
41
|
|
23
42
|
# We have either completed the resource action, or fetched the inline form to load.
|
24
43
|
$(document).on 'ajax:success', '.dataTables_wrapper .col-actions', (event, data) ->
|
44
|
+
[data, status, xhr] = event.detail if event.detail # rails/ujs
|
45
|
+
|
25
46
|
$action = $(event.target)
|
26
47
|
|
27
48
|
return true if ('' + $action.data('inline')) == 'false'
|
@@ -54,12 +75,22 @@ $(document).on 'ajax:error', '.dataTables_wrapper', (event) ->
|
|
54
75
|
EffectiveForm.remote_form_flash = ''
|
55
76
|
true
|
56
77
|
|
57
|
-
|
58
|
-
|
59
|
-
|
78
|
+
## Now for the fetched form. We add the datatables params attributes
|
79
|
+
|
80
|
+
$(document).on 'ajax:before', '.dataTables_wrapper .col-inline-form', (event) ->
|
81
|
+
$action = $(event.target)
|
82
|
+
$form = $action.closest('form')
|
83
|
+
$table = $action.closest('table')
|
84
|
+
|
85
|
+
if $form.find('input[name=_datatable_id]').length == 0
|
86
|
+
$('<input>').attr(
|
87
|
+
{type: 'hidden', name: '_datatable_id', value: $table.attr('id')}
|
88
|
+
).appendTo($form)
|
60
89
|
|
61
|
-
|
62
|
-
|
90
|
+
if $form.find('input[name=_datatable_attributes]').length == 0
|
91
|
+
$('<input>').attr(
|
92
|
+
{type: 'hidden', name: '_datatable_attributes', value: $table.data('attributes')}
|
93
|
+
).appendTo($form)
|
63
94
|
|
64
95
|
true
|
65
96
|
|
@@ -92,7 +123,6 @@ beforeNew = ($action) ->
|
|
92
123
|
|
93
124
|
# Append spinner and show Processing
|
94
125
|
$th.append($table.data('spinner'))
|
95
|
-
$table.DataTable().flash()
|
96
126
|
$table.one 'draw.dt', (event) ->
|
97
127
|
$th.find('a').show().siblings('svg').remove() if event.target == event.currentTarget
|
98
128
|
|
@@ -121,7 +151,6 @@ beforeEdit = ($action) ->
|
|
121
151
|
|
122
152
|
# Append spinner and show Processing
|
123
153
|
$td.append($table.data('spinner'))
|
124
|
-
$table.DataTable().flash()
|
125
154
|
|
126
155
|
afterEdit = ($action) ->
|
127
156
|
$tr = $action.closest('tr')
|
@@ -8,7 +8,14 @@ reorder = (event, diff, edit) ->
|
|
8
8
|
return unless oldNode? && newNode?
|
9
9
|
|
10
10
|
url = @context[0].ajax.url.replace('.json', '/reorder.json')
|
11
|
-
|
11
|
+
|
12
|
+
data = {
|
13
|
+
'authenticity_token': $('head').find("meta[name='csrf-token']").attr('content'),
|
14
|
+
'reorder[id]': oldNode.data('reorder-resource'),
|
15
|
+
'reorder[old]': oldNode.val(),
|
16
|
+
'reorder[new]': newNode.val(),
|
17
|
+
'attributes': $table.data('attributes')
|
18
|
+
}
|
12
19
|
|
13
20
|
@context[0].rowreorder.c.enable = false
|
14
21
|
|
@@ -40,4 +47,3 @@ $(document).on 'click', '.dataTables_wrapper a.buttons-reorder', (event) ->
|
|
40
47
|
$table.addClass('reordering')
|
41
48
|
|
42
49
|
column.visible(!column.visible())
|
43
|
-
|
@@ -162,9 +162,7 @@ div.dataTables_scrollFoot > .dataTables_scrollFootInner > table {
|
|
162
162
|
text-align: center;
|
163
163
|
}
|
164
164
|
}
|
165
|
-
|
166
|
-
padding-right: 20px;
|
167
|
-
}
|
165
|
+
|
168
166
|
table.dataTable.table-sm .sorting:before,
|
169
167
|
table.dataTable.table-sm .sorting_asc:before,
|
170
168
|
table.dataTable.table-sm .sorting_desc:before {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# These are expected to be called by a developer. They are part of the datatables DSL.
|
2
2
|
module EffectiveDatatablesHelper
|
3
|
-
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, pagination: true, search: true, simple: false, sort: true)
|
3
|
+
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, namespace: nil, pagination: true, search: true, simple: false, sort: true)
|
4
4
|
raise 'expected datatable to be present' unless datatable
|
5
5
|
raise 'expected input_js to be a Hash' unless input_js.kind_of?(Hash)
|
6
6
|
|
@@ -10,6 +10,7 @@ module EffectiveDatatablesHelper
|
|
10
10
|
|
11
11
|
datatable.attributes[:inline] = true if inline
|
12
12
|
datatable.attributes[:sortable] = false unless sort
|
13
|
+
datatable.attributes[:namespace] = namespace if namespace
|
13
14
|
|
14
15
|
datatable.view ||= self
|
15
16
|
|
@@ -40,6 +41,7 @@ module EffectiveDatatablesHelper
|
|
40
41
|
id: datatable.to_param,
|
41
42
|
class: html_class,
|
42
43
|
data: {
|
44
|
+
'all-label' => I18n.t('effective_datatables.all'),
|
43
45
|
'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
|
44
46
|
'authenticity-token' => form_authenticity_token,
|
45
47
|
'bulk-actions' => datatable_bulk_actions(datatable),
|
@@ -44,7 +44,7 @@ module EffectiveDatatablesPrivateHelper
|
|
44
44
|
action = { action: :new, class: ['btn', column[:btn_class].presence].compact.join(' '), 'data-remote': true }
|
45
45
|
|
46
46
|
if column[:actions][:new].kind_of?(Hash) # This might be active_record_array_collection?
|
47
|
-
action
|
47
|
+
action.merge!(column[:actions][:new])
|
48
48
|
|
49
49
|
effective_resource = (datatable.effective_resource || datatable.fallback_effective_resource)
|
50
50
|
klass = (column[:actions][:new][:klass] || effective_resource&.klass || datatable.collection_class)
|
@@ -84,7 +84,7 @@ module EffectiveDatatablesPrivateHelper
|
|
84
84
|
collection = opts[:search].delete(:collection)
|
85
85
|
value = datatable.state[:search][name]
|
86
86
|
|
87
|
-
options = opts[:search].
|
87
|
+
options = opts[:search].merge!(
|
88
88
|
name: nil,
|
89
89
|
feedback: false,
|
90
90
|
label: false,
|
@@ -92,24 +92,26 @@ module EffectiveDatatablesPrivateHelper
|
|
92
92
|
data: { 'column-name': name, 'column-index': opts[:index] }
|
93
93
|
)
|
94
94
|
|
95
|
+
options.delete(:fuzzy)
|
96
|
+
|
95
97
|
case options.delete(:as)
|
96
98
|
when :string, :text, :number
|
97
99
|
form.text_field name, options
|
98
100
|
when :date, :datetime
|
99
|
-
form.date_field name, options.reverse_merge(
|
101
|
+
form.date_field name, options.reverse_merge!(
|
100
102
|
date_linked: false, prepend: false, input_js: { useStrict: true, keepInvalid: true }
|
101
103
|
)
|
102
104
|
when :time
|
103
|
-
form.time_field name, options.reverse_merge(
|
105
|
+
form.time_field name, options.reverse_merge!(
|
104
106
|
date_linked: false, prepend: false, input_js: { useStrict: false, keepInvalid: true }
|
105
107
|
)
|
106
108
|
when :select, :boolean
|
107
|
-
options[:input_js] = (options[:input_js] || {}).reverse_merge(placeholder: '')
|
109
|
+
options[:input_js] = (options[:input_js] || {}).reverse_merge!(placeholder: '')
|
108
110
|
|
109
111
|
form.select name, collection, options
|
110
112
|
when :bulk_actions
|
111
113
|
options[:data]['role'] = 'bulk-actions'
|
112
|
-
form.check_box name, options.merge(label: ' ')
|
114
|
+
form.check_box name, options.merge!(label: ' ')
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
@@ -139,7 +141,7 @@ module EffectiveDatatablesPrivateHelper
|
|
139
141
|
placeholder: (opts[:label] || name.to_s.titleize),
|
140
142
|
value: value,
|
141
143
|
wrapper: { class: 'form-group col-auto'}
|
142
|
-
}.merge(opts.except(:as, :collection, :parse, :value))
|
144
|
+
}.merge!(opts.except(:as, :collection, :parse, :value))
|
143
145
|
|
144
146
|
options[:name] = '' unless datatable._filters_form_required?
|
145
147
|
|
@@ -149,6 +151,8 @@ module EffectiveDatatablesPrivateHelper
|
|
149
151
|
elsif as == :boolean
|
150
152
|
collection ||= [true, false].map { |value| [t("effective_datatables.boolean_#{value}"), value] }
|
151
153
|
form.public_send(:select, name, collection, options) # boolean
|
154
|
+
elsif as == :string
|
155
|
+
form.public_send(:text_field, name, options)
|
152
156
|
elsif form.respond_to?(as)
|
153
157
|
form.public_send(as, name, options) # check_box, text_area
|
154
158
|
else
|
@@ -169,7 +173,7 @@ module EffectiveDatatablesPrivateHelper
|
|
169
173
|
label: false,
|
170
174
|
required: false,
|
171
175
|
wrapper: { class: 'form-group col-auto'}
|
172
|
-
}.merge(opts.except(:checked, :value))
|
176
|
+
}.merge!(opts.except(:checked, :value))
|
173
177
|
|
174
178
|
form.radios :scope, collection, options
|
175
179
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Effective
|
2
2
|
class Datatable
|
3
3
|
attr_reader :attributes # Anything that we initialize our table with. That's it. Can't be changed by state.
|
4
|
-
attr_reader :effective_resource
|
5
4
|
attr_reader :state
|
5
|
+
attr_accessor :effective_resource
|
6
6
|
|
7
7
|
# Hashes of DSL options
|
8
8
|
attr_reader :_aggregates
|
@@ -53,10 +53,36 @@ module Effective
|
|
53
53
|
self.view = view if view
|
54
54
|
end
|
55
55
|
|
56
|
+
def rendered(params = {})
|
57
|
+
raise('expected a hash of params') unless params.kind_of?(Hash)
|
58
|
+
|
59
|
+
view = ApplicationController.renderer.controller.helpers
|
60
|
+
|
61
|
+
view.class_eval do
|
62
|
+
attr_accessor :rendered_params
|
63
|
+
|
64
|
+
def current_user
|
65
|
+
rendered_params[:current_user]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if params[:current_user_id]
|
70
|
+
params[:current_user] = User.find(params[:current_user_id])
|
71
|
+
end
|
72
|
+
|
73
|
+
view.rendered_params = params
|
74
|
+
|
75
|
+
self.view = view
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
56
79
|
# Once the view is assigned, we initialize everything
|
57
80
|
def view=(view)
|
58
81
|
@view = (view.respond_to?(:view_context) ? view.view_context : view)
|
59
|
-
|
82
|
+
|
83
|
+
unless @view.respond_to?(:params) || @view.respond_to?(:rendered_params)
|
84
|
+
raise 'expected view to respond to params'
|
85
|
+
end
|
60
86
|
|
61
87
|
assert_attributes!
|
62
88
|
load_attributes!
|
@@ -10,6 +10,7 @@ module Effective
|
|
10
10
|
|
11
11
|
def load_cookie!
|
12
12
|
return unless EffectiveDatatables.save_state
|
13
|
+
return unless view.respond_to?(:cookies)
|
13
14
|
|
14
15
|
@dt_cookie = view.cookies.signed['_effective_dt']
|
15
16
|
|
@@ -33,6 +34,7 @@ module Effective
|
|
33
34
|
|
34
35
|
def save_cookie!
|
35
36
|
return unless EffectiveDatatables.save_state
|
37
|
+
return unless view.respond_to?(:cookies)
|
36
38
|
|
37
39
|
@dt_cookie ||= []
|
38
40
|
@dt_cookie << [cookie_key, cookie_payload]
|
@@ -16,7 +16,7 @@ module Effective
|
|
16
16
|
next unless state[:visible][name]
|
17
17
|
|
18
18
|
if opts[:partial]
|
19
|
-
locals = { datatable: self, column: opts }.merge(resource_col_locals(opts))
|
19
|
+
locals = { datatable: self, column: opts }.merge!(resource_col_locals(opts))
|
20
20
|
|
21
21
|
rendered[name] = (view.render(
|
22
22
|
partial: opts[:partial],
|
@@ -27,7 +27,6 @@ module Effective
|
|
27
27
|
spacer_template: SPACER_TEMPLATE
|
28
28
|
) || '').split(SPACER)
|
29
29
|
elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something'
|
30
|
-
resources = collection.map { |row| row[opts[:index]] }
|
31
30
|
locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE }
|
32
31
|
|
33
32
|
atts = {
|
@@ -36,16 +35,17 @@ module Effective
|
|
36
35
|
effective_resource: effective_resource,
|
37
36
|
locals: locals,
|
38
37
|
partial: opts[:actions_partial],
|
39
|
-
}.
|
38
|
+
}.merge!(opts[:actions]).tap(&:compact!)
|
40
39
|
|
41
40
|
rendered[name] = if effective_resource.blank?
|
42
|
-
|
41
|
+
collection.map { |row| row[opts[:index]] }.map do |resource|
|
43
42
|
polymorphic_resource = Effective::Resource.new(resource, namespace: controller_namespace)
|
44
43
|
(view.render_resource_actions(resource, atts.merge(effective_resource: polymorphic_resource), &opts[:format]) || '')
|
45
44
|
end
|
46
45
|
else
|
47
|
-
(view.render_resource_actions(
|
46
|
+
(view.render_resource_actions(collection.map { |row| row[opts[:index]] }, atts, &opts[:format]) || '').split(SPACER)
|
48
47
|
end
|
48
|
+
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -88,9 +88,9 @@ module Effective
|
|
88
88
|
when :currency
|
89
89
|
view.number_to_currency(value)
|
90
90
|
when :date
|
91
|
-
(value.strftime(
|
91
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_date) : BLANK
|
92
92
|
when :datetime
|
93
|
-
(value.strftime(
|
93
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_datetime) : BLANK
|
94
94
|
when :decimal
|
95
95
|
value
|
96
96
|
when :duration
|
@@ -116,7 +116,7 @@ module Effective
|
|
116
116
|
when Numeric ; view.number_to_currency(value)
|
117
117
|
end
|
118
118
|
when :time
|
119
|
-
(value.strftime(
|
119
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_time) : BLANK
|
120
120
|
else
|
121
121
|
value.to_s
|
122
122
|
end
|
@@ -135,7 +135,7 @@ module Effective
|
|
135
135
|
end
|
136
136
|
|
137
137
|
# Merge local options. Special behaviour for remote: false
|
138
|
-
if column[:actions].
|
138
|
+
if column[:actions].present? && column[:actions].kind_of?(Hash)
|
139
139
|
column[:actions].each do |action, opts|
|
140
140
|
next unless opts.kind_of?(Hash)
|
141
141
|
|
@@ -6,18 +6,23 @@ module Effective
|
|
6
6
|
|
7
7
|
def datatables_ajax_request?
|
8
8
|
return @_datatables_ajax_request unless @_datatables_ajax_request.nil?
|
9
|
+
return unless view.respond_to?(:params)
|
9
10
|
|
10
11
|
@_datatables_ajax_request = (view.present? && view.params.key?(:draw) && view.params.key?(:columns))
|
11
12
|
end
|
12
13
|
|
13
14
|
def datatables_inline_request?
|
14
15
|
return @_datatables_inline_request unless @_datatables_inline_request.nil?
|
16
|
+
return unless view.respond_to?(:params)
|
15
17
|
|
16
18
|
@_datatables_inline_request = (view.present? && view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1])
|
17
19
|
end
|
18
20
|
|
19
21
|
def params
|
20
22
|
return {} unless view.present?
|
23
|
+
return view.rendered_params if view.respond_to?(:rendered_params)
|
24
|
+
return {} unless view.respond_to?(:request)
|
25
|
+
|
21
26
|
@params ||= {}.tap do |params|
|
22
27
|
Rack::Utils.parse_query(URI(view.request.referer.presence || '/').query).each { |k, v| params[k.to_sym] = v }
|
23
28
|
view.params.each { |k, v| params[k.to_sym] = v }
|
@@ -4,7 +4,7 @@ module Effective
|
|
4
4
|
AGGREGATE_SQL_FUNCTIONS = ['ARRAY_AGG(', 'AVG(', 'COUNT(', 'MAX(', 'MIN(', 'STRING_AGG(', 'SUM(']
|
5
5
|
|
6
6
|
def admin_namespace?
|
7
|
-
|
7
|
+
[:admin, 'admin'].include?(controller_namespace)
|
8
8
|
end
|
9
9
|
|
10
10
|
def controller_namespace
|
@@ -31,7 +31,7 @@ module Effective
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def load_effective_resource!
|
34
|
-
@effective_resource
|
34
|
+
@effective_resource ||= if active_record_collection?
|
35
35
|
Effective::Resource.new(collection_class, namespace: controller_namespace)
|
36
36
|
end
|
37
37
|
end
|
@@ -98,9 +98,11 @@ module Effective
|
|
98
98
|
opts[:sql_as_column] = true if (effective_resource.table && effective_resource.column(name).blank?)
|
99
99
|
end
|
100
100
|
|
101
|
-
if opts[:sql_column].present?
|
102
|
-
opts[:
|
101
|
+
if opts[:sql_column].present?
|
102
|
+
sql_column = opts[:sql_column].to_s
|
103
|
+
opts[:sql_as_column] = true if AGGREGATE_SQL_FUNCTIONS.any? { |str| sql_column.start_with?(str) }
|
103
104
|
end
|
105
|
+
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
@@ -200,6 +202,7 @@ module Effective
|
|
200
202
|
|
201
203
|
def load_resource_belongs_tos!
|
202
204
|
return unless active_record_collection?
|
205
|
+
return unless @_collection_apply_belongs_to
|
203
206
|
|
204
207
|
changed = attributes.select do |attribute, value|
|
205
208
|
attribute = attribute.to_s
|
@@ -210,7 +213,7 @@ module Effective
|
|
210
213
|
next unless columns[associated]
|
211
214
|
|
212
215
|
if columns[associated][:as] == :belongs_to
|
213
|
-
|
216
|
+
unless @_collection.where_values_hash.include?(attribute)
|
214
217
|
@_collection = @_collection.where(attribute => value)
|
215
218
|
end
|
216
219
|
|
@@ -218,10 +221,8 @@ module Effective
|
|
218
221
|
elsif columns[associated][:as] == :belongs_to_polymorphic
|
219
222
|
associated_type = attributes["#{associated}_type".to_sym] || raise("Expected #{associated}_type attribute to be present when #{associated}_id is present on a polymorphic belongs to")
|
220
223
|
|
221
|
-
|
222
|
-
|
223
|
-
@_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
|
224
|
-
end
|
224
|
+
unless @_collection.where_values_hash.include?(attribute) || @_collection.where_values_hash.include?("#{associated}_type")
|
225
|
+
@_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
|
225
226
|
end
|
226
227
|
|
227
228
|
columns.delete(associated)
|
@@ -198,7 +198,7 @@ module Effective
|
|
198
198
|
def parse_filter_value(filter, value)
|
199
199
|
return filter[:parse].call(value) if filter[:parse]
|
200
200
|
return nil if value.blank? && !filter[:required]
|
201
|
-
Effective::Attribute.new(filter[:value]).parse(value, name: filter[:name])
|
201
|
+
Effective::Attribute.new(filter[:as] || filter[:value] || :string).parse(value, name: filter[:name])
|
202
202
|
end
|
203
203
|
|
204
204
|
def cookie_state_params
|
@@ -1,4 +1,4 @@
|
|
1
1
|
- Array(resource.public_send(column[:name])).each do |file|
|
2
2
|
.col-resource_item
|
3
3
|
- title = [file.content_type, number_to_human_size(file.byte_size)].map(&:presence).compact
|
4
|
-
= link_to(file.filename, url_for(file), title: title)
|
4
|
+
= link_to(file.filename, url_for(file), title: title, target: '_blank')
|
@@ -1,8 +1,9 @@
|
|
1
1
|
.btn-group.buttons-bulk-actions
|
2
2
|
%button.btn.btn-link.btn-sm.dropdown-toggle{'type': 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false, 'disabled': 'disabled'}
|
3
|
-
|
3
|
+
= t('effective_datatables.bulk_actions')
|
4
4
|
.dropdown-menu
|
5
5
|
- if datatable._bulk_actions.present?
|
6
6
|
= datatable._bulk_actions.join.html_safe
|
7
7
|
- else
|
8
|
-
%a.dropdown-item{href: '#'}
|
8
|
+
%a.dropdown-item{href: '#'}
|
9
|
+
= t('effective_datatables.no_bulk_actions')
|
@@ -35,8 +35,12 @@ EffectiveDatatables.setup do |config|
|
|
35
35
|
config.save_state = true
|
36
36
|
|
37
37
|
# Configure the _effective_dt cookie.
|
38
|
-
config.cookie_max_size =
|
38
|
+
config.cookie_max_size = 1500 # String size. Final byte size is about 1.5 times bigger, after rails signs it
|
39
39
|
config.cookie_domain = :all # Should usually be :all
|
40
40
|
config.cookie_tld_length = nil # Leave nil to autodetect, or set to probably 2
|
41
41
|
|
42
|
+
# Date formatting
|
43
|
+
config.format_datetime = '%F %H:%M'
|
44
|
+
config.format_date = '%F'
|
45
|
+
config.format_time = '%H:%M'
|
42
46
|
end
|
data/config/locales/en.yml
CHANGED
data/config/locales/es.yml
CHANGED
data/config/locales/nl.yml
CHANGED
data/lib/effective_datatables.rb
CHANGED
@@ -16,6 +16,10 @@ module EffectiveDatatables
|
|
16
16
|
mattr_accessor :cookie_domain
|
17
17
|
mattr_accessor :cookie_tld_length
|
18
18
|
|
19
|
+
mattr_accessor :format_datetime
|
20
|
+
mattr_accessor :format_date
|
21
|
+
mattr_accessor :format_time
|
22
|
+
|
19
23
|
mattr_accessor :debug
|
20
24
|
|
21
25
|
alias_method :max_cookie_size, :cookie_max_size
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_datatables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.8.
|
4
|
+
version: 4.8.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -129,11 +129,9 @@ files:
|
|
129
129
|
- app/assets/stylesheets/effective_datatables.scss
|
130
130
|
- app/assets/stylesheets/effective_datatables/_overrides.bootstrap4.scss
|
131
131
|
- app/controllers/effective/datatables_controller.rb
|
132
|
-
- app/datatables/effective_style_guide_datatable.rb
|
133
132
|
- app/helpers/effective_datatables_controller_helper.rb
|
134
133
|
- app/helpers/effective_datatables_helper.rb
|
135
134
|
- app/helpers/effective_datatables_private_helper.rb
|
136
|
-
- app/models/effective/access_denied.rb
|
137
135
|
- app/models/effective/datatable.rb
|
138
136
|
- app/models/effective/datatable_column.rb
|
139
137
|
- app/models/effective/datatable_column_tool.rb
|
@@ -163,7 +161,6 @@ files:
|
|
163
161
|
- app/views/effective/datatables/_resource_column.html.haml
|
164
162
|
- app/views/effective/datatables/_spacer_template.html
|
165
163
|
- app/views/effective/datatables/index.html.haml
|
166
|
-
- app/views/effective/style_guide/_effective_datatables.html.haml
|
167
164
|
- config/effective_datatables.rb
|
168
165
|
- config/locales/en.yml
|
169
166
|
- config/locales/es.yml
|
@@ -178,7 +175,7 @@ homepage: https://github.com/code-and-effect/effective_datatables
|
|
178
175
|
licenses:
|
179
176
|
- MIT
|
180
177
|
metadata: {}
|
181
|
-
post_install_message:
|
178
|
+
post_install_message:
|
182
179
|
rdoc_options: []
|
183
180
|
require_paths:
|
184
181
|
- lib
|
@@ -193,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
190
|
- !ruby/object:Gem::Version
|
194
191
|
version: '0'
|
195
192
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
197
|
-
signing_key:
|
193
|
+
rubygems_version: 3.1.2
|
194
|
+
signing_key:
|
198
195
|
specification_version: 4
|
199
196
|
summary: Uniquely powerful server-side searching, sorting and filtering of any ActiveRecord
|
200
197
|
or Array collection as well as post-rendered content displayed as a frontend jQuery
|
@@ -1,45 +0,0 @@
|
|
1
|
-
class EffectiveStyleGuideDatatable < Effective::Datatable
|
2
|
-
datatable do
|
3
|
-
length 10
|
4
|
-
|
5
|
-
col :id
|
6
|
-
col :material, search: { collection: ['Stainless Steel', 'Copper', 'Cast Iron', 'Composite'] }
|
7
|
-
col :bowl, search: { collection: ['Single Bowl', 'Double Bowl', 'Triple Bowl'] }
|
8
|
-
col :name
|
9
|
-
col :date, as: :date
|
10
|
-
end
|
11
|
-
|
12
|
-
# Set the permission check to the same as Effective::StyleGuide
|
13
|
-
def collection_class
|
14
|
-
defined?(Effective::StyleGuide) ? Effective::StyleGuide : super
|
15
|
-
end
|
16
|
-
|
17
|
-
collection do
|
18
|
-
now = Time.zone.now
|
19
|
-
[
|
20
|
-
[1, 'Stainless Steel', 'Single Bowl', 'KOHLER Staccato', (now + 1.day)],
|
21
|
-
[2, 'Stainless Steel', 'Double Bowl', 'KOHLER Vault Undercounter', (now + 1.day)],
|
22
|
-
[3, 'Stainless Steel', 'Triple Bowl', 'KRAUS All-In-One', (now + 1.day)],
|
23
|
-
[4, 'Stainless Steel', 'Single Bowl', 'KOHLER Vault Dual Mount', (now + 1.day)],
|
24
|
-
[5, 'Stainless Steel', 'Single Bowl', 'KRAUS All-In-One Undermount', (now + 2.days)],
|
25
|
-
[6, 'Stainless Steel', 'Double Bowl', 'Glacier Bay All-in-One', (now + 2.days)],
|
26
|
-
[7, 'Stainless Steel', 'Single Bowl', 'Elkay Neptune', (now + 2.days)],
|
27
|
-
[8, 'Copper', 'Single Bowl', 'ECOSINKS Apron Front Dual Mount', (now + 2.days)],
|
28
|
-
[9, 'Copper', 'Double Bowl', 'ECOSINKS Dual Mount Front Hammered', (now + 2.days)],
|
29
|
-
[10, 'Copper', 'Triple Bowl', 'Glarier Bay Undermount', (now + 3.days)],
|
30
|
-
[11, 'Copper', 'Single Bowl', 'Whitehaus Undermount', (now + 3.days)],
|
31
|
-
[12, 'Copper', 'Double Bowl', 'Belle Foret Apron Front', (now + 3.days)],
|
32
|
-
[13, 'Copper', 'Double Bowl', 'Pegasus Dual Mount', (now + 3.days)],
|
33
|
-
[14, 'Cast Iron', 'Double Bowl', 'KOHLER Whitehaven', (now + 3.days)],
|
34
|
-
[15, 'Cast Iron', 'Triple Bowl', 'KOHLER Hartland', (now + 3.days)],
|
35
|
-
[16, 'Cast Iron', 'Single Bowl', 'KOHLER Cape Dory Undercounter', (now + 4.days)],
|
36
|
-
[17, 'Cast Iron', 'Double Bowl', 'KOLER Bakersfield', (now + 4.days)],
|
37
|
-
[18, 'Cast Iron', 'Double Bowl', 'American Standard Offset', (now + 4.days)],
|
38
|
-
[19, 'Cast Iron', 'Single Bowl', 'Brookfield Top', (now + 4.days)],
|
39
|
-
[20, 'Composite', 'Single Bowl', 'Blanco Diamond Undermount', (now + 5.days)],
|
40
|
-
[21, 'Composite', 'Double Bowl', 'Mont Blanc Waterbrook', (now + 5.days)],
|
41
|
-
[22, 'Composite', 'Triple Bowl', 'Pegasus Triple Mount', (now + 5.days)],
|
42
|
-
[23, 'Composite', 'Single Bowl', 'Swanstone Dual Mount', (now + 5.days)]
|
43
|
-
]
|
44
|
-
end
|
45
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
unless defined?(Effective::AccessDenied)
|
2
|
-
module Effective
|
3
|
-
class AccessDenied < StandardError
|
4
|
-
attr_reader :action, :subject
|
5
|
-
|
6
|
-
def initialize(message = nil, action = nil, subject = nil)
|
7
|
-
@message = message
|
8
|
-
@action = action
|
9
|
-
@subject = subject
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
@message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
= render_datatable(EffectiveStyleGuideDatatable.new)
|