2018-04-26 22:33:18 -04:00
// global variables
2018-05-10 13:21:29 -04:00
const fadeTime = 250 ;
2018-04-24 20:38:04 -04:00
2018-04-26 22:33:18 -04:00
// declare a reverse function for jquery
jQuery . fn . reverse = [ ] . reverse ;
2018-05-10 13:21:29 -04:00
// show or hide the loading modal
function loadingModal ( action ) {
const $loadingModal = $ ( "#loading-modal" ) ;
2018-04-24 20:38:04 -04:00
2018-05-10 13:21:29 -04:00
if ( action === "show" ) {
$loadingModal . css ( {
visibility : "visible" ,
opacity : 1
} ) ;
} else if ( action === "hide" ) {
$loadingModal . css ( { opacity : 0 } ) ;
2018-04-24 20:38:04 -04:00
2018-05-10 13:21:29 -04:00
setTimeout ( function ( ) {
$loadingModal . css ( { visibility : "hidden" } ) ;
} , fadeTime ) ;
}
2018-04-26 01:21:14 -04:00
}
2018-04-24 20:38:04 -04:00
2016-01-26 23:20:08 -05:00
// show the confirmation modal and run the supplied command if confirm is pressed
2018-01-21 20:55:07 -05:00
function askConfirmation ( message , command , cancelCommand ) {
2016-08-01 21:26:54 -04:00
const $confirmationModal = $ ( "#confirmation-modal" ) ,
2018-04-16 00:45:32 -04:00
$heading = $confirmationModal . find ( ".card-header" ) ,
2016-08-01 21:26:54 -04:00
$cancelButton = $confirmationModal . find ( ".btn.cancel-button" ) ,
2018-04-24 20:38:04 -04:00
$confirmButton = $confirmationModal . find ( ".btn.confirm-button" ) ;
2016-01-26 23:20:08 -05:00
// close the confirmation modal and unbind its events
2016-08-01 21:26:54 -04:00
const closeConfirmationModal = function ( ) {
2016-01-26 23:20:08 -05:00
// unbind events
2018-04-26 01:21:14 -04:00
$ ( document ) . off ( "keydown" , escapeModal ) ;
2016-08-01 21:26:54 -04:00
$cancelButton . off ( "click" , closeConfirmationModal ) ;
$confirmButton . off ( "click" , confirmModal ) ;
2016-01-26 23:20:08 -05:00
// hide the modal
$confirmationModal . css ( { opacity : 0 } ) ;
2018-04-24 20:38:04 -04:00
setTimeout ( function ( ) {
2018-06-26 20:58:03 -04:00
// set visibility to hidden
2018-04-24 20:38:04 -04:00
$confirmationModal . css ( { visibility : "hidden" } ) ;
2018-06-26 20:58:03 -04:00
// clear the heading
$heading . empty ( ) ;
2018-04-24 20:38:04 -04:00
} , fadeTime ) ;
2016-01-26 23:20:08 -05:00
} ;
// close the modal if the escape button is pressed
2016-08-01 21:26:54 -04:00
const escapeModal = function ( e ) {
2018-04-26 01:21:14 -04:00
if ( e . keyCode === 27 ) {
closeConfirmationModal ( ) ;
} else {
e . preventDefault ( ) ;
}
2016-01-26 23:20:08 -05:00
} ;
// functionality to run when clicking the confirm button
2016-08-01 21:26:54 -04:00
const confirmModal = function ( ) {
2016-01-26 23:20:08 -05:00
command ( ) ;
closeConfirmationModal ( ) ;
} ;
2018-01-21 20:55:07 -05:00
// functionality to run when clicking the cancel button
const cancelModal = function ( ) {
if ( cancelCommand !== undefined ) {
cancelCommand ( ) ;
}
closeConfirmationModal ( ) ;
} ;
2016-01-26 23:20:08 -05:00
// hide the modal when the cancel button is pressed
2018-01-21 20:55:07 -05:00
$cancelButton . on ( "click" , cancelModal ) ;
2016-01-26 23:20:08 -05:00
// hide the modal when the escape key is pressed
2018-04-26 01:21:14 -04:00
$ ( document ) . on ( "keydown" , escapeModal ) ;
2016-01-26 23:20:08 -05:00
// run the command and hide the modal when the confirm button is pressed
2016-08-01 21:26:54 -04:00
$confirmButton . on ( "click" , confirmModal ) ;
2016-01-26 23:20:08 -05:00
// set the heading with the supplied message
$heading . text ( message ) ;
// show the confirmation modal
$confirmationModal . css ( {
2016-08-01 21:26:54 -04:00
visibility : "visible" ,
2016-01-26 23:20:08 -05:00
opacity : 1
} ) ;
}
// show the alert modal and display the provided message until accept is pressed
function showAlert ( message , command ) {
2016-08-01 21:26:54 -04:00
const $alertModal = $ ( "#alert-modal" ) ,
$message = $alertModal . find ( ".message" ) ,
2018-04-24 20:38:04 -04:00
$acceptButton = $alertModal . find ( ".btn.accept-button" ) ;
2016-01-26 23:20:08 -05:00
// close the alert modal and unbind its events
2016-08-01 21:26:54 -04:00
const closeAlertModal = function ( ) {
2016-01-26 23:20:08 -05:00
// unbind events
2018-04-26 01:21:14 -04:00
$ ( document ) . off ( "keydown" , escapeModal ) ;
2016-08-01 21:26:54 -04:00
$acceptButton . off ( "click" , closeAlertModal ) ;
2016-01-26 23:20:08 -05:00
// clear the message
$message . empty ( ) ;
// hide the modal
$alertModal . css ( { opacity : 0 } ) ;
2018-04-26 01:21:14 -04:00
setTimeout ( function ( ) {
$alertModal . css ( { visibility : "hidden" } ) ;
} , fadeTime ) ;
2016-01-26 23:20:08 -05:00
// if a command was passed run it now
2018-04-26 01:21:14 -04:00
if ( command !== undefined ) {
command ( ) ;
}
2016-01-26 23:20:08 -05:00
} ;
// close the modal if the escape button is pressed
2016-08-01 21:26:54 -04:00
const escapeModal = function ( e ) {
2018-04-26 01:21:14 -04:00
if ( e . keyCode === 27 ) {
closeAlertModal ( ) ;
} else {
e . preventDefault ( ) ;
}
2016-01-26 23:20:08 -05:00
} ;
// hide the modal when the escape key is pressed
2018-04-26 01:21:14 -04:00
$ ( document ) . on ( "keydown" , escapeModal ) ;
2016-01-26 23:20:08 -05:00
// hide the modal when the accept button is pressed
2016-08-01 21:26:54 -04:00
$acceptButton . on ( "click" , closeAlertModal ) ;
2016-01-26 23:20:08 -05:00
// set the message with the supplied message
2020-04-24 00:22:42 -04:00
$message . html ( message ) ;
2016-01-26 23:20:08 -05:00
// show the alert modal
$alertModal . css ( {
2016-08-01 21:26:54 -04:00
visibility : "visible" ,
2016-01-26 23:20:08 -05:00
opacity : 1
} ) ;
}
// initialize edit list functionality
function editListInit ( ) {
2016-08-01 21:26:54 -04:00
const editList = document . getElementById ( "edit-list" ) ,
2016-01-26 23:20:08 -05:00
$editList = $ ( editList ) ,
2018-01-21 20:55:07 -05:00
$token = $ ( "#token" ) ,
2018-04-18 00:38:11 -04:00
model = $editList . data ( "model" ) ;
2016-01-26 23:20:08 -05:00
// initialize delete button functionality
2016-08-01 21:26:54 -04:00
const deleteButtonInit = function ( ) {
const $deleteButtons = $ ( ".btn.delete-button" ) ;
2016-01-26 23:20:08 -05:00
2016-08-01 21:26:54 -04:00
$deleteButtons . on ( "click" , function ( ) {
const $this = $ ( this ) ,
$listItem = $this . closest ( ".list-group-item" ) ,
itemId = $listItem . data ( "id" ) ;
2016-01-26 23:20:08 -05:00
2016-08-01 21:26:54 -04:00
askConfirmation ( "Are you sure you want to delete this?" , function ( ) {
2016-01-26 23:20:08 -05:00
$ . ajax ( {
2016-08-01 21:26:54 -04:00
type : "DELETE" ,
url : "/dashboard/delete" ,
2016-01-26 23:20:08 -05:00
data : {
2016-08-01 21:26:54 -04:00
model : model ,
id : itemId ,
2018-01-21 20:55:07 -05:00
_token : $token . val ( )
2016-01-26 23:20:08 -05:00
}
} ) . always ( function ( response ) {
2016-08-01 21:26:54 -04:00
if ( response === "success" ) {
2016-01-26 23:20:08 -05:00
$listItem . slideUp ( 150 , function ( ) { $listItem . remove ( ) ; } ) ;
} else {
2018-04-24 20:38:04 -04:00
showAlert ( "Failed to delete record" ) ;
2016-01-26 23:20:08 -05:00
}
} ) ;
} ) ;
} ) ;
} ;
2017-01-04 23:23:26 -05:00
// initialize action button functionality
const actionButtonInit = function ( ) {
const $actionButtons = $ ( ".btn.action-button" ) ;
$actionButtons . on ( "click" , function ( ) {
const $this = $ ( this ) ,
$listItem = $this . closest ( ".list-group-item" ) ,
itemId = $listItem . data ( "id" ) ,
confirmationMessage = $this . data ( "confirmation" ) ,
successMessage = $this . data ( "success" ) ,
errorMessage = $this . data ( "error" ) ,
postUrl = $this . data ( "url" ) ;
askConfirmation ( confirmationMessage , function ( ) {
$ . ajax ( {
type : "POST" ,
url : postUrl ,
data : {
id : itemId ,
2018-01-21 20:55:07 -05:00
_token : $token . val ( )
2017-01-04 23:23:26 -05:00
}
} ) . always ( function ( response ) {
if ( response === "success" ) {
showAlert ( successMessage ) ;
} else {
showAlert ( "ERROR: " + errorMessage ) ;
}
} ) ;
} ) ;
} ) ;
} ;
2016-01-26 23:20:08 -05:00
// initialize sort functionality if data-sort is set
2016-08-01 21:26:54 -04:00
const sortRowInit = function ( ) {
let sortOrder = { } , sortCol , sortable ;
2016-01-26 23:20:08 -05:00
2016-08-01 21:26:54 -04:00
if ( $editList . attr ( "data-sort" ) ) {
sortCol = $editList . data ( "sort" ) ;
sortable = Sortable . create ( editList , {
handle : ".sort-icon" ,
2020-04-23 22:17:13 -04:00
2016-01-26 23:20:08 -05:00
onUpdate : function ( ) {
// update the sortOrder object based on the updated order
2016-08-01 21:26:54 -04:00
$editList . find ( ".list-group-item" ) . reverse ( ) . each ( function ( index ) {
sortOrder [ $ ( this ) . data ( "id" ) ] = index ;
2016-01-26 23:20:08 -05:00
} ) ;
$ . ajax ( {
2016-08-01 21:26:54 -04:00
type : "POST" ,
url : "/dashboard/reorder" ,
2016-01-26 23:20:08 -05:00
data : {
2016-08-01 21:26:54 -04:00
model : model ,
order : sortOrder ,
2016-01-26 23:20:08 -05:00
column : sortCol ,
2018-01-21 20:55:07 -05:00
_token : $token . val ( )
2016-01-26 23:20:08 -05:00
}
} ) . always ( function ( response ) {
2016-08-01 21:26:54 -04:00
if ( response !== "success" ) {
2018-04-24 20:38:04 -04:00
showAlert ( "Sorting failed" , function ( ) {
2016-01-26 23:20:08 -05:00
document . location . reload ( true ) ;
} ) ;
}
} ) ;
}
} ) ;
}
} ;
2016-12-22 00:20:44 -05:00
// initialize filter functionality if the filter-input element exists
const filterInputInit = function ( ) {
const $filter = $ ( "#filter-input" ) ;
if ( $filter . length ) {
// empty the filter
$filter . val ( "" ) ;
2018-01-13 01:16:19 -05:00
// initialize the filter list functionality
2016-12-22 00:20:44 -05:00
const filterList = new List ( "edit-list-wrapper" , {
2018-01-12 23:58:43 -05:00
valueNames : [ "title-column" ]
2016-12-22 00:20:44 -05:00
} ) ;
2018-01-13 01:16:19 -05:00
// add/remove a filtered class to identify when the list is filtered
$filter . on ( "input" , function ( ) {
if ( $filter . val ( ) === "" ) {
$editList . removeClass ( "filtered" ) ;
} else {
$editList . addClass ( "filtered" ) ;
}
} ) ;
2016-12-22 00:20:44 -05:00
}
} ;
2020-04-24 00:22:42 -04:00
// initialize search functionality if the search-form element exists
const searchFormInit = function ( ) {
const $form = $ ( "#search-form" ) ;
if ( $form . length ) {
$form . on ( "submit" , function ( e ) {
const term = $form . find ( ".search" ) . val ( ) ;
let url = $form . data ( "url" ) ;
e . preventDefault ( ) ;
if ( term !== "" ) {
url += ` ?search= ${ term } ` ;
}
window . location . href = url ;
} ) ;
}
} ;
2016-01-26 23:20:08 -05:00
deleteButtonInit ( ) ;
2017-01-04 23:23:26 -05:00
actionButtonInit ( ) ;
2016-01-26 23:20:08 -05:00
sortRowInit ( ) ;
2016-12-22 00:20:44 -05:00
filterInputInit ( ) ;
2020-04-24 00:22:42 -04:00
searchFormInit ( ) ;
2016-01-26 23:20:08 -05:00
}
2018-04-26 22:36:35 -04:00
// initialize edit item functionality
2016-01-26 23:20:08 -05:00
function editItemInit ( ) {
2016-08-01 21:26:54 -04:00
const $editItem = $ ( "#edit-item" ) ,
$submit = $ ( "#submit" ) ,
$backButton = $ ( "#back" ) ,
$textInputs = $ ( ".text-input" ) ,
2020-04-24 00:22:42 -04:00
$currencyInputs = $ ( ".currency-input" ) ,
2018-01-15 23:43:20 -05:00
$datePickers = $ ( ".date-picker" ) ,
2016-08-01 21:26:54 -04:00
$mkdEditors = $ ( ".mkd-editor" ) ,
2018-01-18 22:29:49 -05:00
$fileUploads = $ ( ".file-upload" ) ,
2018-01-11 01:13:58 -05:00
$imgUploads = $ ( ".image-upload" ) ,
2020-04-24 00:22:42 -04:00
$lists = $ ( ".list" ) ,
2018-01-21 20:55:07 -05:00
$token = $ ( "#token" ) ,
2016-08-01 21:26:54 -04:00
model = $editItem . data ( "model" ) ,
2017-01-03 22:55:12 -05:00
id = $editItem . data ( "id" ) ,
operation = id === "new" ? "create" : "update" ;
2016-08-01 21:26:54 -04:00
let allowTimes = [ ] ,
2020-02-25 17:43:02 -05:00
easymde = [ ] ,
2016-01-26 23:20:08 -05:00
formData = { } ,
2016-08-01 21:26:54 -04:00
submitting = false ,
hours ,
2018-01-12 23:19:24 -05:00
minutes ,
changes = false ;
2016-01-26 23:20:08 -05:00
// fill the formData object with data from all the form fields
2016-08-01 21:26:54 -04:00
const getFormData = function ( ) {
2016-01-26 23:20:08 -05:00
// function to add a column and value to the formData object
2020-04-24 00:22:42 -04:00
const addFormData = function ( type , column , value ) {
2016-01-26 23:20:08 -05:00
// add the value to a key with the column name
formData [ column ] = value ;
// add the column to the array of columns
2020-04-24 00:22:42 -04:00
formData . columns . push ( { type : type , name : column } ) ;
2016-01-26 23:20:08 -05:00
} ;
// reset the formData object
formData = { } ;
// add the database model row id and _token
formData . model = model ;
formData . id = id ;
formData . _token = $token . val ( ) ;
// create an empty array to contain the list of columns
formData . columns = [ ] ;
2020-04-24 00:22:42 -04:00
// add values from the contents of text-input elements
2016-01-26 23:20:08 -05:00
$textInputs . each ( function ( ) {
2016-08-01 21:26:54 -04:00
const $this = $ ( this ) ,
column = $this . attr ( "id" ) ,
2016-01-26 23:20:08 -05:00
value = $this . val ( ) ;
2020-04-24 00:22:42 -04:00
addFormData ( "text" , column , value ) ;
2016-01-26 23:20:08 -05:00
} ) ;
2020-04-24 00:22:42 -04:00
// add values from the contents of date-picker elements
2018-01-15 23:43:20 -05:00
$datePickers . each ( function ( ) {
2016-08-01 21:26:54 -04:00
const $this = $ ( this ) ,
column = $this . attr ( "id" ) ,
2019-07-17 01:21:00 -04:00
value = $this . val ( ) ;
2016-01-26 23:20:08 -05:00
2020-04-24 00:22:42 -04:00
addFormData ( "date" , column , value ) ;
2016-01-26 23:20:08 -05:00
} ) ;
2020-04-24 00:22:42 -04:00
// add values from the contents of currency-input elements
$currencyInputs . each ( function ( ) {
const $this = $ ( this ) ,
column = $this . attr ( "id" ) ,
value = AutoNumeric . getNumericString ( this ) ;
addFormData ( "text" , column , value ) ;
} ) ;
// add values from the contents of the markdown editor for mkd-editor elements
2016-01-26 23:20:08 -05:00
$mkdEditors . each ( function ( ) {
2016-08-01 21:26:54 -04:00
const $this = $ ( this ) ,
column = $this . attr ( "id" ) ,
2020-02-25 17:43:02 -05:00
value = easymde [ column ] . value ( ) ;
2016-01-26 23:20:08 -05:00
2020-04-24 00:22:42 -04:00
addFormData ( "text" , column , value ) ;
} ) ;
// add values from list-items inputs
$lists . each ( function ( ) {
const $this = $ ( this ) ,
column = $this . attr ( "id" ) ,
value = [ ] ;
$this . find ( ".list-items .list-items-row" ) . each ( function ( index , row ) {
const rowData = { } ;
$ ( row ) . find ( ".list-items-row-input-inner" ) . each ( function ( index , input ) {
const $input = $ ( input ) ,
column = $input . data ( "column" ) ,
value = $input . val ( ) ;
rowData [ column ] = value ;
} ) ;
value . push ( rowData ) ;
} ) ;
addFormData ( "list" , column , value ) ;
2016-01-26 23:20:08 -05:00
} ) ;
} ;
2018-01-18 22:29:49 -05:00
const uploadFile = function ( row _id , currentFile ) {
let file , fileUpload ;
2016-08-01 21:26:54 -04:00
2016-01-26 23:20:08 -05:00
// functionality to run on success
2016-08-01 21:26:54 -04:00
const returnSuccess = function ( ) {
2018-05-10 13:21:29 -04:00
loadingModal ( "hide" ) ;
2018-04-23 23:20:35 -04:00
window . location . href = ` /dashboard/edit/ ${ model } / ${ row _id } ` ;
2016-01-26 23:20:08 -05:00
} ;
2018-01-18 22:29:49 -05:00
// add the file from the file upload box for file-upload class elements
if ( $fileUploads . length >= currentFile + 1 ) {
fileUpload = $fileUploads [ currentFile ] ;
if ( $ ( fileUpload ) . val ( ) !== "" ) {
file = new FormData ( ) ;
// add the file, id and model to the formData variable
file . append ( "file" , fileUpload . files [ 0 ] ) ;
file . append ( "name" , $ ( fileUpload ) . attr ( "name" ) ) ;
file . append ( "id" , row _id ) ;
file . append ( "model" , model ) ;
file . append ( "ext" , $ ( fileUpload ) . data ( "ext" ) ) ;
$ . ajax ( {
type : "POST" ,
url : "/dashboard/file-upload" ,
data : file ,
processData : false ,
contentType : false ,
beforeSend : function ( xhr ) { xhr . setRequestHeader ( "X-CSRF-TOKEN" , $token . val ( ) ) ; }
} ) . always ( function ( response ) {
if ( response === "success" ) {
uploadFile ( row _id , currentFile + 1 ) ;
} else {
2018-05-10 13:21:29 -04:00
loadingModal ( "hide" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "Failed to upload file" , function ( ) {
submitting = false ;
} ) ;
2018-01-18 22:29:49 -05:00
}
} ) ;
} else {
uploadFile ( row _id , currentFile + 1 ) ;
}
} else {
returnSuccess ( ) ;
}
} ;
const uploadImage = function ( row _id , currentImage ) {
let file , imgUpload ;
// functionality to run on success
const returnSuccess = function ( ) {
uploadFile ( row _id , 0 ) ;
} ;
2016-01-26 23:20:08 -05:00
// add the image from the image upload box for image-upload class elements
2018-01-11 01:13:58 -05:00
if ( $imgUploads . length >= currentImage + 1 ) {
imgUpload = $imgUploads [ currentImage ] ;
2016-01-26 23:20:08 -05:00
2018-01-11 01:13:58 -05:00
if ( $ ( imgUpload ) . val ( ) !== "" ) {
file = new FormData ( ) ;
2016-01-26 23:20:08 -05:00
2018-01-11 01:13:58 -05:00
// add the file, id and model to the formData variable
file . append ( "file" , imgUpload . files [ 0 ] ) ;
file . append ( "name" , $ ( imgUpload ) . attr ( "name" ) ) ;
file . append ( "id" , row _id ) ;
file . append ( "model" , model ) ;
$ . ajax ( {
type : "POST" ,
url : "/dashboard/image-upload" ,
data : file ,
processData : false ,
contentType : false ,
beforeSend : function ( xhr ) { xhr . setRequestHeader ( "X-CSRF-TOKEN" , $token . val ( ) ) ; }
} ) . always ( function ( response ) {
if ( response === "success" ) {
uploadImage ( row _id , currentImage + 1 ) ;
} else {
2018-05-10 13:21:29 -04:00
loadingModal ( "hide" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "Failed to upload image" , function ( ) {
submitting = false ;
} ) ;
2018-01-11 01:13:58 -05:00
}
} ) ;
} else {
uploadImage ( row _id , currentImage + 1 ) ;
}
2016-01-26 23:20:08 -05:00
} else {
returnSuccess ( ) ;
}
} ;
2018-01-21 23:07:21 -05:00
const contentChanged = function ( ) {
changes = true ;
2018-04-16 00:45:32 -04:00
$submit . removeClass ( "no-input" ) ;
2018-01-21 23:07:21 -05:00
} ;
2020-04-24 00:22:42 -04:00
// initialize image deletion
2018-01-21 20:55:07 -05:00
$ ( ".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 ) ;
2018-04-26 01:21:14 -04:00
submitting = false ;
2018-01-21 20:55:07 -05:00
} else {
2018-04-26 01:21:14 -04:00
showAlert ( "Failed to delete image: " + response , function ( ) {
submitting = false ;
} ) ;
2018-01-21 20:55:07 -05:00
}
} ) ;
} , function ( ) {
submitting = false ;
} ) ;
}
} ) ;
2020-04-24 00:22:42 -04:00
// initialize file deletion
2018-01-21 20:55:07 -05:00
$ ( ".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 ) ;
2018-04-26 01:21:14 -04:00
submitting = false ;
2018-01-21 20:55:07 -05:00
} else {
2018-04-26 01:21:14 -04:00
showAlert ( "Failed to delete file: " + response , function ( ) {
submitting = false ;
} ) ;
2018-01-21 20:55:07 -05:00
}
} ) ;
} , function ( ) {
submitting = false ;
} ) ;
}
} ) ;
2020-04-24 00:22:42 -04:00
// initialize list item functionality
$lists . each ( function ( index , list ) {
const $list = $ ( list ) ,
$template = $list . find ( ".list-template" ) ,
$items = $list . find ( ".list-items" ) ;
let sortable = undefined ;
const initSort = function ( ) {
if ( typeof sortable !== "undefined" ) {
sortable . destroy ( ) ;
}
sortable = Sortable . create ( $items [ 0 ] , {
handle : ".sort-icon" ,
onUpdate : contentChanged
} ) ;
} ;
const initDelete = function ( ) {
$items . find ( ".list-items-row" ) . each ( function ( index , row ) {
const $row = $ ( row ) ;
// initialize delete button functionality
$row . find ( ".list-items-row-button" ) . off ( "click" ) . on ( "click" , function ( ) {
$row . remove ( ) ;
initSort ( ) ;
contentChanged ( ) ;
} ) ;
} ) ;
} ;
const initList = function ( ) {
$list . find ( ".list-data-row" ) . each ( function ( rowIndex , row ) {
// Add the values from the current data row to the template
$ ( row ) . find ( ".list-data-row-item" ) . each ( function ( itemIndex , item ) {
const $item = $ ( item ) ,
column = $item . data ( "column" ) ,
value = $item . data ( "value" ) ;
$template . find ( ".list-items-row-input-inner" ) . each ( function ( inputIndex , input ) {
const $input = $ ( input ) ;
if ( $input . data ( "column" ) === column ) {
$input . val ( value ) ;
}
} ) ;
} ) ;
// Add the populated template to the list of items then clear the template values
$template . find ( ".list-items-row" ) . clone ( ) . appendTo ( $items ) ;
$template . find ( ".list-items-row-input-inner" ) . val ( "" ) ;
} ) ;
initSort ( ) ;
initDelete ( ) ;
} ;
$list . find ( ".list-add-button" ) . on ( "click" , function ( ) {
$template . find ( ".list-items-row" ) . clone ( ) . appendTo ( $items ) ;
initDelete ( ) ;
initSort ( ) ;
contentChanged ( ) ;
} ) ;
initList ( ) ;
} ) ;
// allow the date picker start time selection to start on the hour and every 15 minutes after
2016-08-01 21:26:54 -04:00
for ( hours = 0 ; hours <= 23 ; hours ++ ) {
for ( minutes = 0 ; minutes <= 3 ; minutes ++ ) {
allowTimes . push ( hours + ":" + ( minutes === 0 ? "00" : minutes * 15 ) ) ;
2016-01-26 23:20:08 -05:00
}
}
2020-04-24 00:22:42 -04:00
// enable the datepicker for date-picker elements
2018-01-15 23:43:20 -05:00
$datePickers . each ( function ( ) {
2019-07-17 01:11:09 -04:00
$ ( this ) . flatpickr ( {
enableTime : true
2016-01-26 23:20:08 -05:00
} ) ;
} ) ;
2020-04-24 00:22:42 -04:00
// enable the markdown editor for mkd-editor elements
2016-01-26 23:20:08 -05:00
$mkdEditors . each ( function ( ) {
2016-08-01 21:26:54 -04:00
const $this = $ ( this ) ,
column = $this . attr ( "id" ) ;
2016-01-26 23:20:08 -05:00
2020-02-25 17:43:02 -05:00
easymde [ column ] = new EasyMDE ( {
2016-01-26 23:20:08 -05:00
element : this ,
toolbar : [
2016-08-01 21:26:54 -04:00
"bold" ,
"italic" ,
"|" ,
"heading-1" ,
"heading-2" ,
"heading-3" ,
"|" ,
"quote" ,
"unordered-list" ,
"ordered-list" ,
"link"
2016-01-26 23:20:08 -05:00
] ,
2016-08-01 21:26:54 -04:00
blockStyles : { italic : "_" } ,
2016-01-26 23:20:08 -05:00
autoDownloadFontAwesome : false ,
2016-04-08 18:03:18 -04:00
tabSize : 4 ,
spellChecker : false
2016-01-26 23:20:08 -05:00
} ) ;
setTimeout ( function ( ) {
2018-04-24 20:38:04 -04:00
// load the initial value into the editor
2020-02-25 17:43:02 -05:00
easymde [ column ] . value ( $this . attr ( "value" ) ) ;
easymde [ column ] . codemirror . refresh ( ) ;
2018-04-24 20:38:04 -04:00
2020-02-25 17:43:02 -05:00
// watch for changes to easymde editor contents
easymde [ column ] . codemirror . on ( "change" , contentChanged ) ;
2018-01-21 21:20:13 -05:00
} , 500 ) ;
2016-01-26 23:20:08 -05:00
} ) ;
2020-04-24 00:22:42 -04:00
// enable currency formatting for currency-input elements
new AutoNumeric . multiple ( $currencyInputs . toArray ( ) , {
currencySymbol : "$" ,
rawValueDivisor : 0.01 ,
allowDecimalPadding : false ,
modifyValueOnWheel : false
} ) ;
2018-04-24 20:38:04 -04:00
// watch for changes to input and select element contents
2018-01-21 23:07:21 -05:00
$editItem . find ( "input, select" ) . on ( "input change" , contentChanged ) ;
2018-01-12 23:19:24 -05:00
2016-01-26 23:20:08 -05:00
// initialize back button
2016-08-01 21:26:54 -04:00
$backButton . on ( "click" , function ( ) {
2016-01-26 23:20:08 -05:00
if ( ! submitting ) {
2018-01-12 23:19:24 -05:00
if ( changes ) {
askConfirmation ( "Cancel changes and return to the list?" , function ( ) {
2018-04-18 00:38:11 -04:00
window . location . href = "/dashboard/edit/" + model ;
2018-01-12 23:19:24 -05:00
} ) ;
} else {
2018-04-18 00:38:11 -04:00
window . location . href = "/dashboard/edit/" + model ;
2018-01-12 23:19:24 -05:00
}
2016-01-26 23:20:08 -05:00
}
} ) ;
// initialize submit button
2016-08-01 21:26:54 -04:00
$submit . on ( "click" , function ( ) {
2018-01-12 23:19:24 -05:00
if ( ! submitting && changes ) {
2016-01-26 23:20:08 -05:00
submitting = true ;
// show the loading modal
2018-05-10 13:21:29 -04:00
loadingModal ( "show" ) ;
2016-01-26 23:20:08 -05:00
// populate the formData object
getFormData ( ) ;
// submit the update
2018-05-10 23:22:09 -04:00
if ( Object . keys ( formData . columns ) . length ) {
$ . ajax ( {
type : "POST" ,
url : "/dashboard/update" ,
data : formData
} ) . always ( function ( response ) {
2020-04-24 00:22:42 -04:00
let message = "" ;
2019-01-02 23:56:16 -05:00
if ( ( /^id:[0-9][0-9]*$/ ) . test ( response ) ) {
2018-05-10 23:22:09 -04:00
uploadImage ( response . replace ( /^id:/ , "" ) , 0 ) ;
} else {
loadingModal ( "hide" ) ;
2018-04-26 01:21:14 -04:00
2020-04-24 00:22:42 -04:00
if ( ( /^not-unique:/ ) . test ( response ) ) {
message = ` <strong> ${ response . replace ( /'/g , "" ) . replace ( /^[^:]*:/ , "" ) . replace ( /,([^,]*)$/ , "</strong> and <strong>$1" ) . replace ( /,/g , "</strong>, <strong>" ) } </strong> must be unique ` ;
} else if ( ( /^required:/ ) . test ( response ) ) {
message = ` <strong> ${ response . replace ( /'/g , "" ) . replace ( /^[^:]*:/ , "" ) . replace ( /,([^,]*)$/ , "</strong> and <strong>$1" ) . replace ( /,/g , "</strong>, <strong>" ) } </strong> must not be empty ` ;
} else {
message = ` Failed to <strong> ${ operation } </strong> record ` ;
}
showAlert ( message , function ( ) {
2018-05-10 23:22:09 -04:00
submitting = false ;
} ) ;
}
} ) ;
} else {
uploadImage ( formData . id , 0 ) ;
}
2016-01-26 23:20:08 -05:00
}
} ) ;
}
2018-04-26 22:36:35 -04:00
// initialize the user profile image functionality
2018-04-25 01:22:33 -04:00
function userProfileImageInit ( ) {
const $form = $ ( "#user-profile-image" ) ,
$upload = $ ( "#profile-image-upload" ) ,
$delete = $ ( "#profile-image-delete" ) ,
$token = $ ( "#token" ) ,
2018-04-25 01:33:17 -04:00
$display = $form . find ( ".image-display" ) . first ( ) ,
defaultImage = $display . data ( "default" ) ;
2018-04-25 01:22:33 -04:00
let file ,
submitting = false ;
$upload . on ( "change" , function ( ) {
if ( $upload . val ( ) !== "" && ! submitting ) {
submitting = true ;
askConfirmation ( "Update your user profile image?" , function ( ) {
// show the loading modal
2018-05-10 13:21:29 -04:00
loadingModal ( "show" ) ;
2018-04-25 01:22:33 -04:00
// add the image to the form data
file = new FormData ( ) ;
file . append ( "file" , $upload [ 0 ] . files [ 0 ] ) ;
// submit the form data
$ . ajax ( {
type : "POST" ,
url : "/dashboard/user/profile-image-upload" ,
data : file ,
processData : false ,
contentType : false ,
beforeSend : function ( xhr ) { xhr . setRequestHeader ( "X-CSRF-TOKEN" , $token . val ( ) ) ; }
} ) . always ( function ( response ) {
2018-05-10 13:21:29 -04:00
loadingModal ( "hide" ) ;
2018-04-25 01:22:33 -04:00
2019-01-02 23:56:16 -05:00
if ( ( /\.png\?version=/ ) . test ( response ) ) {
2018-04-25 01:33:17 -04:00
$display . css ( { backgroundImage : ` url( ${ response } ) ` } ) ;
2018-04-25 01:22:33 -04:00
$delete . removeClass ( "inactive" ) ;
2018-04-26 01:21:14 -04:00
submitting = false ;
2018-04-25 01:22:33 -04:00
} else {
2018-04-26 01:21:14 -04:00
showAlert ( "Failed to upload image" , function ( ) {
submitting = false ;
} ) ;
2018-04-25 01:22:33 -04:00
}
} ) ;
} , function ( ) {
$upload . val ( "" ) ;
submitting = false ;
} ) ;
}
} ) ;
$delete . on ( "click" , function ( ) {
if ( ! submitting ) {
submitting = true ;
askConfirmation ( "Delete your profile image?" , function ( ) {
// delete the profile image
$ . ajax ( {
type : "DELETE" ,
url : "/dashboard/user/profile-image-delete" ,
data : {
_token : $token . val ( )
}
} ) . always ( function ( response ) {
if ( response === "success" ) {
2018-04-25 01:33:17 -04:00
$display . css ( { backgroundImage : ` url( ${ defaultImage } ) ` } ) ;
2018-04-25 01:22:33 -04:00
$delete . addClass ( "inactive" ) ;
2018-04-26 01:21:14 -04:00
submitting = false ;
2018-04-25 01:22:33 -04:00
} else {
2018-04-26 01:21:14 -04:00
showAlert ( "Failed to delete profile image" , function ( ) {
submitting = false ;
} ) ;
2018-04-25 01:22:33 -04:00
}
} ) ;
} , function ( ) {
submitting = false ;
} ) ;
}
} ) ;
}
2018-04-26 22:36:35 -04:00
// initialize the user profile update functionality
2018-04-25 23:27:45 -04:00
function userProfileUpdateInit ( ) {
const $form = $ ( "#user-profile-update" ) ,
$submit = $form . find ( ".submit-button" ) ,
$inputs = $form . find ( "input" ) ,
$name = $ ( "#name" ) ,
$website = $ ( "#website" ) ,
$facebook = $ ( "#facebook" ) ,
$soundcloud = $ ( "#soundcloud" ) ,
$instagram = $ ( "#instagram" ) ,
$twitter = $ ( "#twitter" ) ,
$token = $ ( "#token" ) ;
let formData = { } ,
submitting = false ;
const getFormData = function ( ) {
formData = {
name : $name . val ( ) ,
website : $website . val ( ) ,
facebook : $facebook . val ( ) ,
soundcloud : $soundcloud . val ( ) ,
instagram : $instagram . val ( ) ,
twitter : $twitter . val ( ) ,
_token : $token . val ( )
} ;
} ;
// remove the error class from an input and enable submit when its value changes
$inputs . on ( "input change" , function ( ) {
$submit . removeClass ( "no-input" ) ;
$ ( this ) . removeClass ( "error" ) ;
} ) ;
// initialize submit button
$submit . on ( "click" , function ( ) {
if ( ! submitting ) {
submitting = true ;
// remove the error class from inputs
$inputs . removeClass ( "error" ) ;
// show the loading modal
2018-05-10 13:21:29 -04:00
loadingModal ( "show" ) ;
2018-04-25 23:27:45 -04:00
// populate the formData object
getFormData ( ) ;
// submit the update
$ . ajax ( {
type : "POST" ,
url : "/dashboard/user/profile-update" ,
data : formData
} ) . always ( function ( response ) {
2018-05-10 13:21:29 -04:00
loadingModal ( "hide" ) ;
2018-04-25 23:27:45 -04:00
if ( response === "success" ) {
$submit . addClass ( "no-input" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "User profile updated successfully" , function ( ) {
submitting = false ;
} ) ;
2018-04-25 23:27:45 -04:00
} else {
// add the error class to fields that haven't been filled correctly
for ( let errorName in response . responseJSON . errors ) {
if ( $form . find ( ` [name=' ${ errorName } '] ` ) . length ) {
$form . find ( ` [name=' ${ errorName } '] ` ) . addClass ( "error" ) ;
}
}
2018-04-26 01:21:14 -04:00
showAlert ( "Error updating user profile" , function ( ) {
submitting = false ;
} ) ;
2018-04-25 23:27:45 -04:00
}
} ) ;
}
} ) ;
}
2018-04-26 22:36:35 -04:00
// initialize the user password update functionality
2018-04-25 23:27:45 -04:00
function userPasswordUpdateInit ( ) {
const $form = $ ( "#user-password-update" ) ,
2018-04-24 20:38:04 -04:00
$submit = $form . find ( ".submit-button" ) ,
$inputs = $form . find ( "input" ) ,
$oldpass = $ ( "#oldpass" ) ,
$newpass = $ ( "#newpass" ) ,
$newpassConfirmation = $ ( "#newpass_confirmation" ) ,
$token = $ ( "#token" ) ;
let formData = { } ,
submitting = false ;
const getFormData = function ( ) {
formData = {
oldpass : $oldpass . val ( ) ,
newpass : $newpass . val ( ) ,
newpass _confirmation : $newpassConfirmation . val ( ) ,
_token : $token . val ( )
} ;
} ;
// remove the error class from inputs and enable submit if all inputs have data when changes are made
$inputs . on ( "input change" , function ( ) {
let enableSubmit = true ;
for ( let i = 0 ; i < $inputs . length ; i ++ ) {
if ( $inputs [ i ] . value === "" ) {
enableSubmit = false ;
break ;
}
}
if ( enableSubmit ) {
$submit . removeClass ( "no-input" ) ;
} else {
$submit . addClass ( "no-input" ) ;
}
$inputs . removeClass ( "error" ) ;
} ) ;
// initialize submit button
$submit . on ( "click" , function ( ) {
if ( ! submitting ) {
submitting = true ;
// remove the error class from inputs
$inputs . removeClass ( "error" ) ;
// show the loading modal
2018-05-10 13:21:29 -04:00
loadingModal ( "show" ) ;
2018-04-24 20:38:04 -04:00
// populate the formData object
getFormData ( ) ;
if ( formData . newpass !== formData . newpass _confirmation ) {
// fail with an error if the newpass and newpass_confirmation don't match
$newpassConfirmation . val ( "" ) ;
$newpass . addClass ( "error" ) ;
$newpassConfirmation . addClass ( "error" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "New passwords do not match" , function ( ) {
submitting = false ;
} ) ;
2018-04-24 20:38:04 -04:00
} else {
// submit the update
$ . ajax ( {
type : "POST" ,
2018-04-25 01:22:33 -04:00
url : "/dashboard/user/password-update" ,
2018-04-24 20:38:04 -04:00
data : formData
} ) . always ( function ( response ) {
2018-05-10 13:21:29 -04:00
loadingModal ( "hide" ) ;
2018-04-24 20:38:04 -04:00
2018-04-25 01:22:33 -04:00
if ( response === "success" ) {
$inputs . val ( "" ) . trigger ( "change" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "Password updated successfully" , function ( ) {
submitting = false ;
} ) ;
2018-04-25 01:22:33 -04:00
} else if ( response === "old-password-fail" ) {
$oldpass . addClass ( "error" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "Old password is not correct" , function ( ) {
submitting = false ;
} ) ;
2018-04-24 20:38:04 -04:00
} else {
2018-04-25 01:22:33 -04:00
$newpass . addClass ( "error" ) ;
$newpassConfirmation . val ( "" ) ;
2018-04-26 01:21:14 -04:00
showAlert ( "New password must be at least 6 characters" , function ( ) {
submitting = false ;
} ) ;
2018-04-24 20:38:04 -04:00
}
} ) ;
}
}
} ) ;
}
2018-04-26 22:36:35 -04:00
// run the respective initialization functions for each form on the current page
2016-01-26 23:20:08 -05:00
$ ( document ) . ready ( function ( ) {
2016-08-01 21:26:54 -04:00
if ( $ ( "#edit-list" ) . length ) {
2016-01-26 23:20:08 -05:00
editListInit ( ) ;
2018-04-24 20:38:04 -04:00
}
if ( $ ( "#edit-item" ) . length ) {
2016-01-26 23:20:08 -05:00
editItemInit ( ) ;
}
2018-04-24 20:38:04 -04:00
2018-04-25 01:22:33 -04:00
if ( $ ( "#user-profile-image" ) . length ) {
userProfileImageInit ( ) ;
}
2018-04-25 23:27:45 -04:00
if ( $ ( "#user-profile-update" ) . length ) {
userProfileUpdateInit ( ) ;
}
if ( $ ( "#user-password-update" ) . length ) {
userPasswordUpdateInit ( ) ;
2018-04-24 20:38:04 -04:00
}
2016-01-26 23:20:08 -05:00
} ) ;