mirror of
https://github.com/prurigro/hypothetical.git
synced 2024-11-25 16:51:25 -05:00
Implement deletion functionality for uploaded images and files
This commit is contained in:
parent
5c2ad8cccb
commit
27ef5d09e5
7 changed files with 179 additions and 26 deletions
|
@ -105,7 +105,7 @@ class DashboardController extends Controller {
|
||||||
$directory = base_path() . '/public/uploads/' . $request['model'] . '/img/';
|
$directory = base_path() . '/public/uploads/' . $request['model'] . '/img/';
|
||||||
file::makeDirectory($directory, 0755, true, true);
|
file::makeDirectory($directory, 0755, true, true);
|
||||||
$image = Image::make($request->file('file'));
|
$image = Image::make($request->file('file'));
|
||||||
$image->save($directory . $request['id'] . "-" . $request['name'] . '.jpg');
|
$image->save($directory . $request['id'] . '-' . $request['name'] . '.jpg');
|
||||||
} else {
|
} else {
|
||||||
return 'file-upload-fail';
|
return 'file-upload-fail';
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ class DashboardController extends Controller {
|
||||||
if ($request->hasFile('file')) {
|
if ($request->hasFile('file')) {
|
||||||
$directory = base_path() . '/public/uploads/' . $request['model'] . '/files/';
|
$directory = base_path() . '/public/uploads/' . $request['model'] . '/files/';
|
||||||
file::makeDirectory($directory, 0755, true, true);
|
file::makeDirectory($directory, 0755, true, true);
|
||||||
$request->file('file')->move($directory, $request['id'] . "-" . $request['name'] . '.' . $request['ext']);
|
$request->file('file')->move($directory, $request['id'] . '-' . $request['name'] . '.' . $request['ext']);
|
||||||
} else {
|
} else {
|
||||||
return 'file-upload-fail';
|
return 'file-upload-fail';
|
||||||
}
|
}
|
||||||
|
@ -242,4 +242,49 @@ class DashboardController extends Controller {
|
||||||
return 'success';
|
return 'success';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dashboard Image Delete: Delete images
|
||||||
|
*/
|
||||||
|
public function deleteImageDelete(Request $request)
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'id' => 'required',
|
||||||
|
'model' => 'required',
|
||||||
|
'name' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$image = base_path() . '/public/uploads/' . $request['model'] . '/img/' . $request['id'] . '-' . $request['name'] . '.jpg';
|
||||||
|
|
||||||
|
if (!file_exists($image)) {
|
||||||
|
return 'image-not-exists-fail';
|
||||||
|
} else if (!unlink($image)) {
|
||||||
|
return 'image-delete-fail';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'success';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dashboard File Delete: Delete files
|
||||||
|
*/
|
||||||
|
public function deleteFileDelete(Request $request)
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'id' => 'required',
|
||||||
|
'model' => 'required',
|
||||||
|
'name' => 'required',
|
||||||
|
'ext' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$file = base_path() . '/public/uploads/' . $request['model'] . '/files/' . $request['id'] . '-' . $request['name'] . '.' . $request['ext'];
|
||||||
|
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
return 'file-not-exists-fail';
|
||||||
|
} else if (!unlink($file)) {
|
||||||
|
return 'file-delete-fail';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'success';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,9 +207,11 @@ The following is a list of possible `types` in the `columns` array for Editable
|
||||||
* `hidden`: Fields that will contain values to pass to the update function but won't appear on the page (this must be used for the sort column)
|
* `hidden`: Fields that will contain values to pass to the update function but won't appear on the page (this must be used for the sort column)
|
||||||
* `image`: Fields that contain image uploads
|
* `image`: Fields that contain image uploads
|
||||||
* `name`: not part of the database and is instead used in the filename
|
* `name`: not part of the database and is instead used in the filename
|
||||||
|
* `delete`: (optional) if true then uploaded images can be deleted
|
||||||
* `file`: Fields that contains file uploads
|
* `file`: Fields that contains file uploads
|
||||||
* `name`: not part of the database and is instead used in the filename
|
* `name`: not part of the database and is instead used in the filename
|
||||||
* `ext` required key containing the file extension
|
* `ext` required key containing the file extension
|
||||||
|
* `delete`: (optional) if true then uploaded files can be deleted
|
||||||
* `display`: Displayed information that can't be edited
|
* `display`: Displayed information that can't be edited
|
||||||
|
|
||||||
#### Edit Item Functionality
|
#### Edit Item Functionality
|
||||||
|
|
91
resources/assets/js/dashboard.js
vendored
91
resources/assets/js/dashboard.js
vendored
|
@ -2,7 +2,7 @@
|
||||||
jQuery.fn.reverse = [].reverse;
|
jQuery.fn.reverse = [].reverse;
|
||||||
|
|
||||||
// show the confirmation modal and run the supplied command if confirm is pressed
|
// show the confirmation modal and run the supplied command if confirm is pressed
|
||||||
function askConfirmation(message, command) {
|
function askConfirmation(message, command, cancelCommand) {
|
||||||
const $confirmationModal = $("#confirmation-modal"),
|
const $confirmationModal = $("#confirmation-modal"),
|
||||||
$heading = $confirmationModal.find(".panel-heading"),
|
$heading = $confirmationModal.find(".panel-heading"),
|
||||||
$cancelButton = $confirmationModal.find(".btn.cancel-button"),
|
$cancelButton = $confirmationModal.find(".btn.cancel-button"),
|
||||||
|
@ -35,8 +35,17 @@ function askConfirmation(message, command) {
|
||||||
closeConfirmationModal();
|
closeConfirmationModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// functionality to run when clicking the cancel button
|
||||||
|
const cancelModal = function() {
|
||||||
|
if (cancelCommand !== undefined) {
|
||||||
|
cancelCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
closeConfirmationModal();
|
||||||
|
};
|
||||||
|
|
||||||
// hide the modal when the cancel button is pressed
|
// hide the modal when the cancel button is pressed
|
||||||
$cancelButton.on("click", closeConfirmationModal);
|
$cancelButton.on("click", cancelModal);
|
||||||
|
|
||||||
// hide the modal when the escape key is pressed
|
// hide the modal when the escape key is pressed
|
||||||
$(document).on("keyup", escapeModal);
|
$(document).on("keyup", escapeModal);
|
||||||
|
@ -103,6 +112,7 @@ function showAlert(message, command) {
|
||||||
function editListInit() {
|
function editListInit() {
|
||||||
const editList = document.getElementById("edit-list"),
|
const editList = document.getElementById("edit-list"),
|
||||||
$editList = $(editList),
|
$editList = $(editList),
|
||||||
|
$token = $("#token"),
|
||||||
model = $editList.data("model"),
|
model = $editList.data("model"),
|
||||||
path = $editList.data("path");
|
path = $editList.data("path");
|
||||||
|
|
||||||
|
@ -145,7 +155,7 @@ function editListInit() {
|
||||||
data: {
|
data: {
|
||||||
model: model,
|
model: model,
|
||||||
id: itemId,
|
id: itemId,
|
||||||
_token: $("#token").val()
|
_token: $token.val()
|
||||||
}
|
}
|
||||||
}).always(function(response) {
|
}).always(function(response) {
|
||||||
if (response === "success") {
|
if (response === "success") {
|
||||||
|
@ -177,7 +187,7 @@ function editListInit() {
|
||||||
url: postUrl,
|
url: postUrl,
|
||||||
data: {
|
data: {
|
||||||
id: itemId,
|
id: itemId,
|
||||||
_token: $("#token").val()
|
_token: $token.val()
|
||||||
}
|
}
|
||||||
}).always(function(response) {
|
}).always(function(response) {
|
||||||
if (response === "success") {
|
if (response === "success") {
|
||||||
|
@ -212,7 +222,7 @@ function editListInit() {
|
||||||
model: model,
|
model: model,
|
||||||
order: sortOrder,
|
order: sortOrder,
|
||||||
column: sortCol,
|
column: sortCol,
|
||||||
_token: $("#token").val()
|
_token: $token.val()
|
||||||
}
|
}
|
||||||
}).always(function(response) {
|
}).always(function(response) {
|
||||||
if (response !== "success") {
|
if (response !== "success") {
|
||||||
|
@ -267,7 +277,7 @@ function editItemInit() {
|
||||||
$mkdEditors = $(".mkd-editor"),
|
$mkdEditors = $(".mkd-editor"),
|
||||||
$fileUploads = $(".file-upload"),
|
$fileUploads = $(".file-upload"),
|
||||||
$imgUploads = $(".image-upload"),
|
$imgUploads = $(".image-upload"),
|
||||||
$token = $("#_token"),
|
$token = $("#token"),
|
||||||
$spinner = $("#loading-modal"),
|
$spinner = $("#loading-modal"),
|
||||||
fadeTime = 250,
|
fadeTime = 250,
|
||||||
model = $editItem.data("model"),
|
model = $editItem.data("model"),
|
||||||
|
@ -440,6 +450,74 @@ function editItemInit() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$(".edit-button.delete.image").on("click", function(e) {
|
||||||
|
const $this = $(this),
|
||||||
|
name = $this.data("name");
|
||||||
|
|
||||||
|
if (!submitting) {
|
||||||
|
submitting = true;
|
||||||
|
|
||||||
|
askConfirmation("Are you sure you want to delete this image?", function() {
|
||||||
|
// delete the image
|
||||||
|
$.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: "/dashboard/image-delete",
|
||||||
|
data: {
|
||||||
|
id: id,
|
||||||
|
model: model,
|
||||||
|
name: name,
|
||||||
|
_token: $token.val()
|
||||||
|
}
|
||||||
|
}).always(function(response) {
|
||||||
|
if (response === "success") {
|
||||||
|
$(`#current-image-${name}`).slideUp(200);
|
||||||
|
} else {
|
||||||
|
showAlert("ERROR: Failed to delete the image: " + response);
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting = false;
|
||||||
|
});
|
||||||
|
}, function() {
|
||||||
|
submitting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".edit-button.delete.file").on("click", function(e) {
|
||||||
|
const $this = $(this),
|
||||||
|
name = $this.data("name"),
|
||||||
|
ext = $this.data("ext");
|
||||||
|
|
||||||
|
if (!submitting) {
|
||||||
|
submitting = true;
|
||||||
|
|
||||||
|
askConfirmation("Are you sure you want to delete this file?", function() {
|
||||||
|
// delete the file
|
||||||
|
$.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: "/dashboard/file-delete",
|
||||||
|
data: {
|
||||||
|
id: id,
|
||||||
|
model: model,
|
||||||
|
name: name,
|
||||||
|
ext: ext,
|
||||||
|
_token: $token.val()
|
||||||
|
}
|
||||||
|
}).always(function(response) {
|
||||||
|
if (response === "success") {
|
||||||
|
$(`#current-file-${name}`).slideUp(200);
|
||||||
|
} else {
|
||||||
|
showAlert("ERROR: Failed to delete the file: " + response);
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting = false;
|
||||||
|
});
|
||||||
|
}, function() {
|
||||||
|
submitting = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// allow start time selection to start on the hour and every 15 minutes after
|
// allow start time selection to start on the hour and every 15 minutes after
|
||||||
for (hours = 0; hours <= 23; hours++) {
|
for (hours = 0; hours <= 23; hours++) {
|
||||||
for (minutes = 0; minutes <= 3; minutes++) {
|
for (minutes = 0; minutes <= 3; minutes++) {
|
||||||
|
@ -518,7 +596,6 @@ function editItemInit() {
|
||||||
|
|
||||||
// populate the formData object
|
// populate the formData object
|
||||||
getFormData();
|
getFormData();
|
||||||
// console.log(JSON.stringify(formData));
|
|
||||||
|
|
||||||
// submit the update
|
// submit the update
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
33
resources/assets/sass/dashboard.scss
vendored
33
resources/assets/sass/dashboard.scss
vendored
|
@ -397,23 +397,38 @@ body {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-file {
|
.edit-button {
|
||||||
|
margin-bottom: ($grid-gutter-width / 2);
|
||||||
|
display: inline-block;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
border: 1px solid darken($c-dashboard-dark, 5%);
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: $c-dashboard-dark;
|
|
||||||
color: $c-text-light;
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
transition: background-color 150ms;
|
transition: background-color 150ms;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover, &:focus {
|
||||||
background-color: lighten($c-dashboard-dark, 5%);
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.no-file {
|
&.view {
|
||||||
margin-bottom: 15px;
|
border: 1px solid darken($c-dashboard-dark, 5%);
|
||||||
|
background-color: $c-dashboard-dark;
|
||||||
|
color: $c-text-light;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($c-dashboard-dark, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.delete {
|
||||||
|
border: 1px solid darken($c-dashboard-delete, 5%);
|
||||||
|
background-color: $c-dashboard-delete;
|
||||||
|
color: $c-text-light;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten($c-dashboard-delete, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-button {
|
.back-button {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<form id="edit-item" class="edit-item" data-id="{{ $id }}" data-model="{{ $model }}" data-path="{{ isset($path) ? $path : $model }}">
|
<form id="edit-item" class="edit-item" data-id="{{ $id }}" data-model="{{ $model }}" data-path="{{ isset($path) ? $path : $model }}">
|
||||||
<input type="hidden" name="_token" id="_token" value="{{ csrf_token() }}" />
|
<input type="hidden" id="token" value="{{ csrf_token() }}" />
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@foreach($columns as $column)
|
@foreach($columns as $column)
|
||||||
|
@ -51,9 +51,15 @@
|
||||||
@set('current_image', "/uploads/$model/img/$id-" . $column['name'] . '.jpg')
|
@set('current_image', "/uploads/$model/img/$id-" . $column['name'] . '.jpg')
|
||||||
|
|
||||||
@if(file_exists(base_path() . '/public' . $current_image))
|
@if(file_exists(base_path() . '/public' . $current_image))
|
||||||
<img class="current-image" src="{{ $current_image }}" />
|
<div id="current-image-{{ $column['name'] }}">
|
||||||
@else
|
<img class="current-image" src="{{ $current_image }}" />
|
||||||
<div class="no-file">(No Image Set)</div>
|
|
||||||
|
@if(array_key_exists('delete', $column) && $column['delete'])
|
||||||
|
<span class="edit-button delete image" data-name="{{ $column['name'] }}">
|
||||||
|
Delete Image
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@elseif($column['type'] == 'file')
|
@elseif($column['type'] == 'file')
|
||||||
<input class="file-upload" type="file" name="{{ $column['name'] }}" id="{{ $column['name'] }}" data-ext="{{ $column['ext'] }}" />
|
<input class="file-upload" type="file" name="{{ $column['name'] }}" id="{{ $column['name'] }}" data-ext="{{ $column['ext'] }}" />
|
||||||
|
@ -61,9 +67,15 @@
|
||||||
@set('current_file', "/uploads/$model/files/$id-" . $column['name'] . '.' . $column['ext'])
|
@set('current_file', "/uploads/$model/files/$id-" . $column['name'] . '.' . $column['ext'])
|
||||||
|
|
||||||
@if(file_exists(base_path() . '/public' . $current_file))
|
@if(file_exists(base_path() . '/public' . $current_file))
|
||||||
<a class="current-file" href="{{ $current_file }}" target="_blank">View Current {{ strtoupper($column['ext']) }}</a>
|
<div id="current-file-{{ $column['name'] }}">
|
||||||
@else
|
<a class="edit-button view" href="{{ $current_file }}" target="_blank">View {{ strtoupper($column['ext']) }}</a>
|
||||||
<div class="no-file">(No {{ strtoupper($column['ext']) }} Set)</div>
|
|
||||||
|
@if(array_key_exists('delete', $column) && $column['delete'])
|
||||||
|
<span class="edit-button delete file" data-name="{{ $column['name'] }}" data-ext="{{ $column['ext'] }}">
|
||||||
|
Delete {{ strtoupper($column['ext']) }}
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@elseif($column['type'] == 'display')
|
@elseif($column['type'] == 'display')
|
||||||
<div class="text-display">{{ $value }}</div>
|
<div class="text-display">{{ $value }}</div>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
@section('dashboard-body')
|
@section('dashboard-body')
|
||||||
<div id="edit-list-wrapper">
|
<div id="edit-list-wrapper">
|
||||||
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}" />
|
<input type="hidden" id="token" value="{{ csrf_token() }}" />
|
||||||
|
|
||||||
@if($filter)
|
@if($filter)
|
||||||
<input id="filter-input" class="search" placeholder="Filter" />
|
<input id="filter-input" class="search" placeholder="Filter" />
|
||||||
|
|
|
@ -38,6 +38,8 @@ Route::group([ 'prefix' => 'dashboard' ], function() {
|
||||||
Route::post('/edit', 'DashboardController@postEdit');
|
Route::post('/edit', 'DashboardController@postEdit');
|
||||||
Route::post('/reorder', 'DashboardController@postReorder');
|
Route::post('/reorder', 'DashboardController@postReorder');
|
||||||
Route::delete('/delete', 'DashboardController@deleteDelete');
|
Route::delete('/delete', 'DashboardController@deleteDelete');
|
||||||
|
Route::delete('/image-delete', 'DashboardController@deleteImageDelete');
|
||||||
|
Route::delete('/file-delete', 'DashboardController@deleteFileDelete');
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue