Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/app/Http/Controllers/Operations/DeleteOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ protected function setupDeleteDefaults()
LifecycleHook::hookInto(['list:before_setup', 'show:before_setup'], function () {
$this->crud->addButton('line', 'delete', 'view', 'crud::buttons.delete', 'end');
});

// setup the default redirect to where user will be redirected after delete
// if user has access to list, redirect to list, otherwise redirect to previous page
LifecycleHook::hookInto('show:before_setup', function () {
$this->crud->setOperationSetting('deleteButtonRedirect', function () {
if ($this->crud->hasAccess('list')) {
return url($this->crud->route);
}

return url()->previous();
});
});
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/app/Library/CrudPanel/CrudButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,11 @@ public function section($stack)
* The HTML itself of the button.
*
* @param object|null $entry The eloquent Model for the current entry or null if no current entry.
* @param \Backpack\CRUD\app\Library\CrudPanel\CrudPanel|null $crud The CRUD panel instance.
* @param string|null $crudTableId The ID of the DataTable for multi-table support.
* @return \Illuminate\Contracts\View\View
*/
public function getHtml($entry = null, ?CrudPanel $crud = null)
public function getHtml($entry = null, ?CrudPanel $crud = null, ?string $crudTableId = null)
{
$button = $this;
$crud = $crud ?? $this->crud();
Expand All @@ -311,7 +313,7 @@ public function getHtml($entry = null, ?CrudPanel $crud = null)
}

if ($this->type == 'view') {
return view($button->getFinalViewPath(), compact('button', 'crud', 'entry'));
return view($button->getFinalViewPath(), compact('button', 'crud', 'entry', 'crudTableId'));
}

abort(500, 'Unknown button type', ['developer-error-exception']);
Expand Down
3 changes: 3 additions & 0 deletions src/app/Library/CrudPanel/Traits/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,13 @@ public function getRowViews($entry, $rowNumber = false)

// add the buttons as the last column
if ($this->buttons()->where('stack', 'line')->count()) {
$crudTableId = request()->input('datatable_id', 'crudTable');

$row_items[] = \View::make('crud::inc.button_stack', ['stack' => 'line'])
->with('crud', $this)
->with('entry', $entry)
->with('row_number', $rowNumber)
->with('crudTableId', $crudTableId)
->render();
}

Expand Down
229 changes: 136 additions & 93 deletions src/resources/views/crud/buttons/delete.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@

@php
$redirectUrl = $crud->getOperationSetting('deleteButtonRedirect');
if($redirectUrl && $redirectUrl instanceof \Closure){
$redirectUrl = $redirectUrl();
}
$redirectUrl = filter_var($redirectUrl, FILTER_VALIDATE_URL) ? $redirectUrl : null;
@endphp

@if ($crud->hasAccess('delete', $entry))
<a href="javascript:void(0)" onclick="deleteEntry(this)" bp-button="delete" data-route="{{ url($crud->route.'/'.$entry->getKey()) }}" class="btn btn-sm btn-link" data-button-type="delete">
<a href="javascript:void(0)"
onclick="deleteEntry(this)"
bp-button="delete"
data-redirect-route="{{ $redirectUrl }}"
data-route="{{ url($crud->route.'/'.$entry->getKey()) }}"
data-table-id="{{ isset($crudTableId) ? $crudTableId : 'crudTable' }}"
class="btn btn-sm btn-link"
data-button-type="delete"
>
<i class="la la-trash"></i> <span>{{ trans('backpack::crud.delete') }}</span>
</a>
@endif
Expand All @@ -11,103 +28,129 @@
@bassetBlock('backpack/crud/buttons/delete-button-'.app()->getLocale().'.js')
<script>

