effective_datatables 3.6.3 → 3.7.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/app/assets/javascripts/dataTables/locales/en.lang +33 -0
  4. data/app/assets/javascripts/dataTables/locales/es.lang +36 -0
  5. data/app/assets/javascripts/dataTables/locales/nl.lang +30 -0
  6. data/app/assets/javascripts/effective_datatables/filters.js.coffee +1 -0
  7. data/app/assets/javascripts/effective_datatables/flash.js.coffee +31 -0
  8. data/app/assets/javascripts/effective_datatables/initialize.js.coffee +41 -53
  9. data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +217 -0
  10. data/app/assets/javascripts/effective_datatables/overrides.js.coffee +7 -0
  11. data/app/assets/javascripts/effective_datatables/reorder.js.coffee +43 -0
  12. data/app/assets/javascripts/effective_datatables/reset.js.coffee +1 -1
  13. data/app/assets/stylesheets/effective_datatables/_overrides.scss +28 -0
  14. data/app/controllers/effective/datatables_controller.rb +39 -6
  15. data/app/datatables/effective_style_guide_datatable.rb +47 -0
  16. data/app/helpers/effective_datatables_helper.rb +49 -56
  17. data/app/helpers/effective_datatables_private_helper.rb +137 -11
  18. data/app/models/effective/datatable.rb +36 -16
  19. data/app/models/effective/datatable_column.rb +1 -0
  20. data/app/models/effective/datatable_value_tool.rb +20 -20
  21. data/app/models/effective/effective_datatable/attributes.rb +5 -13
  22. data/app/models/effective/effective_datatable/collection.rb +18 -3
  23. data/app/models/effective/effective_datatable/compute.rb +15 -6
  24. data/app/models/effective/effective_datatable/cookie.rb +19 -18
  25. data/app/models/effective/effective_datatable/dsl.rb +8 -3
  26. data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +16 -23
  27. data/app/models/effective/effective_datatable/dsl/datatable.rb +70 -28
  28. data/app/models/effective/effective_datatable/dsl/filters.rb +12 -4
  29. data/app/models/effective/effective_datatable/format.rb +1 -4
  30. data/app/models/effective/effective_datatable/params.rb +9 -4
  31. data/app/models/effective/effective_datatable/resource.rb +129 -74
  32. data/app/models/effective/effective_datatable/state.rb +30 -15
  33. data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +3 -5
  34. data/app/views/effective/datatables/_datatable.html.haml +3 -5
  35. data/app/views/effective/datatables/_filters.html.haml +4 -24
  36. data/app/views/effective/datatables/_reorder_column.html.haml +5 -0
  37. data/app/views/effective/style_guide/_effective_datatables.html.haml +1 -0
  38. data/config/effective_datatables.rb +8 -21
  39. data/config/locales/en.yml +12 -0
  40. data/config/locales/es.yml +12 -0
  41. data/config/locales/nl.yml +12 -0
  42. data/config/routes.rb +5 -4
  43. data/lib/effective_datatables.rb +49 -2
  44. data/lib/effective_datatables/engine.rb +4 -2
  45. data/lib/effective_datatables/version.rb +1 -1
  46. metadata +17 -5
  47. data/app/views/effective/datatables/_reset.html.haml +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 509cfa19dfd481e41030c2ba527e34b23b41fdd66485d53923317b43938e0f56
4
- data.tar.gz: bfb1dcae3e580fcf1795290cbb543a68f741b2442484289b23f50c421ae98153
3
+ metadata.gz: 63197015127b15c2f50203c0cd6b8fad50fd441cefed7bee38e7a1755dd3e131
4
+ data.tar.gz: e3615c89e3c8c3c0b89c107625d4e9c7ed4f75dc356b29bb16b929d6df4bddf7
5
5
  SHA512:
