Working on datatables on client page

This commit is contained in:
Hillel Coren 2016-11-25 12:53:35 +02:00
parent eb710348bf
commit 1323f21867
8 changed files with 145 additions and 171 deletions

View File

@ -1,6 +1,7 @@
<?php namespace App\Http\Controllers; <?php namespace App\Http\Controllers;
use Utils; use Utils;
use Request;
use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
@ -27,14 +28,20 @@ class BaseController extends Controller
if ( ! is_array($ids)) { if ( ! is_array($ids)) {
$ids = [$ids]; $ids = [$ids];
} }
$isDatatable = filter_var(request()->datatable, FILTER_VALIDATE_BOOLEAN); $isDatatable = filter_var(request()->datatable, FILTER_VALIDATE_BOOLEAN);
$referer = Request::server('HTTP_REFERER');
$entityTypes = Utils::pluralizeEntityType($entityType); $entityTypes = Utils::pluralizeEntityType($entityType);
if ($action == 'restore' && count($ids) == 1) { if (strpos($referer, '/clients/')) {
// when restoring redirect to entity
return redirect($referer);
} elseif ($action == 'restore' && count($ids) == 1) {
return redirect("{$entityTypes}/" . $ids[0]); return redirect("{$entityTypes}/" . $ids[0]);
// when viewing from a datatable list
} elseif ($isDatatable || ($action == 'archive' || $action == 'delete')) { } elseif ($isDatatable || ($action == 'archive' || $action == 'delete')) {
return redirect("{$entityTypes}"); return redirect("{$entityTypes}");
// when viewing individual entity
} elseif (count($ids)) { } elseif (count($ids)) {
return redirect("{$entityTypes}/" . $ids[0]); return redirect("{$entityTypes}/" . $ids[0]);
} else { } else {

View File

@ -114,7 +114,7 @@ class ExpenseDatatable extends EntityDatatable
[ [
trans('texts.invoice_expense'), trans('texts.invoice_expense'),
function ($model) { function ($model) {
return "javascript:invoiceEntity({$model->public_id})"; return "javascript:submitForm_expense('invoice', {$model->public_id})";
}, },
function ($model) { function ($model) {
return ! $model->invoice_id && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('create', ENTITY_INVOICE); return ! $model->invoice_id && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('create', ENTITY_INVOICE);

View File

@ -110,8 +110,8 @@ class InvoiceDatatable extends EntityDatatable
], ],
[ [
trans('texts.mark_sent'), trans('texts.mark_sent'),
function ($model) { function ($model) use ($entityType) {
return "javascript:markEntity({$model->public_id})"; return "javascript:submitForm_{$entityType}('markSent', {$model->public_id})";
}, },
function ($model) { function ($model) {
return $model->invoice_status_id < INVOICE_STATUS_SENT && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); return $model->invoice_status_id < INVOICE_STATUS_SENT && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]);
@ -147,7 +147,7 @@ class InvoiceDatatable extends EntityDatatable
[ [
trans('texts.convert_to_invoice'), trans('texts.convert_to_invoice'),
function ($model) { function ($model) {
return "javascript:convertEntity({$model->public_id})"; return "javascript:submitForm_quote('convert', {$model->public_id})";
}, },
function ($model) use ($entityType) { function ($model) use ($entityType) {
return $entityType == ENTITY_QUOTE && ! $model->quote_invoice_id && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]); return $entityType == ENTITY_QUOTE && ! $model->quote_invoice_id && Auth::user()->can('editByOwner', [ENTITY_INVOICE, $model->user_id]);

View File

@ -78,7 +78,7 @@ class TaskDatatable extends EntityDatatable
[ [
trans('texts.stop_task'), trans('texts.stop_task'),
function ($model) { function ($model) {
return "javascript:stopTask({$model->public_id})"; return "javascript:submitForm_task('stop', {$model->public_id})";
}, },
function ($model) { function ($model) {
return $model->is_running && Auth::user()->can('editByOwner', [ENTITY_TASK, $model->user_id]); return $model->is_running && Auth::user()->can('editByOwner', [ENTITY_TASK, $model->user_id]);
@ -87,7 +87,7 @@ class TaskDatatable extends EntityDatatable
[ [
trans('texts.invoice_task'), trans('texts.invoice_task'),
function ($model) { function ($model) {
return "javascript:invoiceEntity({$model->public_id})"; return "javascript:submitForm_task('invoice', {$model->public_id})";
}, },
function ($model) { function ($model) {
return ! $model->invoice_number && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('create', ENTITY_INVOICE); return ! $model->invoice_number && (!$model->deleted_at || $model->deleted_at == '0000-00-00') && Auth::user()->can('create', ENTITY_INVOICE);

View File

@ -116,16 +116,16 @@ class DatatableService
} }
if (($datatable->entityType != ENTITY_USER || $model->public_id) && $can_edit) { if (($datatable->entityType != ENTITY_USER || $model->public_id) && $can_edit) {
$dropdown_contents .= "<li><a href=\"javascript:archiveEntity({$model->public_id})\">" $dropdown_contents .= "<li><a href=\"javascript:submitForm_{$datatable->entityType}('archive', {$model->public_id})\">"
. trans("texts.archive_{$datatable->entityType}") . '</a></li>'; . trans("texts.archive_{$datatable->entityType}") . '</a></li>';
} }
} else if($can_edit) { } else if($can_edit) {
$dropdown_contents .= "<li><a href=\"javascript:restoreEntity({$model->public_id})\">" $dropdown_contents .= "<li><a href=\"javascript:submitForm_{$datatable->entityType}('restore', {$model->public_id})\">"
. trans("texts.restore_{$datatable->entityType}") . '</a></li>'; . trans("texts.restore_{$datatable->entityType}") . '</a></li>';
} }
if (property_exists($model, 'is_deleted') && !$model->is_deleted && $can_edit) { if (property_exists($model, 'is_deleted') && !$model->is_deleted && $can_edit) {
$dropdown_contents .= "<li><a href=\"javascript:deleteEntity({$model->public_id})\">" $dropdown_contents .= "<li><a href=\"javascript:submitForm_{$datatable->entityType}('delete', {$model->public_id})\">"
. trans("texts.delete_{$datatable->entityType}") . '</a></li>'; . trans("texts.delete_{$datatable->entityType}") . '</a></li>';
} }

View File

@ -218,6 +218,7 @@
trans('texts.adjustment')) trans('texts.adjustment'))
->setUrl(url('api/activities/'. $client->public_id)) ->setUrl(url('api/activities/'. $client->public_id))
->setCustomValues('entityType', 'activity') ->setCustomValues('entityType', 'activity')
->setCustomValues('clientId', $client->public_id)
->setOptions('sPaginationType', 'bootstrap') ->setOptions('sPaginationType', 'bootstrap')
->setOptions('bFilter', false) ->setOptions('bFilter', false)
->setOptions('aaSorting', [['0', 'desc']]) ->setOptions('aaSorting', [['0', 'desc']])

View File

@ -79,7 +79,9 @@
{!! json_encode($k) !!}: {!! $o !!}, {!! json_encode($k) !!}: {!! $o !!},
@endforeach @endforeach
"fnDrawCallback": function(oSettings) { "fnDrawCallback": function(oSettings) {
if (window.onDatatableReady) { if (window.onDatatableReady_{{ $values['entityType'] }}) {
window.onDatatableReady_{{ $values['entityType'] }}();
} else if (window.onDatatableReady) {
window.onDatatableReady(); window.onDatatableReady();
} }
}, },

View File

@ -1,27 +1,28 @@
{!! Former::open(Utils::pluralizeEntityType($entityType) . '/bulk')->addClass('listForm') !!} {!! Former::open(Utils::pluralizeEntityType($entityType) . '/bulk')
->addClass('listForm_' . $entityType) !!}
<div style="display:none"> <div style="display:none">
{!! Former::text('action') !!} {!! Former::text('action')->id('action_' . $entityType) !!}
{!! Former::text('public_id') !!} {!! Former::text('public_id')->id('public_id_' . $entityType) !!}
{!! Former::text('datatable')->value('true') !!} {!! Former::text('datatable')->value('true') !!}
</div> </div>
<div class="pull-left"> <div class="pull-left">
@can('create', 'invoice') @can('create', 'invoice')
@if ($entityType == ENTITY_TASK) @if ($entityType == ENTITY_TASK)
{!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!} {!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm_'.$entityType.'("invoice")'])->appendIcon(Icon::create('check')) !!}
@endif @endif
@if ($entityType == ENTITY_EXPENSE) @if ($entityType == ENTITY_EXPENSE)
{!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm("invoice")'])->appendIcon(Icon::create('check')) !!} {!! Button::primary(trans('texts.invoice'))->withAttributes(['class'=>'invoice', 'onclick' =>'submitForm_'.$entityType.'("invoice")'])->appendIcon(Icon::create('check')) !!}
@endif @endif
@endcan @endcan
@if (in_array($entityType, [ENTITY_EXPENSE_CATEGORY, ENTITY_PRODUCT])) @if (in_array($entityType, [ENTITY_EXPENSE_CATEGORY, ENTITY_PRODUCT]))
{!! Button::normal(trans('texts.archive'))->asLinkTo('javascript:submitForm("archive")')->appendIcon(Icon::create('trash')) !!} {!! Button::normal(trans('texts.archive'))->asLinkTo('javascript:submitForm_'.$entityType.'("archive")')->appendIcon(Icon::create('trash')) !!}
@else @else
{!! DropdownButton::normal(trans('texts.archive'))->withContents([ {!! DropdownButton::normal(trans('texts.archive'))->withContents([
['label' => trans('texts.archive_'.$entityType), 'url' => 'javascript:submitForm("archive")'], ['label' => trans('texts.archive_'.$entityType), 'url' => 'javascript:submitForm_'.$entityType.'("archive")'],
['label' => trans('texts.delete_'.$entityType), 'url' => 'javascript:submitForm("delete")'], ['label' => trans('texts.delete_'.$entityType), 'url' => 'javascript:submitForm_'.$entityType.'("delete")'],
])->withAttributes(['class'=>'archive'])->split() !!} ])->withAttributes(['class'=>'archive'])->split() !!}
@endif @endif
@ -49,7 +50,7 @@
</div> </div>
<div id="top_right_buttons" class="pull-right"> <div id="top_right_buttons" class="pull-right">
<input id="tableFilter" type="text" style="width:140px;margin-right:17px;background-color: white !important" <input id="tableFilter_{{ $entityType }}" type="text" style="width:140px;margin-right:17px;background-color: white !important"
class="form-control pull-left" placeholder="{{ trans('texts.filter') }}" value="{{ Input::get('filter') }}"/> class="form-control pull-left" placeholder="{{ trans('texts.filter') }}" value="{{ Input::get('filter') }}"/>
@if (empty($clientId)) @if (empty($clientId))
@ -64,6 +65,7 @@
</div> </div>
{!! Datatable::table() {!! Datatable::table()
->addColumn(Utils::trans($datatable->columnFields())) ->addColumn(Utils::trans($datatable->columnFields()))
->setUrl(url('api/' . Utils::pluralizeEntityType($entityType) . '/' . (isset($clientId) ? $clientId : ''))) ->setUrl(url('api/' . Utils::pluralizeEntityType($entityType) . '/' . (isset($clientId) ? $clientId : '')))
@ -112,166 +114,128 @@
<script type="text/javascript"> <script type="text/javascript">
function submitForm(action) { function submitForm_{{ $entityType }}(action, id) {
if (action == 'delete') { if (id) {
sweetConfirm(function() { $('#public_id_{{ $entityType }}').val(id);
$('#action').val(action); }
$('form.listForm').submit();
});
} else {
$('#action').val(action);
$('form.listForm').submit();
}
}
function deleteEntity(id) { if (action == 'delete') {
$('#public_id').val(id); sweetConfirm(function() {
submitForm('delete'); $('#action_{{ $entityType }}').val(action);
} $('form.listForm_{{ $entityType }}').submit();
});
function archiveEntity(id) { } else {
$('#public_id').val(id); $('#action_{{ $entityType }}').val(action);
submitForm('archive'); $('form.listForm_{{ $entityType }}').submit();
} }
function restoreEntity(id) {
$('#public_id').val(id);
submitForm('restore');
}
function convertEntity(id) {
$('#public_id').val(id);
submitForm('convert');
}
function markEntity(id) {
$('#public_id').val(id);
submitForm('markSent');
}
function stopTask(id) {
$('#public_id').val(id);
submitForm('stop');
}
function invoiceEntity(id) {
$('#public_id').val(id);
submitForm('invoice');
}
@if ($entityType == ENTITY_PAYMENT)
var paymentId = null;
function showRefundModal(id, amount, formatted, symbol){
paymentId = id;
$('#refundCurrencySymbol').text(symbol);
$('#refundMax').text(formatted);
$('#refundAmount').val(amount).attr('max', amount);
$('#paymentRefundModal').modal('show');
} }
function handleRefundClicked(){
$('#public_id').val(paymentId);
submitForm('refund');
}
@endif
/*
function setTrashVisible() {
var checked = $('#trashed').is(':checked');
var url = '{{ URL::to('set_entity_filter/' . $entityType) }}' + (checked ? '/true' : '/false');
$.get(url, function(data) {
refreshDatatable();
})
}
*/
$(function() {
var tableFilter = '';
var searchTimeout = false;
var oTable0 = $('#DataTables_Table_0').dataTable();
var oTable1 = $('#DataTables_Table_1').dataTable();
function filterTable(val) {
if (val == tableFilter) {
return;
}
tableFilter = val;
oTable0.fnFilter(val);
}
$('#tableFilter').on('keyup', function(){
if (searchTimeout) {
window.clearTimeout(searchTimeout);
}
searchTimeout = setTimeout(function() {
filterTable($('#tableFilter').val());
}, 500);
})
if ($('#tableFilter').val()) {
filterTable($('#tableFilter').val());
}
window.onDatatableReady = function() {
$(':checkbox').click(function() {
setBulkActionsEnabled();
});
$('tbody tr').unbind('click').click(function(event) {
if (event.target.type !== 'checkbox' && event.target.type !== 'button' && event.target.tagName.toLowerCase() !== 'a') {
$checkbox = $(this).closest('tr').find(':checkbox:not(:disabled)');
var checked = $checkbox.prop('checked');
$checkbox.prop('checked', !checked);
setBulkActionsEnabled();
}
});
actionListHandler();
}
@if ($entityType == ENTITY_PAYMENT) @if ($entityType == ENTITY_PAYMENT)
$('#completeRefundButton').click(handleRefundClicked) var paymentId = null;
function showRefundModal(id, amount, formatted, symbol){
paymentId = id;
$('#refundCurrencySymbol').text(symbol);
$('#refundMax').text(formatted);
$('#refundAmount').val(amount).attr('max', amount);
$('#paymentRefundModal').modal('show');
}
function handleRefundClicked(){
$('#public_id').val(paymentId);
submitForm_{{ $entityType }}('refund');
}
@endif @endif
$('.archive, .invoice').prop('disabled', true); $(function() {
$('.archive:not(.dropdown-toggle)').click(function() {
submitForm('archive');
});
$('.selectAll').click(function() { // Handle datatable filtering
$(this).closest('table').find(':checkbox:not(:disabled)').prop('checked', this.checked); var tableFilter = '';
}); var searchTimeout = false;
function setBulkActionsEnabled() { function filterTable_{{ $entityType }}(val) {
var buttonLabel = "{{ trans('texts.archive') }}"; if (val == tableFilter) {
var count = $('tbody :checkbox:checked').length; return;
$('button.archive, button.invoice').prop('disabled', !count); }
if (count) { tableFilter = val;
buttonLabel += ' (' + count + ')'; var oTable0 = $('.listForm_{{ $entityType }} .data-table').dataTable();
} oTable0.fnFilter(val);
$('button.archive').not('.dropdown-toggle').text(buttonLabel); }
}
$('#statuses_{{ $entityType }}').select2({ $('#tableFilter_{{ $entityType }}').on('keyup', function(){
placeholder: "{{ trans('texts.status') }}", if (searchTimeout) {
}).val('{{ session('entity_state_filter:' . $entityType, STATUS_ACTIVE) . ',' . session('entity_status_filter:' . $entityType) }}'.split(',')) window.clearTimeout(searchTimeout);
.trigger('change') }
.on('change', function() { searchTimeout = setTimeout(function() {
var filter = $('#statuses_{{ $entityType }}').val(); filterTable_{{ $entityType }}($('#tableFilter_{{ $entityType }}').val());
if (filter) { }, 500);
filter = filter.join(','); })
} else {
filter = '';
}
var url = '{{ URL::to('set_entity_filter/' . $entityType) }}' + '/' + filter;
$.get(url, function(data) {
refreshDatatable();
})
}).maximizeSelect2Height();
$('#statusWrapper_{{ $entityType }}').show(); if ($('#tableFilter_{{ $entityType }}').val()) {
filterTable_{{ $entityType }}($('#tableFilter_{{ $entityType }}').val());
}
}); // Enable/disable bulk action buttons
window.onDatatableReady_{{ Utils::pluralizeEntityType($entityType) }} = function() {
$(':checkbox').click(function() {
setBulkActionsEnabled_{{ $entityType }}();
});
$('.listForm_{{ $entityType }} tbody tr').unbind('click').click(function(event) {
if (event.target.type !== 'checkbox' && event.target.type !== 'button' && event.target.tagName.toLowerCase() !== 'a') {
$checkbox = $(this).closest('tr').find(':checkbox:not(:disabled)');
var checked = $checkbox.prop('checked');
$checkbox.prop('checked', !checked);
setBulkActionsEnabled_{{ $entityType }}();
}
});
actionListHandler();
}
@if ($entityType == ENTITY_PAYMENT)
$('#completeRefundButton').click(handleRefundClicked)
@endif
$('.listForm_{{ $entityType }} .archive, .invoice').prop('disabled', true);
$('.listForm_{{ $entityType }} .archive:not(.dropdown-toggle)').click(function() {
submitForm_{{ $entityType }}('archive');
});
$('.listForm_{{ $entityType }} .selectAll').click(function() {
$(this).closest('table').find(':checkbox:not(:disabled)').prop('checked', this.checked);
});
function setBulkActionsEnabled_{{ $entityType }}() {
var buttonLabel = "{{ trans('texts.archive') }}";
var count = $('.listForm_{{ $entityType }} tbody :checkbox:checked').length;
$('.listForm_{{ $entityType }} button.archive, .listForm_{{ $entityType }} button.invoice').prop('disabled', !count);
if (count) {
buttonLabel += ' (' + count + ')';
}
$('.listForm_{{ $entityType }} button.archive').not('.dropdown-toggle').text(buttonLabel);
}
// Setup state/status filter
$('#statuses_{{ $entityType }}').select2({
placeholder: "{{ trans('texts.status') }}",
}).val('{{ session('entity_state_filter:' . $entityType, STATUS_ACTIVE) . ',' . session('entity_status_filter:' . $entityType) }}'.split(','))
.trigger('change')
.on('change', function() {
var filter = $('#statuses_{{ $entityType }}').val();
if (filter) {
filter = filter.join(',');
} else {
filter = '';
}
var url = '{{ URL::to('set_entity_filter/' . $entityType) }}' + '/' + filter;
$.get(url, function(data) {
refreshDatatable();
})
}).maximizeSelect2Height();
$('#statusWrapper_{{ $entityType }}').show();
});
</script> </script>