# To achieve inline crud, we use rails' data-remote links, and override their behaviour when inside a datatable
# This works with EffectiveForm.remote_form which is part of the effective_bootstrap gem.
# We click the New/Edit/Action button from the col-actions
$(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-actions', (e, xhr, settings) ->
$action = $(e.target)
$table = $(e.target).closest('table')
return true if ('' + $action.data('inline')) == 'false'
$params = $.param({_datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie'), _datatable_action: true })
settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
if $action.closest('.effective-datatables-inline-row,table.dataTable').hasClass('effective-datatables-inline-row')
# Nothing.
else if $action.closest('tr').parent().prop('tagName') == 'THEAD'
beforeNew($action)
else
beforeEdit($action)
true
# We have either completed the resource action, or fetched the inline form to load.
$(document).on 'ajax:success', '.dataTables_wrapper .col-actions', (event, data) ->
$action = $(event.target)
return true if ('' + $action.data('inline')) == 'false'
if data.length > 0
return true if data.indexOf('Turbolinks.clearCache()') == 0 && data.includes("Turbolinks.visit(")
return true if data.indexOf('= 0
if ($action.data('method') || 'get') == 'get'
if $action.closest('tr').parent().prop('tagName') == 'THEAD' then afterNew($action) else afterEdit($action)
else
afterAction($action)
EffectiveForm.remote_form_payload = ''
EffectiveForm.remote_form_flash = ''
EffectiveForm.remote_form_refresh_datatables = ''
true
# There was an error completing something
$(document).on 'ajax:error', '.dataTables_wrapper', (event) ->
$action = $(event.target)
return true if ('' + $action.data('inline')) == 'false'
afterError($action)
EffectiveForm.remote_form_payload = ''
EffectiveForm.remote_form_flash = ''
EffectiveForm.remote_form_refresh_datatables = ''
true
# Submitting an inline datatables form
$(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-inline-form', (e, xhr, settings) ->
$table = $(e.target).closest('table')
$params = $.param({_datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie') })
settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
true
# The inline form has been submitted successfully
$(document).on 'effective-form:success', '.dataTables_wrapper .col-inline-form', (event, flash) ->
$action = $(event.target)
$tr = $action.closest('tr')
$table = $tr.closest('table')
if $tr.hasClass('effective-datatables-new-resource')
$table.DataTable().flash(flash || 'Item created', 'success')
$tr.fadeOut('slow')
$actions = $table.children('thead').find('th.col-actions')
$actions.children('svg').remove()
$actions.children('a').fadeIn()
else
$table.DataTable().flash(flash || 'Item updated', 'success')
$tr.fadeOut('slow')
unless redirectDatatables($table)
$table.DataTable().draw()
refreshDatatables($table)
beforeNew = ($action) ->
$table = $action.closest('table')
$th = $action.closest('th')
# Hide New Button
$th.children('a').hide()
# Append spinner and show Processing
$th.append($table.data('spinner'))
$table.DataTable().flash()
$table.one 'draw.dt', (event) ->
$th.find('a').show().siblings('svg').remove() if event.target == event.currentTarget
afterNew = ($action) ->
$tr = $action.closest('tr')
$table = $tr.closest('table')
$action.siblings('svg').remove()
html = buildRow($tr.children('th').length, EffectiveForm.remote_form_payload)
$tr = $("
#{html}
")
$table.children('tbody').prepend($tr)
expand($table)
$tr.find('form').attr('data-remote', true).trigger('turbolinks:load')
$tr.hide().fadeIn()
beforeEdit = ($action) ->
$table = $action.closest('table')
$td = $action.closest('td')
# Hide dropdown
$td.find('.dropdown-toggle').dropdown('toggle')
$td.children('.btn-group').hide()
$td.children('a').hide()
# Append spinner and show Processing
$td.append($table.data('spinner'))
$table.DataTable().flash()
afterEdit = ($action) ->
$tr = $action.closest('tr')
$table = $tr.closest('table')
html = buildRow($tr.children('td').length, EffectiveForm.remote_form_payload)
$tr.data('inline-form-original-html', $tr.children().detach())
$tr.html(html)
$tr.addClass('effective-datatables-inline-row')
expand($table)
$tr.find('form').attr('data-remote', true).trigger('turbolinks:load')
$tr.hide().fadeIn()
# This is when one of the resource actions completes
afterAction = ($action) ->
$table = $action.closest('table')
if EffectiveForm.remote_form_flash.length > 0
flash = EffectiveForm.remote_form_flash[0]
$table.DataTable().flash(flash[1], flash[0])
else
$table.DataTable().flash('Successfully ' + $action.attr('title'), 'success')
unless redirectDatatables($table)
$table.DataTable().draw()
refreshDatatables($table)
afterError = ($action) ->
$table = $action.closest('table')
$td = $action.closest('td')
# Show dropdown
$td.children('.btn-group').show()
# Hide spinner
$td.children('svg').hide()
# Cancel
cancel($table)
# Don't redraw
$table.DataTable().flash('unable to ' + ($action.attr('title') || 'complete action'), 'danger')
buildRow = (length, payload) ->
"#{payload} | " +
"" +
"Cancel" +
" | "
expand = ($table) ->
$wrapper = $table.closest('.dataTables_wrapper').addClass('effective-datatables-inline-expanded')
$table.on 'draw.dt', (event) ->
$wrapper.removeClass('effective-datatables-inline-expanded') if event.target == event.currentTarget
cancel = ($table) ->
$wrapper = $table.closest('.dataTables_wrapper')
if $wrapper.find('.effective-datatables-inline-row').length == 0
$wrapper.removeClass('effective-datatables-inline-expanded')
redirectDatatables = ($source) ->
return false unless EffectiveForm.remote_form_refresh_datatables.length > 0
if EffectiveForm.remote_form_refresh_datatables.includes('refresh')
if Turbolinks?
Turbolinks.visit(window.location.href, { action: 'replace'})
else
window.location.reload()
return true
false
refreshDatatables = ($source) ->
return unless EffectiveForm.remote_form_refresh_datatables.length > 0
$('table.dataTable.initialized').each ->
$table = $(this)
if EffectiveForm.remote_form_refresh_datatables.find((id) -> $table.attr('id').startsWith(id) || id == 'all')
$table.DataTable().draw() if $table != $source
# Cancel button clicked. Blow away new tr, or restore edit tr
# No data will have changed at this point
$(document).on 'click', ".dataTables_wrapper a[data-role='inline-form-cancel']", (event) ->
$tr = $(event.currentTarget).closest('tr')
if $tr.hasClass('effective-datatables-new-resource')
$tr.fadeOut('slow', ->
$table = $(this).closest('table')
$actions = $table.children('thead').find('th.col-actions')
$actions.children('svg').remove()
$actions.children('a').fadeIn()
$(this).remove()
cancel($table)
)
else
$tr.fadeOut('slow', ->
$table = $(this).closest('table')
$tr.html($tr.data('inline-form-original-html'))
$td = $tr.children('.col-actions').first()
$td.children('svg').remove()
$toggle = $td.find('.dropdown-toggle')
$toggle.dropdown('toggle') if $toggle.parent().hasClass('show')
$td.children('.btn-group').show()
$td.children('a').show()
$tr.removeClass('effective-datatables-inline-row').fadeIn()
cancel($table)
)
false