6
- metadata.gz: ea2b82022025d623e56b0b2b5425b2161dcc7ae4d7697cf46d132ca9216c217a555cf53d30bc47af88323ceb9dfaac42dbf9e97753a9114fb1742709f60aab51
7
- data.tar.gz: ee06ea290b341b2047676f5dd79de2165483f8522c05c6f438d920e94ddb85d9fef63ba4795c6539e10bfb6c7486db308597cdd87daa173358d2dcd7476103aa
6
+ metadata.gz: b3cfa114b29faca24afed1d84ebdc4276de6c802c2a2682dcf288541438127c15fd60f7897142ec13e89d0abdef3d719509aac5e0fce69d9fe0ca2c8f00d5de7
7
+ data.tar.gz: d296c07e31f1b00b8b94aaecfbda53612016a3fade4f0631078a0a2f33af79dc2ca64f1ef50a421b10c35d6c60b649da74a741927cede4603467bfe32cee4fe6
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2017 Code and Effect Inc.
1
+ Copyright 2019 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -0,0 +1,33 @@
1
+ /**
2
+ * English - this is the default DataTables ships with
3
+ * @name English
4
+ * @anchor English
5
+ * @author <a href="http://www.sprymedia.co.uk/">Allan Jardine</a>
6
+ */
7
+
8
+ {
9
+ "sEmptyTable": "No data available in table",
10
+ "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11
+ "sInfoEmpty": "Showing 0 to 0 of 0 entries",
12
+ "sInfoFiltered": "(filtered from _MAX_ total entries)",
13
+ "sInfoPostFix": "",
14
+ "sInfoThousands": ",",
15
+ "sLengthMenu": "&nbsp;with _MENU_ per page",
16
+ "sLoadingRecords": "Loading...",
17
+ "sProcessing": "Processing...",
18
+ "sSearch": "Search:",
19
+ "sZeroRecords": "No matching records found",
20
+ "oPaginate": {
21
+ "sFirst": "First",
22
+ "sLast": "Last",
23
+ "sNext": "Next",
24
+ "sPrevious": "Previous"
25
+ },
26
+ "oAria": {
27
+ "sSortAscending": ": activate to sort column ascending",
28
+ "sSortDescending": ": activate to sort column descending"
29
+ },
30
+ "buttons": {
31
+ "colvis": "Show / Hide"
32
+ }
33
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Spanish translation
3
+ * @name Spanish
4
+ * @anchor Spanish
5
+ * @author Giovanni Ariza, Aristobulo Gomez and Roberto Poo
6
+ */
7
+
8
+ {
9
+ "sProcessing": "Procesando...",
10
+ "sLengthMenu": "Mostrar _MENU_ registros",
11
+ "sZeroRecords": "No se encontraron resultados",
12
+ "sEmptyTable": "Ningún dato disponible en esta tabla =(",
13
+ "sInfo": "Mostrando registros del _START_ al _END_ de un total de _TOTAL_ registros",
14
+ "sInfoEmpty": "Mostrando registros del 0 al 0 de un total de 0 registros",
15
+ "sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
16
+ "sLengthMenu": "&nbsp; con _MENU_ por página",
17
+ "sInfoPostFix": "",
18
+ "sSearch": "Buscar:",
19
+ "sUrl": "",
20
+ "sInfoThousands": ",",
21
+ "sLoadingRecords": "Cargando...",
22
+ "oPaginate": {
23
+ "sFirst": "Primero",
24
+ "sLast": "Último",
25
+ "sNext": "Siguiente",
26
+ "sPrevious": "Anterior"
27
+ },
28
+ "oAria": {
29
+ "sSortAscending": ": Activar para ordenar la columna de manera ascendente",
30
+ "sSortDescending": ": Activar para ordenar la columna de manera descendente"
31
+ },
32
+ "buttons": {
33
+ "copy": "Copiar",
34
+ "colvis": "Mostrar/Ocultar"
35
+ }
36
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Dutch translation
3
+ * @name Dutch
4
+ * @anchor Dutch
5
+ * @author <a href="http://www.blikgooien.nl/">Erwin Kerk</a> and <i>ashwin</i>
6
+ */
7
+
8
+ {
9
+ "sProcessing": "Bezig...",
10
+ "sLengthMenu": "_MENU_ resultaten weergeven",
11
+ "sZeroRecords": "Geen resultaten gevonden",
12
+ "sInfo": "_START_ tot _END_ van _TOTAL_ resultaten",
13
+ "sInfoEmpty": "Geen resultaten om weer te geven",
14
+ "sInfoFiltered": " (gefilterd uit _MAX_ resultaten)",
15
+ "sInfoPostFix": "",
16
+ "sSearch": "Zoeken:",
17
+ "sEmptyTable": "Geen resultaten aanwezig in de tabel",
18
+ "sInfoThousands": ".",
19
+ "sLoadingRecords": "Een moment geduld aub - bezig met laden...",
20
+ "oPaginate": {
21
+ "sFirst": "Eerste",
22
+ "sLast": "Laatste",
23
+ "sNext": "Volgende",
24
+ "sPrevious": "Vorige"
25
+ },
26
+ "oAria": {
27
+ "sSortAscending": ": activeer om kolom oplopend te sorteren",
28
+ "sSortDescending": ": activeer om kolom aflopend te sorteren"
29
+ }
30
+ }
@@ -1,3 +1,4 @@
1
+ # Don't scope by .datatables_wrapper here, because it's out of the wrapper!
1
2
  $(document).on 'click', 'a[data-apply-effective-datatables-filters]', (event) ->
2
3
  event.preventDefault()
3
4
  $form = $(event.currentTarget).closest('.effective-datatables-filters')
@@ -0,0 +1,31 @@
1
+ flash = (message, status = '') ->
2
+ @context[0].oFeatures.bProcessing = false
3
+
4
+ message ||= 'Processing...'
5
+
6
+ if status == 'danger'
7
+ message = 'Error: ' + message
8
+
9
+ $processing = $(@table().node()).siblings('.dataTables_processing')
10
+
11
+ if status.length > 0
12
+ $processing.addClass("alert-#{status}")
13
+
14
+ $processing.html(message).show()
15
+
16
+ timeout = $processing.data('timeout')
17
+ clearTimeout(timeout) if timeout
18
+
19
+ delay = (if status == 'danger' then 4000 else 1500)
20
+
21
+ $processing.html(message).data('timeout', setTimeout( =>
22
+ $processing.html('Processing...')
23
+ $processing.removeClass('alert-success alert-info alert-warning alert-danger alert-error')
24
+ $processing.hide()
25
+ @context[0].oFeatures.bProcessing = true
26
+ , delay)
27
+ )
28
+
29
+ return @
30
+
31
+ $.fn.DataTable.Api.register('flash()', flash);
@@ -1,14 +1,12 @@
1
- initializeDataTables = ->
2
- $('table.effective-datatable').each ->
3
- return if $.fn.DataTable.fnIsDataTable(this)
4
-
1
+ initializeDataTables = (target) ->
2
+ $(target || document).find('table.effective-datatable:not(.initialized)').each ->
5
3
  datatable = $(this)
6
- input_js_options = datatable.data('input-js-options') || {}
7
- buttons_export_columns = input_js_options['buttons_export_columns'] || ':not(.col-actions)'
8
- simple = ('' + datatable.data('simple') == 'true')
4
+ options = datatable.data('options') || {}
5
+ buttons_export_columns = options['buttons_export_columns'] || ':not(.col-actions)'
6
+ reorder = datatable.data('reorder')
9
7
 
10
- if input_js_options['buttons'] == false
11
- input_js_options['buttons'] = []
8
+ if options['buttons'] == false
9
+ options['buttons'] = []
12
10
 
13
11
  init_options =
14
12
  ajax: { url: datatable.data('source'), type: 'POST' }
@@ -16,10 +14,10 @@ initializeDataTables = ->
16
14
  buttons: [
17
15
  {
18
16
  extend: 'colvis',
19
- text: 'Show / Hide',
20
17
  postfixButtons: [
21
- { extend: 'colvisGroup', text: 'Show all', show: ':hidden'},
22
- { extend: 'colvisRestore', text: 'Show default'}
18
+ { extend: 'colvisGroup', text: 'Show all', show: ':hidden', className: 'buttons-colvisGroup-first'},
19
+ { extend: 'colvisGroup', text: 'Show none', hide: ':visible' },
20
+ { extend: 'colvisGroup', text: 'Show default', hide: ':not(.colvis-default)', show: '.colvis-default' }
23
21
  ]
24
22
  },
25
23
  {
@@ -49,9 +47,8 @@ initializeDataTables = ->
49
47
  deferLoading: [datatable.data('display-records'), datatable.data('total-records')]
50
48
  deferRender: true
51
49
  displayStart: datatable.data('display-start')
52
- dom: "<'row'<'col-sm-12'B>><'row'<'col-sm-12'tr>><'row'<'col-sm-6 dataTables_entries'il><'col-sm-6'p>>"
53
50
  iDisplayLength: datatable.data('display-length')
54
- language: { 'lengthMenu': '&nbsp;with _MENU_ per page'}
51
+ language: datatable.data('language')
55
52
  lengthMenu: [[5, 10, 25, 50, 100, 250, 500, 9999999], ['5', '10', '25', '50', '100', '250', '500', 'All']]
56
53
  order: datatable.data('display-order')
57
54
  processing: true
@@ -63,7 +60,7 @@ initializeDataTables = ->
63
60
  $table = $(api.table().node())
64
61
  $form = $(".effective-datatables-filters[aria-controls='#{$table.attr('id')}']").first()
65
62
 
66
- params['cookie'] = $table.data('cookie')
63
+ params['attributes'] = $table.data('attributes')
67
64
  params['authenticity_token'] = $table.data('authenticity-token')
68
65
 
69
66
  if $form.length > 0
@@ -78,8 +75,7 @@ initializeDataTables = ->
78
75
  scrollCollapse: true
79
76
  pagingType: 'simple_numbers'
80
77
  initComplete: (settings) ->
81
- initializeReset(this.api())
82
- initializeBulkActions(this.api())
78
+ initializeButtons(this.api())
83
79
  initializeSearch(this.api())
84
80
  drawCallback: (settings) ->
85
81
  $table = $(this.api().table().node())
@@ -95,36 +91,21 @@ initializeDataTables = ->
95
91
  if settings['json']['charts']
96
92
  drawCharts($table, settings['json']['charts'])
97
93
 
98
- drawBulkActions($table)
94
+ $table.children('tbody').trigger('effective-bootstrap:initialize')
99
95
 
100
96
  # Copies the bulk actions html, stored in a data attribute on the table, into the buttons area
101
- initializeBulkActions = (api) ->
102
- $table = $(api.table().node())
103
-
104
- if $table.data('bulk-actions')
105
- $table.closest('.dataTables_wrapper').children().first().find('.dt-buttons').prepend($table.data('bulk-actions'))
106
-
107
- initializeReset = (api) ->
97
+ initializeButtons = (api) ->
108
98
  $table = $(api.table().node())
99
+ $buttons = $table.closest('.dataTables_wrapper').children().first().find('.dt-buttons')
109
100
 
110
101
  if $table.data('reset')
111
- $table.closest('.dataTables_wrapper').children().first().find('.dt-buttons').prepend($table.data('reset'))
112
-
113
- # After we perform a bulk action, we have to re-select the checkboxes manually and do a bit of house keeping
114
- drawBulkActions = ($table) ->
115
- selected = $table.data('bulk-actions-restore-selected-values')
102
+ $buttons.prepend($table.data('reset'))
116
103
 
117
- $bulkActions = $table.closest('.dataTables_wrapper').children().first().find('.buttons-bulk-actions').children('button')
104
+ if $table.data('reorder')
105
+ $buttons.prepend($table.data('reorder'))
118
106
 
119
- if selected && selected.length > 0
120
- $table.find("input[data-role='bulk-actions-resource']").each (_, input) ->
121
- $input = $(input)
122
- $input.prop('checked', selected.indexOf($input.val()) > -1)
123
-
124
- $bulkActions.removeAttr('disabled')
125
- $table.data('bulk-actions-restore-selected-values', [])
126
- else
127
- $bulkActions.attr('disabled', 'disabled')
107
+ if $table.data('bulk-actions')
108
+ $buttons.prepend($table.data('bulk-actions'))
128
109
 
129
110
  drawAggregates = ($table, aggregates) ->
130
111
  $tfoot = $table.find('tfoot').first()
@@ -152,7 +133,7 @@ initializeDataTables = ->
152
133
  api.settings()[0].aoPreSearchCols[index].sSearch = settings.search
153
134
 
154
135
  if settings.searchHtml # Append the search html and initialize input events
155
- $th.append('<br>' + settings.searchHtml)
136
+ $th.append(settings.searchHtml)
156
137
  initializeSearchEvents($th)
157
138
 
158
139
  # Sets up the proper events for each input
@@ -169,6 +150,7 @@ initializeDataTables = ->
169
150
  $input.on 'change', (event) -> dataTableSearch($(event.currentTarget))
170
151
  else if $input.is('input')
171
152
  $input.delayedChange ($input) -> dataTableSearch($input)
153
+ $input.on('paste', -> dataTableSearch($input))
172
154
 
173
155
  # Do the actual search
174
156
  dataTableSearch = ($input) -> # This is the function called by a select or input to run the search
@@ -177,27 +159,33 @@ initializeDataTables = ->
177
159
  table = $input.closest('table.dataTable')
178
160
  table.DataTable().column("#{$input.data('column-name')}:name").search($input.val()).draw()
179
161
 
180
- if simple
181
- init_options['dom'] = "<'row'<'col-sm-12'tr>>" # Just show the table
182
- datatable.addClass('simple')
162
+ if reorder
163
+ init_options['rowReorder'] = { selector: 'td.col-_reorder', snapX: true, dataSrc: datatable.data('reorder-index') }
183
164
 
184
165
  # Let's actually initialize the table now
185
- table = datatable.dataTable(jQuery.extend(init_options, input_js_options))
166
+ table = datatable.dataTable(jQuery.extend(init_options, options))
167
+
168
+ # Fix a tabindex issue
169
+ table.children('tbody').children('tr').children('td[tabindex]').removeAttr('tabindex')
186
170
 
187
171
  # Apply EffectiveFormInputs to the Show x per page dropdown
188
- if datatable.data('effective-form-inputs')
189
- try table.closest('.dataTables_wrapper').find('.dataTables_length select').removeAttr('name').select2(minimumResultsForSearch: 100)
172
+ try table.closest('.dataTables_wrapper').find('.dataTables_length select').removeAttr('name').select2(minimumResultsForSearch: 100)
173
+
174
+ if reorder
175
+ table.DataTable().on('row-reorder', (event, diff, edit) -> $(event.target).DataTable().reorder(event, diff, edit))
176
+
177
+ table.addClass('initialized')
178
+ table.children('thead').trigger('effective-bootstrap:initialize')
179
+ true
190
180
 
191
181
  destroyDataTables = ->
192
- $('table.effective-datatable').each ->
193
- if $.fn.DataTable.fnIsDataTable(this)
194
- $(this).DataTable().destroy()
182
+ $('.effective-datatables-inline-expanded').removeClass('effective-datatables-inline-expanded')
183
+ $('table.effective-datatable').each -> try $(this).removeClass('initialized').DataTable().destroy()
195
184
 
196
185
  $ -> initializeDataTables()
186
+ $(document).on 'effective-datatables:initialize', (event) -> initializeDataTables(event.currentTarget)
187
+
197
188
  $(document).on 'page:change', -> initializeDataTables()
198
189
  $(document).on 'turbolinks:load', -> initializeDataTables()
199
190
  $(document).on 'turbolinks:render', -> initializeDataTables()
200
191
  $(document).on 'turbolinks:before-cache', -> destroyDataTables()
201
-
202
-
203
-
@@ -0,0 +1,217 @@
1
+ # To achieve inline crud, we use rails' data-remote links, and override their behaviour when inside a datatable
2
+ # This works with EffectiveForm.remote_form which is part of the effective_bootstrap gem.
3
+
4
+ # We click the New/Edit/Action button from the col-actions
5
+ $(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-actions', (e, xhr, settings) ->
6
+ $action = $(e.target)
7
+ $table = $(e.target).closest('table')
8
+
9
+ return true if ('' + $action.data('inline')) == 'false'
10
+
11
+ $params = $.param({_datatable_id: $table.attr('id'), _datatable_attributes: $table.data('attributes'), _datatable_action: true })
12
+ settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
13
+
14
+ if $action.closest('.effective-datatables-inline-row,table.dataTable').hasClass('effective-datatables-inline-row')
15
+ # Nothing.
16
+ else if $action.closest('tr').parent().prop('tagName') == 'THEAD'
17
+ beforeNew($action)
18
+ else
19
+ beforeEdit($action)
20
+
21
+ true
22
+
23
+ # We have either completed the resource action, or fetched the inline form to load.
24
+ $(document).on 'ajax:success', '.dataTables_wrapper .col-actions', (event, data) ->
25
+ $action = $(event.target)
26
+
27
+ return true if ('' + $action.data('inline')) == 'false'
28
+
29
+ if data.length > 0
30
+ return true if data.indexOf('Turbolinks.clearCache()') == 0 && data.includes("Turbolinks.visit(")
31
+ return true if data.indexOf('<html') >= 0
32
+
33
+ if ($action.data('method') || 'get') == 'get'
34
+ if $action.closest('tr').parent().prop('tagName') == 'THEAD' then afterNew($action) else afterEdit($action)
35
+ else
36
+ afterAction($action)
37
+
38
+ EffectiveForm.remote_form_payload = ''
39
+ EffectiveForm.remote_form_commit = ''
40
+ EffectiveForm.remote_form_flash = ''
41
+
42
+ true
43
+
44
+ # There was an error completing something
45
+ $(document).on 'ajax:error', '.dataTables_wrapper', (event) ->
46
+ $action = $(event.target)
47
+
48
+ return true if ('' + $action.data('inline')) == 'false'
49
+
50
+ afterError($action)
51
+
52
+ EffectiveForm.remote_form_payload = ''
53
+ EffectiveForm.remote_form_commit = ''
54
+ EffectiveForm.remote_form_flash = ''
55
+ true
56
+
57
+ # Submitting an inline datatables form
58
+ $(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-inline-form', (e, xhr, settings) ->
59
+ $table = $(e.target).closest('table')
60
+
61
+ $params = $.param({_datatable_id: $table.attr('id'), _datatable_attributes: $table.data('attributes') })
62
+ settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
63
+
64
+ true
65
+
66
+ # The inline form has been submitted successfully
67
+ $(document).on 'effective-form:success', '.dataTables_wrapper .col-inline-form', (event, flash) ->
68
+ $action = $(event.target)
69
+
70
+ $tr = $action.closest('tr')
71
+ $table = $tr.closest('table')
72
+
73
+ if $tr.hasClass('effective-datatables-new-resource')
74
+ $table.DataTable().flash(flash || 'Item created', 'success')
75
+ $tr.fadeOut('slow')
76
+
77
+ $actions = $table.children('thead').find('th.col-actions')
78
+ $actions.children('svg').remove()
79
+ $actions.children('a').fadeIn()
80
+ else
81
+ $table.DataTable().flash(flash || 'Item updated', 'success')
82
+ $tr.fadeOut('slow')
83
+
84
+ $table.DataTable().draw()
85
+
86
+ beforeNew = ($action) ->
87
+ $table = $action.closest('table')
88
+ $th = $action.closest('th')
89
+
90
+ # Hide New Button
91
+ $th.children('a').hide()
92
+
93
+ # Append spinner and show Processing
94
+ $th.append($table.data('spinner'))
95
+ $table.DataTable().flash()
96
+ $table.one 'draw.dt', (event) ->
97
+ $th.find('a').show().siblings('svg').remove() if event.target == event.currentTarget
98
+
99
+ afterNew = ($action) ->
100
+ $tr = $action.closest('tr')
101
+ $table = $tr.closest('table')
102
+ $action.siblings('svg').remove()
103
+
104
+ html = buildRow($tr.children('th').length, EffectiveForm.remote_form_payload)
105
+
106
+ $tr = $("<tr class='effective-datatables-inline-row effective-datatables-new-resource' role='row'>#{html}</tr>")
107
+ $table.children('tbody').prepend($tr)
108
+
109
+ expand($table)
110
+ $tr.trigger('turbolinks:load')
111
+ $tr.hide().fadeIn()
112
+
113
+ beforeEdit = ($action) ->
114
+ $table = $action.closest('table')
115
+ $td = $action.closest('td')
116
+
117
+ # Hide dropdown
118
+ $td.find('.dropdown-toggle').dropdown('toggle')
119
+ $td.children('.btn-group').hide()
120
+ $td.children('a').hide()
121
+
122
+ # Append spinner and show Processing
123
+ $td.append($table.data('spinner'))
124
+ $table.DataTable().flash()
125
+
126
+ afterEdit = ($action) ->
127
+ $tr = $action.closest('tr')
128
+ $table = $tr.closest('table')
129
+
130
+ html = buildRow($tr.children('td').length, EffectiveForm.remote_form_payload)
131
+
132
+ $tr.data('inline-form-original-html', $tr.children().detach())
133
+ $tr.html(html)
134
+ $tr.addClass('effective-datatables-inline-row')
135
+
136
+ expand($table)
137
+ $tr.trigger('turbolinks:load')
138
+ $tr.hide().fadeIn()
139
+
140
+ # This is when one of the resource actions completes
141
+ afterAction = ($action) ->
142
+ $table = $action.closest('table')
143
+
144
+ if EffectiveForm.remote_form_flash.length > 0
145
+ flash = EffectiveForm.remote_form_flash[0]
146
+ $table.DataTable().flash(flash[1], flash[0])
147
+ else
148
+ $table.DataTable().flash('Successfully ' + $action.attr('title'), 'success')
149
+
150
+ $table.DataTable().draw()
151
+
152
+ afterError = ($action) ->
153
+ $table = $action.closest('table')
154
+ $td = $action.closest('td')
155
+
156
+ # Show dropdown
157
+ $td.children('.btn-group').show()
158
+
159
+ # Hide spinner
160
+ $td.children('svg').hide()
161
+
162
+ # Cancel
163
+ cancel($table)
164
+
165
+ # Don't redraw
166
+ $table.DataTable().flash('unable to ' + ($action.attr('title') || 'complete action'), 'danger')
167
+
168
+ buildRow = (length, payload) ->
169
+ "<td class='col-inline-form' colspan='#{length-1}'><div class='container'>#{payload}</div></td>" +
170
+ "<td class='col-actions col-actions-inline-form'>" +
171
+ "<a href='#' class='btn btn-sm btn-outline-primary' title='Cancel' data-role='inline-form-cancel'>Cancel</a>" +
172
+ "</td>"
173
+
174
+ expand = ($table) ->
175
+ $wrapper = $table.closest('.dataTables_wrapper').addClass('effective-datatables-inline-expanded')
176
+ $table.on 'draw.dt', (event) ->
177
+ $wrapper.removeClass('effective-datatables-inline-expanded') if event.target == event.currentTarget
178
+
179
+ cancel = ($table) ->
180
+ $wrapper = $table.closest('.dataTables_wrapper')
181
+ if $wrapper.find('.effective-datatables-inline-row').length == 0
182
+ $wrapper.removeClass('effective-datatables-inline-expanded')
183
+
184
+ # Cancel button clicked. Blow away new tr, or restore edit tr
185
+ # No data will have changed at this point
186
+ $(document).on 'click', ".dataTables_wrapper a[data-role='inline-form-cancel']", (event) ->
187
+ $tr = $(event.currentTarget).closest('tr')
188
+
189
+ if $tr.hasClass('effective-datatables-new-resource')
190
+ $tr.fadeOut('slow', ->
191
+ $table = $(this).closest('table')
192
+
193
+ $actions = $table.children('thead').find('th.col-actions')
194
+ $actions.children('svg').remove()
195
+ $actions.children('a').fadeIn()
196
+
197
+ $(this).remove()
198
+ cancel($table)
199
+ )
200
+ else
201
+ $tr.fadeOut('slow', ->
202
+ $table = $(this).closest('table')
203
+ $tr.html($tr.data('inline-form-original-html'))
204
+
205
+ $td = $tr.children('.col-actions').first()
206
+ $td.children('svg').remove()
207
+
208
+ $toggle = $td.find('.dropdown-toggle')
209
+ $toggle.dropdown('toggle') if $toggle.parent().hasClass('show')
210
+ $td.children('.btn-group').show()
211
+ $td.children('a').show()
212
+
213
+ $tr.removeClass('effective-datatables-inline-row').fadeIn()
214
+ cancel($table)
215
+ )
216
+
217
+ false