if (typeof deleteEntry != 'function') {
$("[data-button-type=delete]").unbind('click');
if (typeof deleteEntry != 'function') {
$("[data-button-type=delete]").unbind('click');

function deleteEntry(button) {
// ask for confirmation before deleting an item
// e.preventDefault();
var route = $(button).attr('data-route');
function deleteEntry(button) {
// ask for confirmation before deleting an item
// e.preventDefault();
var route = $(button).attr('data-route');

swal({
title: "{!! trans('backpack::base.warning') !!}",
text: "{!! trans('backpack::crud.delete_confirm') !!}",
icon: "warning",
buttons: {
cancel: {
text: "{!! trans('backpack::crud.cancel') !!}",
value: null,
visible: true,
className: "bg-secondary",
closeModal: true,
},
delete: {
text: "{!! trans('backpack::crud.delete') !!}",
value: true,
visible: true,
className: "bg-danger",
},
},
dangerMode: true,
}).then((value) => {
if (value) {
$.ajax({
url: route,
type: 'DELETE',
success: function(result) {
if (result == 1) {
// Redraw the table
if (typeof crud != 'undefined' && typeof crud.table != 'undefined') {
// Move to previous page in case of deleting the only item in table
if(crud.table.rows().count() === 1) {
crud.table.page("previous");
}
swal({
title: "{!! trans('backpack::base.warning') !!}",
text: "{!! trans('backpack::crud.delete_confirm') !!}",
icon: "warning",
buttons: {
cancel: {
text: "{!! trans('backpack::crud.cancel') !!}",
value: null,
visible: true,
className: "bg-secondary",
closeModal: true,
},
delete: {
text: "{!! trans('backpack::crud.delete') !!}",
value: true,
visible: true,
className: "bg-danger",
},
},
dangerMode: true,
}).then((value) => {
function showDeleteNotyAlert() {
// Show a success notification bubble
new Noty({
type: "success",
text: "{!! '<strong>'.trans('backpack::crud.delete_confirmation_title').'</strong><br>'.trans('backpack::crud.delete_confirmation_message') !!}"
}).show();
}
if (value) {
$.ajax({
url: route,
type: 'DELETE',
success: function(result) {
if (result == 1) {
// Get the table ID from the button's data attribute
let tableId = $(button).data('table-id') || 'crudTable';

// Check if we have a specific DataTable instance
if (typeof window.crud !== 'undefined' &&
typeof window.crud.tables !== 'undefined' &&
window.crud.tables[tableId]) {

let table = window.crud.tables[tableId];

// Move to previous page in case of deleting the only item in table
if(table.rows().count() === 1) {
table.page("previous");
}
// Hide the modal, if any is displayed
$('.dtr-modal-close').click();

crud.table.draw(false);
}
showDeleteNotyAlert();
table.draw(false);
} else {
// there is no crud table in the current page, so we will redirect the user to the defined button redirect route in data-redirect-url
let redirectRoute = $(button).data('redirect-route');
if(redirectRoute){
// queue the alert in localstorage to show it after the redirect
localStorage.setItem('backpack_alerts', JSON.stringify({
'success': [
"{!! '<strong>'.trans('backpack::crud.delete_confirmation_title').'</strong><br>'.trans('backpack::crud.delete_confirmation_message') !!}"
]
}));
window.location.href = redirectRoute;
} else {
// Show a success notification bubble, keep the previous behaviour of not redirecting
// and keeping the entry open after deletion
showDeleteNotyAlert();
}
}
} else {
// if the result is an array, it means
// we have notification bubbles to show
if (result instanceof Object) {
// trigger one or more bubble notifications
Object.entries(result).forEach(function(entry, index) {
var type = entry[0];
entry[1].forEach(function(message, i) {
new Noty({
type: type,
text: message
}).show();
});
});
} else {
// Show an error alert
swal({
title: "{!! trans('backpack::crud.delete_confirmation_not_title') !!}",
text: "{!! trans('backpack::crud.delete_confirmation_not_message') !!}",
icon: "error",
timer: 4000,
buttons: false,
});
}
}
},
error: function(result) {
// Show an alert with the result
swal({
title: "{!! trans('backpack::crud.delete_confirmation_not_title') !!}",
text: "{!! trans('backpack::crud.delete_confirmation_not_message') !!}",
icon: "error",
timer: 4000,
buttons: false,
});
}
});
}
});

// Show a success notification bubble
new Noty({
type: "success",
text: "{!! '<strong>'.trans('backpack::crud.delete_confirmation_title').'</strong><br>'.trans('backpack::crud.delete_confirmation_message') !!}"
}).show();

// Hide the modal, if any
$('.modal').modal('hide');
} else {
// if the result is an array, it means
// we have notification bubbles to show
if (result instanceof Object) {
// trigger one or more bubble notifications
Object.entries(result).forEach(function(entry, index) {
var type = entry[0];
entry[1].forEach(function(message, i) {
new Noty({
type: type,
text: message
}).show();
});
});
} else {// Show an error alert
swal({
title: "{!! trans('backpack::crud.delete_confirmation_not_title') !!}",
text: "{!! trans('backpack::crud.delete_confirmation_not_message') !!}",
icon: "error",
timer: 4000,
buttons: false,
});
}
}
},
error: function(result) {
// Show an alert with the result
swal({
title: "{!! trans('backpack::crud.delete_confirmation_not_title') !!}",
text: "{!! trans('backpack::crud.delete_confirmation_not_message') !!}",
icon: "error",
timer: 4000,
buttons: false,
});
}
});
}
});

}
}
}
}

// make it so that the function above is run after each DataTable draw event
// crud.addFunctionToDataTablesDrawEventQueue('deleteEntry');
// make it so that the function above is run after each DataTable draw event
// crud.addFunctionToDataTablesDrawEventQueue('deleteEntry');
</script>
@endBassetBlock
@if (!request()->ajax()) @endpush @endif
2 changes: 1 addition & 1 deletion src/resources/views/crud/inc/button_stack.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@if ($crud->buttons()->where('stack', $stack)->count())
@foreach ($crud->buttons()->where('stack', $stack) as $button)
{!! $button->getHtml($entry ?? null, $crud) !!}
{!! $button->getHtml($entry ?? null, $crud, $crudTableId ?? null) !!}
@endforeach
@endif