File: D:/HostingSpaces/netwerkbrabant/netwerkbrabant.nl/wwwroot/js/kms/attributes.js
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/**
* Manages file inputs in a wrapper so that files
*
* @param {HTMLElement} wrapper
* @param {HTML5Uploader} HTML5Uploader
*/
var DocumentManager = /*#__PURE__*/function () {
function DocumentManager(wrapper, HTML5Uploader) {
_classCallCheck(this, DocumentManager);
//Initialize variables
this.constructedSuccessFully = false;
this.wrapper = wrapper;
this.HTML5Uploader = HTML5Uploader;
this.accept = "documentsAccept" in wrapper.dataset ? wrapper.dataset.documentsAccept : undefined;
if ("documentsKey" in wrapper.dataset) {
this.key = wrapper.dataset.documentsKey;
} else {
console.error('Make sure that the wrapper contains the attributes key');
return;
}
this.isSortable = "documentsIsSortable" in wrapper.dataset ? wrapper.dataset.documentsIsSortable === "1" : false;
this.extensionThumbsFolder = "documentsExtensionThumbsFolder" in wrapper.dataset ? wrapper.dataset.documentsExtensionThumbsFolder : '/img/kms/extension_thumbs/';
this.availableExtensionThumbs = "documentsAvailableExtensionThumbs" in wrapper.dataset ? wrapper.dataset.documentsAvailableExtensionThumbs : ['svg', 'pdf', 'zip', 'rar', 'csv', 'xlsx', 'mp3', 'mp4', 'docx', 'doc', 'png', 'jpg', 'jpeg', 'gif'], this.enablePreviewsIfPossible = "documentsEnablePreviewsIfPossible" in wrapper.dataset ? wrapper.dataset.documentsEnablePreviewsIfPossible === "1" : false;
this.maxDocuments = "documentsMaxDocuments" in wrapper.dataset ? wrapper.dataset.documentsMaxDocuments : undefined;
this.eventMap = {};
var form = document.getElementById('entity-form');
if (form) {
var maxUploadSizeInBytes = form.dataset.maxUploadSize;
if (maxUploadSizeInBytes) this.maxUploadSizeInBytes = maxUploadSizeInBytes;
}
this.uploadSizeExceededMessage = 'You cannot upload more files right now. Please save these first before continuing. The limit is:';
if (wrapper == null) {
console.error('The wrapper was not a valid html element. Stopping DocumentManager construction');
return;
}
var documentList = wrapper.getElementsByClassName('files')[0];
var dataInput = wrapper.querySelector('input[name="' + this.key + '-data"]');
if (!documentList) {
console.error('The document uploader needs an ul element with class "files" in the given wrapper');
return;
}
this.documentList = documentList;
if (!dataInput) {
console.error('The document uploader needs an input element with name "' + this.key + '-data" in the given wrapper. It is used to keep track of the states of all documents. Stopping DocumentManager construction');
return;
}
this.dataInput = dataInput;
if (!"uploadedDocuments" in wrapper.dataset) {
console.error('The wrapper must have a uploadedDocuments dataset attribute containing a json string representing the uploaded documents as an array of documents. Stopping DocumentManager construction');
}
var documents = JSON.parse(this.dataInput.value);
this.constructedSuccessFully = true;
this.initialize(documents);
}
/**
* Initializes the setup of the document uploader.
* @param documents string Example structure:
* '[{
* "id": 3,
* "path": "uploads/products/Before 2018-01-25 at 14,48,23_1522928384.png",
* "documentable_id": 1,
* "documentable_type": "App\\KommaApp\\Shop\\Products\\Product\\Product",
* "created_at": "2018-04-05 11:39:44",
* "updated_at": "2018-04-05 11:39:44"
* }]'
*
*/
_createClass(DocumentManager, [{
key: "initialize",
value: function initialize(documents) {
if (!this.constructedSuccessFully) return;
if (documents) {
var length = documents.length;
for (var index = 0; index < length; index++) {
var initDocument = documents[index];
var documentModel = DocumentModel.fromJson(initDocument);
if (documentModel) {
this.addDocumentElement(documentModel);
} else {
console.error("DocumentManager stumbled upon a document that is not valid upon initializing: ");
console.error(initDocument);
}
}
this.sortDocuments();
}
this.updateDataInput();
this.setupHtml5Uploader();
}
/**
* Set up the html 5 uploader. Hook to its events
*/
}, {
key: "setupHtml5Uploader",
value: function setupHtml5Uploader() {
var self = this;
this.HTML5Uploader.on('uploadStart', this.HTML5UploadStarted.bind(this));
this.HTML5Uploader.on('updateProgress', this.HTML5UploadProgress.bind(this));
this.HTML5Uploader.on('uploadComplete', this.HTML5UploadedFile.bind(this));
this.HTML5Uploader.on('uploadFailed', this.HTML5UploadFailedOrCanceled.bind(this));
this.HTML5Uploader.on('uploadCanceled', this.HTML5UploadFailedOrCanceled.bind(this));
}
/**
* Triggered when a HTML file upload failed to upload or was canceled.
*
* @constructor
*/
}, {
key: "HTML5UploadFailedOrCanceled",
value: function HTML5UploadFailedOrCanceled(file) {
var documentElement = file.documentElement;
if (!documentElement) return;
this.documentList.removeChild(documentElement);
this.updateDataInput();
}
/**
* Triggered when a file was uploaded successfully
*
* @param file
* @param responseText
* @constructor
*/
}, {
key: "HTML5UploadedFile",
value: function HTML5UploadedFile(file, responseText) {
var documentElement = file.documentElement;
if (!documentElement) return;
var trackerModel = JSON.parse(responseText);
var documentModel = DocumentModel.fromJson(JSON.parse(documentElement.dataset.json));
documentModel.upload_tracker_id = trackerModel.id; //TrackerModel as array.
this.attachDocumentModelToDocumentElement(documentElement, documentModel);
documentElement.querySelector('.drag-icon').classList.remove('is-hidden');
documentElement.querySelector('.thumb').classList.remove('is-uploading');
documentElement.querySelector('.percentage').remove();
this.updateDataInput();
}
/**
* Triggered when HTML5 Uploader made progress in uploading a file
*
* @param file
* @param percentCompleteOrNull
* @constructor
*/
}, {
key: "HTML5UploadProgress",
value: function HTML5UploadProgress(file, percentCompleteOrNull) {
var documentElement = file.documentElement;
if (!documentElement) return;
var progress = documentElement.querySelector('.percentage'); //There is still some backend processing time needed. So we don't show 100%. Only when the backend responds with a complete
if (percentCompleteOrNull && percentCompleteOrNull === 100) percentCompleteOrNull = 99;else if (!percentCompleteOrNull) percentCompleteOrNull = 1; // Update the progress value
progress.setAttribute("aria-valuenow", percentCompleteOrNull);
}
/**
* Triggered when a HTML 5 upload was started.
*
* @param file
* @constructor
*/
}, {
key: "HTML5UploadStarted",
value: function HTML5UploadStarted(file) {
var documentElement = this.createDocumentElement();
this.attachDocumentModelToDocumentElement(documentElement);
var documentModel = DocumentModel.fromJson(JSON.parse(documentElement.dataset.json));
documentModel.state = DOCUMENT_STATE_NEW;
documentModel.name = file.name;
documentModel.path = file.name;
documentElement = this.updateDocumentElementWithDocumentData(documentElement, documentModel);
this.attachDocumentModelToDocumentElement(documentElement, documentModel); // Add the progress element to the thumb
var progressPercentageString = '<span class="percentage" role="progressbar" aria-valuemin="0" aria-valuemax="100"></span>'; // let progressPercentage = document.createElement('span');
// progressPercentage.setAttribute('class', 'percentage');
// progressPercentage.setAttribute("role", "progressbar");
// progressPercentage.setAttribute("aria-valuemin", 0);
// progressPercentage.setAttribute("aria-valuemax", 100);
documentElement.querySelector('.thumb').insertAdjacentHTML('afterbegin', progressPercentageString);
this.documentList.appendChild(documentElement);
documentElement.querySelector('.drag-icon').classList.add('is-hidden');
documentElement.querySelector('.thumb').classList.add('is-uploading'); // documentElement.querySelector('.thumb').classList.add('has-image');
file.documentElement = documentElement;
}
/**
* Occurs when the user clicked the delete document button
*
* @param mouseEvent A javascript mouse event
*/
}, {
key: "deleteDocumentButtonClicked",
value: function deleteDocumentButtonClicked(mouseEvent) {
var documentElement = mouseEvent.target.parentElement;
var document = JSON.parse(documentElement.dataset.json);
if (document.state === DOCUMENT_STATE_DELETED) return;
if (document.state !== DOCUMENT_STATE_NEW) {
document.state = DOCUMENT_STATE_DELETED;
documentElement.classList.add(DOCUMENT_STATE_DELETED);
documentElement.dataset.json = JSON.stringify(document);
} else {
this.documentList.removeChild(documentElement);
}
this.updateDataInput();
this.updateSortOrder();
}
/**
* Occurs when the user modified the document
*
* @param event A javascript event
*/
}, {
key: "modifiedDocument",
value: function modifiedDocument(event) {
var wrapper = event.target.parentElement.parentElement; //Document exists. Updates its json state and hide it.
var document = JSON.parse(wrapper.dataset.json);
if (document.state === DOCUMENT_STATE_DELETED) return;
if (document.state !== DOCUMENT_STATE_NEW) document.state = DOCUMENT_STATE_MODIFIED; //Check what is modified and update the document accordingly
var nameInput = wrapper.getElementsByClassName('name')[0];
document.name = nameInput.value;
wrapper.dataset.json = JSON.stringify(document);
wrapper.classList.add(DOCUMENT_STATE_MODIFIED);
this.updateDataInput();
}
/**
* Adds a new document element. When documentModel isn't specified, the document element wil give the user the
* ability to upload a new document by transforming that document element to a document uploader (fancy fileinput)
*
* @param documentModel DocumentModel. You only need to specify it when it is an existing document.
*/
}, {
key: "addDocumentElement",
value: function addDocumentElement() {
var documentModel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
//Create an fileInput wrapper in which we put the fileInput and delete / remove button
var documentElement = this.createDocumentElement();
if (documentModel !== undefined) this.updateDocumentElementWithDocumentData(documentElement, documentModel);
this.attachDocumentModelToDocumentElement(documentElement, documentModel); // if(documentModel === undefined) this.transformDocumentElementIntoADocumentUpload(documentElement);
//Make it dragable if needed. With this it can be sorted
if (documentModel) {
this.makeElementRespondToDragging(documentElement, this.isSortable);
this.makeElementRespondToDragOverAndLeave(documentElement, this.isSortable);
this.makeElementRespondToDrop(documentElement, this.isSortable);
} //Add the newly created HTMLElement to the document list
this.documentList.appendChild(documentElement);
}
/**
* @param documentElement {HTMLElement}
* @param documentModel {DocumentModel|undefined}
* @returns {HTMLElement} The document element
*/
}, {
key: "attachDocumentModelToDocumentElement",
value: function attachDocumentModelToDocumentElement(documentElement) {
var documentModel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
if (documentModel !== undefined) {
documentElement.dataset.json = JSON.stringify(documentModel);
} else {
documentModel = new DocumentModel();
documentModel.sort_order = this.getCurrentDocumentsCount() + 1;
documentElement.dataset.json = JSON.stringify(documentModel);
}
return documentElement;
}
/**
*
* @param documentElement {HTMLElement}
* @param documentModel {DocumentModel}
* @return {HTMLElement}
*/
}, {
key: "updateDocumentElementWithDocumentData",
value: function updateDocumentElementWithDocumentData(documentElement, documentModel) {
var nameInput = documentElement.querySelector('.name');
var pathParagraph = documentElement.querySelector('.path');
var thumbImageElement = documentElement.querySelector('.thumb'); //Set the path of the document
if (pathParagraph) {
pathParagraph.innerText = documentModel.path;
} //Set the name of the document
if (nameInput) {
nameInput.setAttribute('value', documentModel.name);
} //Set the thumb image
if (thumbImageElement && documentModel.path) {
var thumbUrl = this.getThumbUrlUsingDocumentModel(documentModel);
var documentExtension = this.getExtensionFromFileName(documentModel.path);
thumbImageElement.setAttribute('data-filetype', documentExtension);
var thumbImage = thumbImageElement.querySelector('.thumb__image');
if (thumbUrl && thumbImage && documentModel.state !== 'new') {
thumbImage.style.backgroundImage = "url('" + thumbUrl + "')";
thumbImageElement.classList.add('has-image');
} else if (thumbImage && this.availableExtensionThumbs.indexOf(documentExtension) !== -1) {
thumbImage.style.backgroundImage = "url('" + this.extensionThumbsFolder + documentExtension + ".svg')";
thumbImageElement.classList.add('has-icon');
}
}
return documentElement;
}
/**
* Creates a li item with a name input, path text paragraph, delete button and a thumb image.
*
* @returns {HTMLElement}
*/
}, {
key: "createDocumentElement",
value: function createDocumentElement() {
var documentElement = document.createElement('li');
documentElement.className = 'document';
var nameInput = document.createElement('input');
nameInput.setAttribute('class', 'name');
nameInput.setAttribute('type', 'text');
nameInput.addEventListener('change', this.modifiedDocument.bind(this));
var pathText = document.createElement('p');
pathText.setAttribute('class', 'path');
var contentWrapper = document.createElement('div');
contentWrapper.setAttribute('class', 'content-wrapper');
contentWrapper.appendChild(nameInput);
contentWrapper.appendChild(pathText);
var deleteButton = document.createElement('span');
deleteButton.className = 'delete'; // deleteButton.innerText = 'x';
deleteButton.addEventListener('click', this.deleteDocumentButtonClicked.bind(this));
var dragIcon = document.createElement('span');
dragIcon.className = 'drag-icon';
var thumbContainer = document.createElement('div');
thumbContainer.className = 'thumb';
thumbContainer.setAttribute('draggable', 'false'); //Prevent image from being dragged and interfering with what the makeElementDraggableIfNeeded method does
var thumbImage = document.createElement('div');
thumbImage.className = 'thumb__image';
thumbContainer.appendChild(thumbImage);
var fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
fileInput.setAttribute('name', this.key + '-' + (this.getCurrentDocumentsCount() + 1));
if (this.accept) fileInput.setAttribute('accept', this.accept);
documentElement.appendChild(fileInput);
fileInput.style.display = "none";
documentElement.appendChild(dragIcon);
documentElement.appendChild(thumbContainer);
documentElement.appendChild(contentWrapper);
documentElement.appendChild(deleteButton);
return documentElement;
}
/**
* Retrieves a javascript file instance and creates a documentElement for it.
* Usually used by outside classes to inject a document from a file to upload.
*
* @param fileInstance {File}
*/
}, {
key: "receiveFile",
value: function receiveFile(fileInstance) {
if (!fileInstance) {
console.warn('DocumentManager:receiveFile: Expected to get a file but did not get one');
return;
}
console.log('this.getCurrentDocumentsCount() < this.maxDocuments: ', this.getCurrentDocumentsCount(), this.maxDocuments, 'File', fileInstance);
if (this.getCurrentDocumentsCount() < this.maxDocuments) {
var documentElement = this.createDocumentElement();
this.attachDocumentModelToDocumentElement(documentElement);
if (this.HTML5Uploader.isSupported() === false) {
documentElement = this.giveDocumentElementAFile(documentElement, fileInstance); //Add the newly created HTMLElement to the document list
this.documentList.appendChild(documentElement);
if (this.formSizeExceeded()) {
documentElement.parentElement.removeChild(documentElement); //Remove the documentElement
}
this.updateSortOrder();
} else {
console.log('Uploading via HTML5');
this.HTML5Uploader.upload(fileInstance);
}
}
}
/**
* Returns the amount of documents
*/
}, {
key: "getCurrentDocumentsCount",
value: function getCurrentDocumentsCount() {
return this.documentList.getElementsByClassName('document').length;
}
/**
* Sets the file of an document element to the given one.
* Makes the drag icon invisible since it was not uploaded yet
* and cannot be positioned. Sets the file input to the files name and
* loads the thumb with the appropiate extension
*
* @param {HTMLElement} documentElement
* @param {File} file
* @return {HTMLElement} the documentElement
*/
}, {
key: "giveDocumentElementAFile",
value: function giveDocumentElementAFile(documentElement, file) {
var filename = file.name;
var extension = this.getExtensionFromFileName(filename);
var thumbUrl = this.previewThumbUrlIsImage(filename); //Get the document element and some parts in it
var nameInputElement = documentElement.querySelector('.name');
var thumbImageElement = documentElement.querySelector('.thumb');
var contentWrapper = documentElement.querySelector('.content-wrapper');
var deleteButton = documentElement.querySelector('.delete');
var dragIcon = documentElement.querySelector('.drag-icon');
var fileInputElement = documentElement.querySelector('input[type="file"]'); //Hide the drag icon. Dragging is only supported after file upload
dragIcon.style.display = 'none'; //Update file input with a file if the input does not have a file.
if (fileInputElement && !fileInputElement.files[0]) {
fileInputElement.files = new FileList(file);
} //Make thumb visible and load extension image
thumbImageElement.setAttribute('data-filetype', extension);
if (this.availableExtensionThumbs.indexOf(extension) !== -1) {
var thumbImage = thumbImageElement.querySelector('thumb__image');
thumbImage.style.backgroundImage = "url('" + this.extensionThumbsFolder + extension + ".svg')";
thumbImage.classList.add('has-icon');
}
nameInputElement.value = filename;
return documentElement;
}
/**
* Returns the thumbnail for the document or false if it isn't available
*/
}, {
key: "getThumbUrlUsingDocumentModel",
value: function getThumbUrlUsingDocumentModel(documentModel) {
if (documentModel) {
var filename = documentModel.path;
if (documentModel.thumb_image_url !== '') filename = documentModel.thumb_image_url;
if (this.previewThumbUrlIsImage(filename)) return filename;
}
return false;
}
/**
* Returns the given preview thumb url for an extension if that extension is an image or false if it is not an image
*/
}, {
key: "previewThumbUrlIsImage",
value: function previewThumbUrlIsImage(url) {
if (!this.enablePreviewsIfPossible) return false;
var extension = this.getExtensionFromFileName(url);
switch (extension) {
case 'png':
case 'jpg':
case 'jpeg':
case 'gif':
return url;
case 'pdf':
default:
return false;
}
}
/**
* Returns the extension without leading dot from a file name or '' when it did not have an extension.
*/
}, {
key: "getExtensionFromFileName",
value: function getExtensionFromFileName(filename) {
var extension = filename.split(/[.]+/).pop();
if (extension === filename) return '';
return extension.toLowerCase();
}
/**
* Check if the total form size isn't bigger then the maximum allowed upload size.
* Warning: when maxUploadSizeInBytes isn't set this function wil always return false.
*/
}, {
key: "formSizeExceeded",
value: function formSizeExceeded() {
if (this.maxUploadSizeInBytes) {
var exceeded = false;
var currentTotalInBytes = 0; //validate total
this.documentList.querySelectorAll('input[type="file"]').forEach(function (fileInput) {
if (fileInput.files.length !== 1) return;
var document = fileInput.files[0];
currentTotalInBytes += document.size;
});
console.log('max upload size in bytes: ' + this.maxUploadSizeInBytes + ' current upload size in bytes: ' + currentTotalInBytes);
if (currentTotalInBytes > this.maxUploadSizeInBytes) {
var maxUploadSizeInMegaBytes = this.maxUploadSizeInBytes / 1048576;
exceeded = true;
alert(this.uploadSizeExceededMessage + ' ' + maxUploadSizeInMegaBytes + ' MegaBytes');
}
return exceeded;
} else {
return false;
}
}
/**
* Update the data input with an array of json objects that are the data-json attribues of each "document" li.
* This is used for the backend to determine what has changed and what did not.
*/
}, {
key: "updateDataInput",
value: function updateDataInput() {
var documentsDataArray = []; //Please notice that the first document isnt a document but is the document add button. That's why we check for the json dataset
var documents = this.documentList.children;
var nDocuments = documents.length;
for (var documentsIndex = 0; documentsIndex < nDocuments; documentsIndex++) {
var documentElement = documents[documentsIndex];
if ("json" in documentElement.dataset) {
documentsDataArray.push(JSON.parse(documentElement.dataset.json));
}
}
if (nDocuments >= this.maxDocuments) {
this.wrapper.querySelector('.drag-and-drop-area').classList.add('is-hidden');
} else {
this.wrapper.querySelector('.drag-and-drop-area').classList.remove('is-hidden');
}
this.dataInput.value = JSON.stringify(documentsDataArray);
}
/**
* Updates the sort order of each document when needed and then updates the data input field
*/
}, {
key: "updateSortOrder",
value: function updateSortOrder() {
//Please notice that the first document isnt a document but is the document add button. That's why we check for the json dataset
var documents = this.documentList.children;
var nDocuments = documents.length;
var currentSortNumber = 1;
for (var documentsIndex = 0; documentsIndex < nDocuments; documentsIndex++) {
var documentElement = documents[documentsIndex];
if ("json" in documentElement.dataset === false) continue; //used to skip the add new document button
var _document = JSON.parse(documentElement.dataset.json);
if (_document.state === DOCUMENT_STATE_DELETED) continue;
_document.sort_order = currentSortNumber;
if (_document.state !== DOCUMENT_STATE_NEW) _document.state = DOCUMENT_STATE_MODIFIED;
documentElement.dataset.json = JSON.stringify(_document);
documentElement.classList.add(DOCUMENT_STATE_MODIFIED);
currentSortNumber++;
}
this.updateDataInput();
}
/**
* Does have a look at the documentElements and sorts them by using their sort order values
*/
}, {
key: "sortDocuments",
value: function sortDocuments() {
var documentElements = this.documentList.children;
documentElements = Array.prototype.slice.call(documentElements); //Converts the htmlCollection of HTMLElement documentElements to an Array of documentElements
documentElements.sort(function (itemA, itemB) {
var itemADocument = JSON.parse(itemA.dataset.json);
var itemBDocument = JSON.parse(itemB.dataset.json); // console.log(itemADocument.sort_order, itemBDocument.sort_order);
if (itemADocument.sort_order < itemBDocument.sort_order) return -1;
return 1;
});
var sortedDocumentsLength = documentElements.length;
for (var index = 1; index < sortedDocumentsLength; index++) {
this.documentList.removeChild(documentElements[index]);
if (this.documentList.length > 1) this.documentList.insertBefore(documentElements[index], this.documentList.firstChild);else this.documentList.appendChild(documentElements[index]);
}
}
/**
* @param element HTMLElement that needs to be draggable or not
* @param respondOrNotBoolean
* @return {DocumentManager}
*/
}, {
key: "makeElementRespondToDragging",
value: function makeElementRespondToDragging(element) {
var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
element.setAttribute('draggable', respondOrNotBoolean ? 'true' : 'false');
element.id = this.key + '_' + this.getCurrentDocumentsCount();
if (respondOrNotBoolean) {
element.removeEventListener('dragstart', this.drag.bind(this));
element.addEventListener('dragstart', this.drag.bind(this));
} else {
element.removeEventListener('dragstart', this.drag.bind(this));
}
return this;
}
/**
* @param element HTMLElement that needs to be draggable or not
* @param respondOrNotBoolean
* @return {DocumentManager}
*/
}, {
key: "makeElementRespondToDrop",
value: function makeElementRespondToDrop(element) {
var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (respondOrNotBoolean) {
element.removeEventListener('drop', this.drop.bind(this));
element.addEventListener('drop', this.drop.bind(this));
} else {
element.removeEventListener('drop', this.drop.bind(this));
}
return this;
}
/**
* Prepares the element so that it can receive items that are dropped onto it
*
* @param element HTMLElement that needs can be a drop target or not
* @param respondOrNotBoolean wheter or not it should be a drop target
*/
}, {
key: "makeElementRespondToDragOverAndLeave",
value: function makeElementRespondToDragOverAndLeave(element) {
var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (respondOrNotBoolean) {
element.removeEventListener('dragover', this.dragOver.bind(this));
element.removeEventListener('dragleave', this.dragLeave.bind(this));
element.addEventListener('dragover', this.dragOver.bind(this));
element.addEventListener('dragleave', this.dragLeave.bind(this));
} else {
element.removeEventListener('dragover', this.dragOver.bind(this));
element.removeEventListener('dragleave', this.dragLeave.bind(this));
}
}
/**
* Occurs when a document (li) HTMLElement is being dragged
*
* @param dragEvent
*/
}, {
key: "drag",
value: function drag(dragEvent) {
if (!dragEvent.target.id) return;
dragEvent.stopPropagation();
dragEvent.dataTransfer.setData("text", dragEvent.target.id); //Set the id of the thing that is being dragged in the event.
var draggedElement = document.getElementById(dragEvent.target.id);
this.triggerEvent('drag', draggedElement);
}
/**
* Occurs when a document (li) HTMLElement is being dragged over the target element.
* So the dragEvent target is not the element that you drag, but the place / HTMLElement where it may be dropped.
*
* @param dragEvent
*/
}, {
key: "dragOver",
value: function dragOver(dragEvent) {
dragEvent.preventDefault(); //Sets target HTMLElement to allow a drop
dragEvent.stopPropagation();
if (!dragEvent.target.id) return;
var draggedElementId = dragEvent.dataTransfer.getData("text");
var draggedElement = document.getElementById(draggedElementId);
this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, false);
dragEvent.target.classList.add('isDropTarget');
this.triggerEvent('dragLeave', [draggedElement, dragEvent.target]);
}
/**
* Occurs when a document (li) HTMLElement is NOT being dragged anymore over the target element.
*
* @param dragEvent
*/
}, {
key: "dragLeave",
value: function dragLeave(dragEvent) {
if (!dragEvent.target.id) return;
dragEvent.stopPropagation();
var draggedElementId = dragEvent.dataTransfer.getData("text");
var draggedElement = document.getElementById(draggedElementId);
this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, true);
dragEvent.target.classList.remove('isDropTarget');
this.triggerEvent('dragLeave', [draggedElement, dragEvent.target]);
}
/**
* Occurs when a document is being dropped
*
* @param dragEvent
*/
}, {
key: "drop",
value: function drop(dragEvent) {
dragEvent.preventDefault(); //Prevent browser from activating links and buttons
if (!dragEvent.target.id) return;
var draggedElementId = dragEvent.dataTransfer.getData("text");
var draggedElement = document.getElementById(draggedElementId);
var targetElement = dragEvent.target;
targetElement.classList.remove('isDropTarget'); //Create a shim element that keeps track of where the dragged element was and where the target element must be inserted
var shimElement = document.createElement('div');
draggedElement.parentElement.insertBefore(shimElement, draggedElement); //Move the dragged element in just before the target element
draggedElement.parentElement.insertBefore(draggedElement, targetElement); //Move the target element before the shim and then remove the shim since we only needed that to mark the dragged elements original position
draggedElement.parentElement.insertBefore(targetElement, shimElement);
shimElement.parentElement.removeChild(shimElement);
this.triggerEvent('drop', [draggedElement, targetElement]);
this.enableOrDisablePointerEventsOnChildrenOfElement(targetElement, true);
this.updateSortOrder();
}
/**
* Enables / disables the listening to pointer (example: mouse) events on an element
* and all of it's children. This prevents for example the dragover event from beeing canceled
* when dragging over an input that resides in an element which listens to the dragover event
* because the input captures the mouse.
*/
}, {
key: "enableOrDisablePointerEventsOnChildrenOfElement",
value: function enableOrDisablePointerEventsOnChildrenOfElement(element, enable) {
var length = element.children.length;
for (var index = 1; index < length; index++) {
if (enable === false) {
element.children[index].style.pointerEvents = 'none';
} else {
element.children[index].style.pointerEvents = null;
}
var childrenLength = element.children.children;
for (var childrenIndex = 1; childrenIndex < childrenLength; childrenIndex++) {
this.enableOrDisablePointerEventsOnChildrenOfElement(element.children.children[index], enable);
}
}
}
/**
* Registers a event to a callback and returns the a reference to the event handler for that specific event
*
* @param event (string)
* @param callback (callable)
*/
}, {
key: "on",
value: function on(event, callback) {
if (!this.eventMap.hasOwnProperty(event)) this.eventMap[event] = [];
return this.eventMap[event].push(callback);
}
/**
* Call event callbacks
*
* @param event (string)
* @param eventArgs (array) an array of arguments to pass to the callback
*/
}, {
key: "triggerEvent",
value: function triggerEvent(event, eventArgs) {
if (!this.eventMap.hasOwnProperty(event)) return;
var nEvents = this.eventMap[event].length;
for (var index = 0; index < nEvents; index++) {
var callback = this.eventMap[event][index];
if (eventArgs && eventArgs.length > 0) {
callback.apply(this, eventArgs);
} else {
callback.call(this);
}
}
}
}]);
return DocumentManager;
}();
/**
* Represents a Document. It the equivalent of the laravel php version
*/
var DocumentModel = /*#__PURE__*/function () {
function DocumentModel() {
_classCallCheck(this, DocumentModel);
this.id = -1;
this.path = '';
this.state = DOCUMENT_STATE_NEW;
this.name = '';
this.sort_order = 1;
this.thumb_image_url = '';
this.small_image_url = '';
this.medium_image_url = '';
this.large_image_url = '';
this.documentable_id = -1;
this.documentable_type = '';
this.upload_tracker_id = -1;
this.created_at = '';
this.updated_at = '';
}
_createClass(DocumentModel, null, [{
key: "isValidDocumentJson",
value: function isValidDocumentJson(jsonData) {
return jsonData.hasOwnProperty('id') && jsonData.hasOwnProperty('path') && jsonData.hasOwnProperty('state') && jsonData.hasOwnProperty('name') && jsonData.hasOwnProperty('sort_order') && jsonData.hasOwnProperty('thumb_image_url') && jsonData.hasOwnProperty('small_image_url') && jsonData.hasOwnProperty('medium_image_url') && jsonData.hasOwnProperty('large_image_url') && jsonData.hasOwnProperty('documentable_id') && jsonData.hasOwnProperty('documentable_type') && jsonData.hasOwnProperty('upload_tracker_id') && jsonData.hasOwnProperty('created_at') && jsonData.hasOwnProperty('updated_at');
}
}, {
key: "fromJson",
value: function fromJson(jsonData) {
if (!DocumentModel.isValidDocumentJson(jsonData)) return false;
var documentModel = new DocumentModel();
documentModel.id = jsonData.id;
documentModel.path = jsonData.path;
documentModel.state = jsonData.state;
documentModel.name = jsonData.name;
documentModel.sort_order = jsonData.sort_order;
documentModel.thumb_image_url = jsonData.thumb_image_url;
documentModel.small_image_url = jsonData.small_image_url;
documentModel.medium_image_url = jsonData.medium_image_url;
documentModel.large_image_url = jsonData.large_image_url;
documentModel.documentable_id = jsonData.id;
documentModel.documentable_type = jsonData.documentable_type;
documentModel.upload_tracker_id = jsonData.upload_tracker_id;
documentModel.created_at = jsonData.created_at;
documentModel.updated_at = jsonData.updated_at;
return documentModel;
}
}]);
return DocumentModel;
}();
var DOCUMENT_STATE_NEW = 'new';
var DOCUMENT_STATE_PRISTINE = 'pristine';
var DOCUMENT_STATE_MODIFIED = 'modified';
var DOCUMENT_STATE_DELETED = 'deleted';
/**
* Used for setting files
*/
var FileList = function FileList() {
var _ref;
for (var _len = arguments.length, items = new Array(_len), _key = 0; _key < _len; _key++) {
items[_key] = arguments[_key];
}
_classCallCheck(this, FileList);
// flatten rest parameter
items = (_ref = []).concat.apply(_ref, _toConsumableArray(items)); // check if every element of array is an instance of `File`
if (items.length && !items.every(function (file) {
return file instanceof File;
})) {
throw new TypeError("expected argument to FileList is File or array of File objects");
} // use `ClipboardEvent("").clipboardData` for Firefox, which returns `null` at Chromium
// we just need the `DataTransfer` instance referenced by `.clipboardData`
var dt = new ClipboardEvent("").clipboardData || new DataTransfer(); // add `File` objects to `DataTransfer` `.items`
var _iterator = _createForOfIteratorHelper(items),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var file = _step.value;
dt.items.add(file);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return dt.files;
};
var FileDragAndDropHandler = /*#__PURE__*/function () {
/**
*
*
* @param areaElement {HTMLElement}
*/
function FileDragAndDropHandler(areaElement) {
_classCallCheck(this, FileDragAndDropHandler);
this.hooks = [];
this.selectButton = areaElement.querySelector('button.select');
if (!this.selectButton) {
console.log('FileDragAndDropHandler:constructor The document area must have a button in it with class select. But did not have one. Not responding to drag and drop');
return;
}
this.fileCatcherInput = areaElement.querySelector('input[type="file"]');
if (!this.fileCatcherInput) {
console.log('FileDragAndDropHandler:constructor The document area must have file input. But did not have one. Not responding to drag and drop');
return;
}
this.makeElementRespondToDragOverAndLeave(areaElement);
this.makeElementRespondToDrop(areaElement);
this.makeElementRespondToClick(areaElement);
this.makeFileInputPassFilesToHooks();
}
/**
* Adds an event listener to the file input and makes it pass its files to the document manager
*/
_createClass(FileDragAndDropHandler, [{
key: "makeFileInputPassFilesToHooks",
value: function makeFileInputPassFilesToHooks() {
var self = this;
this.fileCatcherInput.addEventListener('change', function (event) {
var nFiles = event.target.files.length;
for (var index = 0; index < nFiles; index++) {
var file = event.target.files[index]; // console.log(file);
self.createFileListForFileAndPassToHooks(file);
}
event.target.value = '';
});
}
/**
* Catches click on the element and passes them trough to the file input
*/
}, {
key: "makeElementRespondToClick",
value: function makeElementRespondToClick(element) {
var self = this;
element.addEventListener('click', function (event) {
self.fileCatcherInput.click();
});
}
/**
* Hooks a hookable (an object that has a addFile method / function) to the drag and drop handler so that the drag and drop handler passes inputs to the
* hookable
* @param hookable {Class}
*/
}, {
key: "hookTo",
value: function hookTo(hookable) {
if (typeof hookable.receiveFile !== 'function') {
console.error('The given hookable does not have a required receiveFile method / function. Not hooking the given "hookable".');
return;
}
this.hooks.push(hookable);
}
/**
* @param element HTMLElement that needs to be draggable or not
* @param respondOrNotBoolean
* @return {FileDragAndDropHandler}
*/
}, {
key: "makeElementRespondToDrop",
value: function makeElementRespondToDrop(element) {
var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (respondOrNotBoolean) {
element.removeEventListener('drop', this.drop.bind(this));
element.addEventListener('drop', this.drop.bind(this));
} else {
element.removeEventListener('drop', this.drop.bind(this));
}
return this;
}
/**
* Prepares the element so that it can receive items that are dropped onto it
*
* @param element HTMLElement that needs can be a drop target or not
* @param respondOrNotBoolean wheter or not it should be a drop target
*/
}, {
key: "makeElementRespondToDragOverAndLeave",
value: function makeElementRespondToDragOverAndLeave(element) {
var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (respondOrNotBoolean) {
element.removeEventListener('dragover', this.dragOver.bind(this));
element.removeEventListener('dragleave', this.dragLeave.bind(this));
element.addEventListener('dragover', this.dragOver.bind(this));
element.addEventListener('dragleave', this.dragLeave.bind(this));
} else {
element.removeEventListener('dragover', this.dragOver.bind(this));
element.removeEventListener('dragleave', this.dragLeave.bind(this));
}
}
/**
* Occurs when a document (li) HTMLElement is being dragged over the target element.
* So the dragEvent target is not the element that you drag, but the place / HTMLElement where it may be dropped.
*
* @param dragEvent
*/
}, {
key: "dragOver",
value: function dragOver(dragEvent) {
dragEvent.preventDefault(); //Sets target HTMLElement to allow a drop
dragEvent.stopPropagation();
if (!dragEvent.target.id) return;
this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, false);
dragEvent.target.classList.add('isDropTarget');
}
/**
* Occurs when a document (li) HTMLElement is NOT being dragged anymore over the target element.
*
* @param dragEvent
*/
}, {
key: "dragLeave",
value: function dragLeave(dragEvent) {
if (!dragEvent.target.id) return;
dragEvent.stopPropagation();
this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, true);
dragEvent.target.classList.remove('isDropTarget');
}
/**
* Occurs when a document is being dropped
*
* @param dragEvent
*/
}, {
key: "drop",
value: function drop(dragEvent) {
dragEvent.preventDefault(); //Prevent browser from activating links and buttons
var targetElement = dragEvent.target;
targetElement.classList.remove('isDropTarget');
this.enableOrDisablePointerEventsOnChildrenOfElement(targetElement, true); // Prevent default behavior (Prevent file from being opened)
dragEvent.preventDefault();
if (dragEvent.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
for (var i = 0; i < dragEvent.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (dragEvent.dataTransfer.items[i].kind === 'file') {
var file = dragEvent.dataTransfer.items[i].getAsFile();
this.createFileListForFileAndPassToHooks(file);
}
}
} else {
// Use DataTransfer interface to access the file(s)
for (var _i = 0; _i < dragEvent.dataTransfer.files.length; _i++) {
var _file = dragEvent.dataTransfer.files[_i];
this.createFileListForFileAndPassToHooks(_file);
}
}
}
}, {
key: "createFileListForFileAndPassToHooks",
value: function createFileListForFileAndPassToHooks(file) {
var length = this.hooks.length;
for (var index = 0; index < length; index++) {
this.hooks[index].receiveFile(file);
}
}
/**
* Enables / disables the listening to pointer (example: mouse) events on an element
* and all of it's children. This prevents for example the dragover event from beeing canceled
* when dragging over an input that resides in an element which listens to the dragover event
* because the input captures the mouse.
*/
}, {
key: "enableOrDisablePointerEventsOnChildrenOfElement",
value: function enableOrDisablePointerEventsOnChildrenOfElement(element, enable) {
var length = element.children.length;
for (var index = 1; index < length; index++) {
if (enable === false) {
element.children[index].style.pointerEvents = 'none';
} else {
element.children[index].style.pointerEvents = null;
}
var childrenLength = element.children.children;
for (var childrenIndex = 1; childrenIndex < childrenLength; childrenIndex++) {
this.enableOrDisablePointerEventsOnChildrenOfElement(element.children.children[index], enable);
}
}
}
}]);
return FileDragAndDropHandler;
}();
/**
* HTML 5 file uploads that report progress while uploading
*/
var HTML5Uploader = /*#__PURE__*/function () {
function HTML5Uploader(uploadUrl, maxPostSize, maxUploadSize, translations) {
_classCallCheck(this, HTML5Uploader);
this.constructedSuccessfully = false;
if (!uploadUrl) {
console.error('Did not get a valid upload url. Not initializing Html5Uploader');
return;
}
this.uploadUrl = uploadUrl;
if (!maxPostSize) {
console.error('Did not get the maximum post size. Not initializing Html5Uploader');
return;
}
this.maxPostSize = maxPostSize;
if (!maxUploadSize) {
console.error('Did not get the maximum upload size. Not initializing Html5Uploader');
return;
}
this.maxUploadSize = maxUploadSize;
if (!translations) {
console.error('Did not get the translations. Not initializing Html5Uploader');
return;
}
this.translations = JSON.parse(translations);
this.eventMap = {};
if (!this.isSupported()) {
console.warn('HTML 5 file upload is not supported. Not initializing Html5Uploader');
return;
}
this.constructedSuccessfully = true;
}
/**
* Returns true if the browser supports HTML 5 uploading. false if not
* @return {boolean}
*/
_createClass(HTML5Uploader, [{
key: "isSupported",
value: function isSupported() {
return window.FormData !== undefined;
}
/**
* @param {File} file
*/
}, {
key: "receiveFile",
value: function receiveFile(file) {
if (!this.isSupported()) {
console.error('HTML 5 file upload is not supported. Not uploading file.');
return;
}
}
/**
* @param {File} file
*/
}, {
key: "upload",
value: function upload(file) {
if (!this.verifyFileSizeOrShowError(file)) return;
if (this.constructedSuccessfully === false) return;
var self = this;
var formData = new FormData();
formData.append(file.name, file);
var request = new XMLHttpRequest();
var uploadRequest = request.upload;
uploadRequest.addEventListener("progress", function (file) {
return function (event) {
self.updateProgress(file, event);
};
}(file));
request.addEventListener("loadstart", function (file) {
return function () {
self.uploadStart(file);
};
}(file));
request.addEventListener("error", function (file) {
return function () {
self.uploadFailed(file);
};
}(file));
request.addEventListener("abort", function (file) {
return function () {
self.uploadCanceled(file);
};
}(file));
request.onreadystatechange = function (file) {
return function () {
if (request.readyState === 4 && request.status === 200) {
self.uploadComplete(file, request.responseText);
}
};
}(file);
request.open('POST', this.uploadUrl);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
var csfrTokenContainer = document.querySelector('meta[name="csrf-token"]');
if (!csfrTokenContainer) {
console.error('Not uploading file since not csrf-token could be found in a meta tag with name "csrf-token". Please add it');
return;
}
request.setRequestHeader('X-CSRF-TOKEN', csfrTokenContainer.getAttribute('content'));
request.send(formData);
}
/**
* Returns true if the file size is lower then the maximum allowed server upload size.
* Or shows an alert and returns false if it is bigger then the allowed server upload size.
*
* @param {File} file
* @return {boolean}
*/
}, {
key: "verifyFileSizeOrShowError",
value: function verifyFileSizeOrShowError(file) {
if (file.size > this.maxPostSize || file.size > this.maxUploadSize) {
//Calculate file size and max file size to megabytes
var fileSizeInMegaBytes = file.size / (1024 * 1024);
var maxSizeInMegaBytes = (this.maxUploadSize > this.maxPostSize ? this.maxPostSize : this.maxUploadSize) / (1024 * 1024); //Round this sizes to 2 decimals
fileSizeInMegaBytes = Math.round(fileSizeInMegaBytes * 100) / 100;
maxSizeInMegaBytes = Math.round(maxSizeInMegaBytes * 100) / 100; //Gather translation texts
var introText = this.translations.file_to_big;
var maxFileSizeUploadTranslation = this.translations.max_file_size_upload;
var fileSizeUploadTranslation = this.translations.file_size_upload; //Assemble alert message
var alertText = introText + '\n\n' + maxFileSizeUploadTranslation + maxSizeInMegaBytes + ' MB\n' + fileSizeUploadTranslation + fileSizeInMegaBytes + ' MB\n'; //Show alert message and return false
alert(alertText);
return false;
} //File size is fine. Return true
return true;
}
}, {
key: "updateProgress",
value: function updateProgress(file, event) {
if (event.lengthComputable) {
var percentComplete = Math.ceil(event.loaded / event.total * 100);
this.triggerEvent('updateProgress', [file, percentComplete]);
} else {
// Unable to compute progress information since the total size is unknown
this.triggerEvent('updateProgress', [file, null]);
}
}
}, {
key: "uploadStart",
value: function uploadStart(file) {
this.triggerEvent('uploadStart', [file]);
}
}, {
key: "uploadComplete",
value: function uploadComplete(file, responseText) {
this.triggerEvent('uploadComplete', [file, responseText]);
}
}, {
key: "uploadFailed",
value: function uploadFailed(file) {
this.triggerEvent('uploadFailed', [file]);
}
}, {
key: "uploadCanceled",
value: function uploadCanceled(file) {
this.triggerEvent('uploadCanceled', [file]);
}
/**
* Registers a event to a callback and returns the a reference to the event handler for that specific event
*
* @param event (string)
* @param callback (callable)
*/
}, {
key: "on",
value: function on(event, callback) {
if (this.constructedSuccessfully === false) return;
if (!this.eventMap.hasOwnProperty(event)) this.eventMap[event] = [];
return this.eventMap[event].push(callback);
}
/**
* Call event callbacks
*
* @param event (string)
* @param eventArgs (array) an array of arguments to pass to the callback
*/
}, {
key: "triggerEvent",
value: function triggerEvent(event, eventArgs) {
if (!this.eventMap.hasOwnProperty(event)) return;
var nEvents = this.eventMap[event].length;
for (var index = 0; index < nEvents; index++) {
var callback = this.eventMap[event][index];
if (eventArgs && eventArgs.length > 0) {
callback.apply(this, eventArgs);
} else {
callback.call(this);
}
}
}
}]);
return HTML5Uploader;
}();
var ImageController = /*#__PURE__*/function () {
function ImageController(key, images, maxImages) {
_classCallCheck(this, ImageController);
//console.log('Image controller got images: ');
//console.log(images);
//console.log('ImageController: key: '+key);
//console.log('ImageController: maxImages: '+maxImages);
//
this.key = key;
this.currentImageListId = "#image-list-" + key;
this.fileCounter = 0;
this.maxImages = maxImages;
this.images = images; //
this.initialize();
this.checkNewButtonState();
}
_createClass(ImageController, [{
key: "initialize",
value: function initialize() {
var self = this; // Click on an existing image to remove it
$(self.currentImageListId + ' .image-thumb-li').click(function () {
$(this).remove();
self.removeFromImages($('img', this).attr('data-image-id'));
}); // When a file is selected for uploading
$(document).on('click', self.currentImageListId + ' .new-image input', function (e) {
//console.log(self.countActiveImages());
if (self.maxImages != '' && self.countActiveImages() >= self.maxImages) {
e.preventDefault();
return;
}
});
$(document).on('change', self.currentImageListId + ' .new-image input', function () {
//console.log("images.blade.php: Change event triggered");
if (self.maxImages != '' && self.countActiveImages() >= self.maxImages) return; //console.log('Checking old input element: #'+self.key+'-'+self.fileCounter);
var $oldInput = $('#' + self.key + '-' + self.fileCounter); //console.log("old input: ");
//console.log($oldInput);
//console.log("current image list element: "+self.currentImageListId + ' .uploads :');
//console.log($(self.currentImageListId + ' .uploads'));
$(self.currentImageListId + ' .uploads').append($oldInput);
self.images.push({
id: null,
name: $oldInput.attr('id'),
"delete": false
});
self.updateImages();
$oldInput.unbind('change'); //console.log("unbinded change event from the old input element");
var files = $oldInput.prop('files'); //console.log("files from property from the old input: ");
//console.log(files);
// Removing multiple files doesn't work yet, so it is disabled
for (var i = 0; i < files.length; i++) {
self.insertImage(files[i], self.fileCounter, i);
}
self.fileCounter++;
$(self.currentImageListId + ' .new-image').append('<input type="file" id="' + self.key + '-' + self.fileCounter + '" name="' + self.key + '-' + self.fileCounter + '" accept="image/*" />');
});
this.checkNewButtonState();
}
}, {
key: "insertImage",
value: function insertImage(file, fileCounter, imageCounter) {
var self = this; //console.log('insertImage');
var reader = new FileReader();
reader.onload = function (e) {
var dataURL = e.target.result;
$(self.currentImageListId + ' .thumbs').append('' + '<li id="image-thumb-' + this.key + '-' + fileCounter + '-' + imageCounter + '">' + '<img src="' + dataURL + '" />' + '<div class="deleteImage">тип</div>' + '</li>');
var thumb = $('#image-thumb-' + self.key + '-' + fileCounter + '-' + imageCounter); // Remove image for uploading when clicked
thumb.click(function () {
self.removeFromImages('' + self.key + '-' + fileCounter);
thumb.remove();
var element = $('#' + self.key + '-' + fileCounter);
element.val('');
element.remove();
});
};
this.checkNewButtonState();
reader.readAsDataURL(file);
}
}, {
key: "checkNewButtonState",
value: function checkNewButtonState() {
var button = $(self.currentImageListId + ' .new-image');
if (this.maxImages !== undefined && this.countActiveImages() >= this.maxImages) {
//hide the button
button.hide(); // //console.log("hide add new image button");
} else {
//show the button
button.show(); // //console.log("show add new image button");
}
}
}, {
key: "updateImages",
value: function updateImages() {
var images = JSON.stringify(this.images, null, 2); //console.log('Update images: '+images);
$('#' + this.key).val(images); //console.log("Updated images: id:"+'#'+this.key+" with json data:"+JSON.stringify(this.images, null, 2));
//console.log($('#'+this.key));
this.checkNewButtonState();
}
}, {
key: "countActiveImages",
value: function countActiveImages() {
//console.log("countActiveImages: ");
//console.log(this.images);
var count = 0;
for (var i = 0; i < this.images.length; i++) {
if (!this.images[i]["delete"]) count++;
} //console.log("countActiveImages thats: "+count+" length: "+this.images.length);
return count;
}
}, {
key: "removeFromImages",
value: function removeFromImages(idOrFileInputName) {
//console.log('Removing image: '+idOrFileInputName);
//console.log('this.images: ');
//console.log(this.images);
for (var i = 0; i < this.images.length; i++) {
if (this.images[i].name == idOrFileInputName) {
this.images.splice(i, 1);
this.updateImages();
return;
}
if (this.images[i].id == idOrFileInputName) {
this.images[i]["delete"] = true;
this.updateImages();
return;
}
}
}
}]);
return ImageController;
}();
var MultiSelectController = /*#__PURE__*/function () {
/**
* @param multiSelectElement {HTMLInputElement}
*/
function MultiSelectController(multiSelectElement) {
_classCallCheck(this, MultiSelectController);
if (multiSelectElement.tagName !== 'INPUT' || multiSelectElement.type !== 'text') {
console.error('The given parameter must be an instance of HTMLInputElement');
return;
}
this.multiSelectSelectField = multiSelectElement; //The input element that must multiSelect what you type
var input = this.multiSelectSelectField.parentElement.querySelector('input[type="hidden"]'); //The input element that wil store the real value for the multiSelect Attribute
if (!input) {
console.error('Expected an HTMLInputElement as a sibling of the supplied multiSelect element (HTMLInputElement) to store the multiSelect\'s real value');
return;
}
this.input = input;
if (!'attributeKey' in this.multiSelectSelectField.dataset) {
console.error('attributeKey dataset value not set');
return;
}
this.attributeKey = this.multiSelectSelectField.dataset.attributeKey;
if (!'autosaveUrl' in this.multiSelectSelectField.dataset) {
console.error('autosaveUrl dataset value not set');
return;
}
this.autosaveUrl = this.multiSelectSelectField.dataset.autosaveUrl;
if (!'maxItemsToSelect' in this.multiSelectSelectField.dataset) {
console.error('maxItemsToSelect dataset value not set');
return;
}
this.maxItemsToSelect = this.multiSelectSelectField.dataset.maxItemsToSelect;
if (!'itemData' in this.multiSelectSelectField.dataset) {
console.error('itemData dataset value not set');
return;
}
this.dataSet = JSON.parse(this.multiSelectSelectField.dataset.itemdata);
if (!'values' in this.multiSelectSelectField.dataset) {
console.error('values dataset value not set');
return;
}
this.valuesFromAttribute = this.multiSelectSelectField.dataset.values.split(',');
var openElement = this.input.parentElement.querySelector('.open');
if (!openElement) {
console.error('Could not find multiSelect open element. It should be a sibling of the input');
}
this.openbutton = openElement;
var itemsWrapper = multiSelectElement.parentElement.parentElement.querySelector('div.items');
if (!itemsWrapper) {
console.error('Could not find a div HTMLElement with class "items" inside the multiSelectsInputElement\'s parent parent element');
}
this.itemsWrapper = itemsWrapper;
this.sortable = this.multiSelectSelectField.dataset.sortable;
if (this.sortable) {
var _self = this;
this.dragElement = null; // Sorting starts
itemsWrapper.addEventListener('dragstart', function (evt) {
_self.dragElement = evt.target; // Remembering an element that will be moved
// Limiting the movement type
evt.dataTransfer.effectAllowed = 'move';
evt.dataTransfer.setData('Text', _self.dragElement.textContent); // Subscribing to the events at dnd
_self.itemsWrapper.addEventListener('dragover', _self.onDragOver.bind(_self), false);
_self.itemsWrapper.addEventListener('dragend', _self.onDragEnd.bind(_self), false);
setTimeout(function () {
// If this action is performed without setTimeout, then
// the moved object will be of this class.
_self.dragElement.classList.add('ghost');
}, 0);
}, false);
}
this.listenersEnabled = true;
this.constructedSuccessfully = true;
this.initialize();
}
_createClass(MultiSelectController, [{
key: "initialize",
value: function initialize() {
if (this.constructedSuccessfully === false) {
console.error('MultiSelectController was not constructed successfully. Could not initialize because of it');
return;
}
this.makeMultiSelect();
this.addItems();
this.updateRealInput();
this.enableListeners(true);
this.enableMultiSelectOpenButton();
}
}, {
key: "addItems",
value: function addItems() {
var dataSetLength = this.dataSet.length;
var valueFromAttributeLength = this.valuesFromAttribute.length;
for (var valuesIndex = 0; valuesIndex < valueFromAttributeLength; valuesIndex++) {
var idFromAttribute = parseInt(this.valuesFromAttribute[valuesIndex]);
for (var itemIndex = 0; itemIndex < dataSetLength; itemIndex++) {
var item = this.dataSet[itemIndex];
if (item.id === idFromAttribute) {
this.addItem(item.id, item.value);
break;
}
}
}
}
/**
* Makes the fake input field and multiSelect input field.
* Focus method is triggered when you hover over items in the menu
* select method is triggered when you click an item in the list.
*/
}, {
key: "makeMultiSelect",
value: function makeMultiSelect() {
var self = this;
var jqueryElement = $(this.multiSelectSelectField);
return jqueryElement.autocomplete({
source: this.dataSet,
minLength: 0,
focus: function focus(event, ui) {
return false;
},
select: function select(event, ui) {
$(this.multiSelectSelectField).val("");
self.addItem(ui.item.id, ui.item.value);
self.updateRealInput();
self.autosaveIfNeeded();
self.enableListeners(true);
return false;
}
});
}
/**
* Make sure we can open the multiSelect field dropdown with the open button
*/
}, {
key: "enableMultiSelectOpenButton",
value: function enableMultiSelectOpenButton() {
var self = this;
this.openbutton.addEventListener('click', function (event) {
$(self.multiSelectSelectField).autocomplete("search", "");
});
}
/**
* Adds a span tag containing the value given and the data-id property set to id given to
* the p tag with class items.
*/
}, {
key: "addItem",
value: function addItem(id, value) {
var self = this;
if (this.itemsCount() > self.maxItemsToSelect) return;
var itemElement = document.createElement('p');
itemElement.classList.add('item');
if (this.sortable) {
itemElement.draggable = true;
value = '<span class="drag-icon"></span><span class="text">' + value + '</span>';
}
itemElement.innerHTML = value;
var removeButton = document.createElement('span');
removeButton.classList.add('remove');
itemElement.dataset.id = id;
itemElement.dataset.sort_order = this.itemsCount();
removeButton.addEventListener('click', function (itemToRemove) {
return function () {
if (!self.listenersEnabled) return;
self.removeItem(itemToRemove);
};
}(id));
this.itemsWrapper.appendChild(itemElement);
itemElement.appendChild(removeButton);
}
}, {
key: "itemsCount",
value: function itemsCount() {
return this.itemsWrapper.childNodes.length;
}
}, {
key: "removeItem",
/**
* Iterates over the child elements of the p element with class items and removes the element that has
* data-id set to the specified id. Then calls updateRealInput to update the hidden input
*/
value: function removeItem(id) {
var items = this.itemsWrapper.children;
var itemsLength = this.itemsWrapper.children.length;
for (var index = 0; index < itemsLength; index++) {
var item = items[index];
if (parseInt(item.dataset.id) === id) {
this.itemsWrapper.removeChild(item);
break;
}
}
this.updateRealInput();
this.autosaveIfNeeded();
}
}, {
key: "updateRealInput",
/**
* Iterates over the child elements of the p element with class items and concatenates their data-id
* values into a string. After that it sets the hidden input with the id string
*/
value: function updateRealInput() {
var ids = [];
var items = this.itemsWrapper.children;
var itemsLength = items.length;
for (var i = 0; i < itemsLength; i++) {
var item = items[i];
ids[ids.length] = item.dataset.id;
}
var idString = ids.join(',');
this.input.setAttribute('value', idString);
var changeEvent = document.createEvent("Event");
changeEvent.initEvent("change", false, true); // args: string type, boolean bubbles, boolean cancelable
this.input.dispatchEvent(changeEvent);
}
}, {
key: "autosaveIfNeeded",
value: function autosaveIfNeeded() {
if (!this.autosaveUrl) return;
var itemIds = this.input.getAttribute('value');
var self = this;
$.ajax({
type: "POST",
url: this.autosaveUrl,
data: {
'itemIds': itemIds
},
success: function success(response, textStatus, xhr) {
if (xhr.status === 200) {
console.log('autosave successfull to url: ' + self.autosaveUrl);
} else {
console.error('autosave failure to url (no code 200): ' + self.autosaveUrl + '');
console.error(response);
}
},
error: function error(message) {
console.error('autosave failure to url: ' + self.autosaveUrl + '');
console.error(message);
},
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
dataType: 'json'
});
}
}, {
key: "enableListeners",
value: function enableListeners(enable) {
this.listenersEnabled = enable;
var length = this.itemsWrapper.children.length; //Add / remove listeners to items
for (var i = 0; i < length; i++) {
var item = this.itemsWrapper.children[i];
var id = item.dataset.id;
item.classList.remove('readonly');
this.multiSelectSelectField.classList.remove('hidden');
if (!enable) {
item.classList.add('readonly');
this.multiSelectSelectField.classList.add('hidden');
this.openbutton.classList.add('hidden');
}
}
}
}, {
key: "onDragOver",
value: function onDragOver(evt) {
evt.preventDefault();
evt.dataTransfer.dropEffect = 'move';
var target = evt.target;
if (target && target !== this.dragElement && target.nodeName === 'P') {
// Sorting
this.itemsWrapper.insertBefore(this.dragElement, target.nextSibling || target);
}
}
}, {
key: "onDragEnd",
value: function onDragEnd(evt) {
evt.preventDefault();
this.dragElement.classList.remove('ghost');
this.itemsWrapper.removeEventListener('dragover', this.onDragOver, false);
this.itemsWrapper.removeEventListener('dragend', this.onDragEnd, false);
console.log("dragEnd");
this.updateRealInput();
}
}]);
return MultiSelectController;
}(); //also @See onOff.blade.php
var OnOff = /*#__PURE__*/function () {
function OnOff() {
_classCallCheck(this, OnOff);
}
_createClass(OnOff, [{
key: "toggleOnOff",
value: function toggleOnOff($id) {
var onOffBox = document.getElementById($id);
var onOffSwitch = document.getElementById($id + '-switch');
if (onOffBox.checked) {
onOffBox.value = '1';
onOffSwitch.classList.add('on');
onOffBox.setAttribute('checked', true);
} else {
onOffBox.value = '0';
onOffSwitch.classList.remove('on');
onOffBox.removeAttribute('checked');
}
}
}, {
key: "toggleOnOffSwitch",
value: function toggleOnOffSwitch($id) {
var onOffBox = document.getElementById($id);
onOffBox.checked = onOffBox.checked ? onOffBox.checked = false : onOffBox.checked = true;
this.toggleOnOff($id);
var changeEvent = document.createEvent("Event");
changeEvent.initEvent("change", false, true); // args: string type, boolean bubbles, boolean cancelable
onOffBox.dispatchEvent(changeEvent);
}
}]);
return OnOff;
}();
var PasswordController = /*#__PURE__*/function () {
/**
* Validates password fields.
* The password fields values wil be imploded with a pipe symbol
*
* @param passwordInputSelector The css selector for selecting the password input fields
* @param wrapperSelector The css selector for the wrapper div / element that wraps the first and second input fields along the validation helper
* @param passwordDontMatchErrorText string
* @param saveButtonId The id of a save button that needs to be disabled when the passwords are not valid
* @param minPasswordLength int
* @param wrapperHasTitleAttributeAndErrorClass Must be set to true if the wrapper (selected with the wrapper selector) has the ability to have an error class and title attribute for displaying an error
*/
function PasswordController(passwordInputSelector, wrapperSelector, passwordDontMatchErrorText, saveButtonId) {
var minPasswordLength = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 6;
var wrapperHasTitleAttributeAndErrorClass = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
_classCallCheck(this, PasswordController);
this.wrapperHasTitleAttributeAndErrorClass = wrapperHasTitleAttributeAndErrorClass;
this.wrapper = document.querySelector(wrapperSelector);
this.saveButton = document.querySelector("#" + saveButtonId);
this.firstPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + '-1]');
this.secondPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + '-2]');
this.realPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + ']');
this.validationMessageWrapperSelector = '.validationHelper';
this.validationMessageWrapper = this.wrapper.querySelector(this.validationMessageWrapperSelector);
this.minPasswordLength = minPasswordLength; //Used for validation
this.letter = this.validationMessageWrapper.querySelector(".letter");
this.capital = this.validationMessageWrapper.querySelector(".capital");
this.number = this.validationMessageWrapper.querySelector(".number");
this.length = this.validationMessageWrapper.querySelector(".length");
this.match = this.validationMessageWrapper.querySelector(".match"); // this.noPipe = document.querySelector(this.validationMessageWrapperSelector + " .noPipe");
this.activateListeners(true);
}
/**
* Activates listening for keyup events on the password fields to that the passwordChanged method is triggered
*
* @param state
*/
_createClass(PasswordController, [{
key: "activateListeners",
value: function activateListeners(state) {
var self = this;
var validationHelper = this.validationMessageWrapper;
if (state) {
this.firstPasswordInput.addEventListener('keyup', self.debounce(function () {
self.passwordChanged();
}, 100));
this.secondPasswordInput.addEventListener('keyup', self.debounce(function () {
self.passwordChanged();
}, 100));
this.firstPasswordInput.addEventListener('focus', function () {
if (!validationHelper.classList.contains('active')) validationHelper.classList.add('active');
});
this.secondPasswordInput.addEventListener('focus', function () {
if (!validationHelper.classList.contains('active')) validationHelper.classList.add('active');
});
this.firstPasswordInput.addEventListener('blur', function () {
if (validationHelper.classList.contains('active')) validationHelper.classList.remove('active');
});
this.secondPasswordInput.addEventListener('blur', function () {
if (validationHelper.classList.contains('active')) validationHelper.classList.remove('active');
});
} else {
this.firstPasswordInput.removeEventListener('keyup', self.debounce);
this.secondPasswordInput.removeEventListener('keyup', self.debounce);
this.firstPasswordInput.removeEventListener('focus');
this.secondPasswordInput.removeEventListener('focus');
this.firstPasswordInput.removeEventListener('blur');
this.secondPasswordInput.removeEventListener('blur');
}
}
/**
* Triggered when one of the password fields are changed and if the listeners for those fields are active
*/
}, {
key: "passwordChanged",
value: function passwordChanged() {
console.log('password changed');
var value1 = this.firstPasswordInput.value;
var value2 = this.secondPasswordInput.value;
var valid = this.validate(value1, value2);
console.log(valid);
if (valid) this.realPasswordInput.value = value2;else this.realPasswordInput.value = '';
this.enableValidMessage(valid);
this.enableSaveButton(valid);
this.removeWrapperError();
}
}, {
key: "enableValidMessage",
value: function enableValidMessage(enable) {
var validationHelper = this.validationMessageWrapper;
if (enable) {
if (!validationHelper.classList.contains('valid')) validationHelper.classList.add('valid');
} else {
if (validationHelper.classList.contains('valid')) validationHelper.classList.remove('valid');
}
}
}, {
key: "enableSaveButton",
value: function enableSaveButton(enable) {
console.log(enable);
if (enable) {
if (this.saveButton.classList.contains('disabled')) this.saveButton.classList.remove('disabled');
} else {
if (!this.saveButton.classList.contains('disabled')) this.saveButton.classList.add('disabled');
}
}
/**
* Removes the error that may be set on the wrapper
*/
}, {
key: "removeWrapperError",
value: function removeWrapperError() {
if (!this.wrapperHasTitleAttributeAndErrorClass) return;
if (this.wrapper.hasAttribute('title')) this.wrapper.setAttribute('title', '');
if (this.wrapper.classList.contains('error')) this.wrapper.classList.remove('error');
}
/**
* Validate two values and return true or false if respectively valid or not
*
* @param value1
* @param value2
* @returns {boolean}
*/
}, {
key: "validate",
value: function validate(value1, value2) {
var valid = true; // Validate lowercase letters
var lowerCaseLetters = /[a-z]/g;
if (value1.match(lowerCaseLetters)) {
this.letter.classList.remove("invalid");
this.letter.classList.add("valid");
} else {
this.letter.classList.remove("valid");
this.letter.classList.add("invalid");
valid = false;
} // Validate capital letters
var upperCaseLetters = /[A-Z]/g;
if (value1.match(upperCaseLetters)) {
this.capital.classList.remove("invalid");
this.capital.classList.add("valid");
} else {
this.capital.classList.remove("valid");
this.capital.classList.add("invalid");
valid = false;
} // Validate numbers
var numbers = /[0-9]/g;
if (value1.match(numbers)) {
this.number.classList.remove("invalid");
this.number.classList.add("valid");
} else {
this.number.classList.remove("valid");
this.number.classList.add("invalid");
valid = false;
} // Validate numbers
// let pipe = /\|/g;
// if(value1.match(pipe)) {
// this.noPipe.classList.remove("valid");
// this.noPipe.classList.add("invalid");
// valid = false;
// } else {
// this.noPipe.classList.remove("invalid");
// this.noPipe.classList.add("valid");
// }
// Validate length
if (value1.length >= this.minPasswordLength) {
this.length.classList.remove("invalid");
this.length.classList.add("valid");
} else {
this.length.classList.remove("valid");
this.length.classList.add("invalid");
valid = false;
} // Validate password match
if (value1 === value2 && (value1 !== '' || value2 !== '')) {
this.match.classList.remove("invalid");
this.match.classList.add("valid");
} else {
this.match.classList.remove("valid");
this.match.classList.add("invalid");
valid = false;
}
return valid;
}
/**
* Triggers the function after the wait time (milliseconds) has expired and only
* if the function is not triggered again before the wait time expired.
*
* @param func
* @param wait
* @param immediate
* @returns {Function}
*/
}, {
key: "debounce",
value: function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function later() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
}]);
return PasswordController;
}(); //Also See select.blade.php
$(function () {
if (!document.querySelector(".select-menu")) return;
$(".select-menu").selectmenu({
width: '100%',
create: function create(event, ui) {
buttonId = this.id + '-button';
menuId = this.id + '-menu';
},
open: function open(event, ui) {
var button = document.getElementById(this.id + '-button');
var menu = document.getElementById(this.id + '-menu');
menu.style.width = button.offsetWidth + 'px';
menu.parentNode.style.width = button.offsetWidth + 'px';
button.classList.add('dropdown-open');
},
change: function change(event, ui) {
var button = document.getElementById(this.id + '-button');
var buttonText = button.querySelector('.ui-selectmenu-text').innerHTML;
button.querySelector('.ui-selectmenu-text').innerHTML = buttonText.replace(/ /gi, '');
var changeEvent = document.createEvent("Event");
changeEvent.initEvent("change", false, true); // args: string type, boolean bubbles, boolean cancelable
button.dispatchEvent(changeEvent);
},
close: function close(event, ui) {
var button = document.getElementById(this.id + '-button');
button.classList.remove('dropdown-open');
}
});
});
/**
* Helps managing classes on a button.
* You can request to add a class and for each time you request to add the class, it will increment a counter.
* You can also request to remove a class and for each time you do that, it will decrement a counter.
* When that counter hits 0 it will remove the class.
* It will keep counter for each unique class you request to add.
*/
var styleClassController = /*#__PURE__*/function () {
/**
* Constructor
*
* @param {HTMLElement} htmlElement
*/
function styleClassController(htmlElement) {
_classCallCheck(this, styleClassController);
this.constructedSuccessFully = false;
if (!htmlElement instanceof HTMLElement) {
console.error('styleClassController: The given htmlElement must be, but was not a HTMLElement');
return;
}
this.htmlElement = htmlElement;
this.classCounts = {};
this.constructedSuccessFully = true;
}
/**
* @param {string} styleClass
*/
_createClass(styleClassController, [{
key: "requestAddClass",
value: function requestAddClass(styleClass) {
if (!this.htmlElement.classList.contains(styleClass)) this.htmlElement.classList.add(styleClass);
if (!this.classCounts.hasOwnProperty(styleClass)) this.classCounts[styleClass] = 0;
this.classCounts[styleClass]++;
return true;
}
}, {
key: "requestRemoveClass",
value: function requestRemoveClass(styleClass) {
if (!this.htmlElement.classList.contains(styleClass) || !this.classCounts.hasOwnProperty(styleClass)) return false;
this.classCounts[styleClass]--;
if (this.classCounts[styleClass] === 0) {
delete this.classCounts[styleClass];
this.htmlElement.classList.remove(styleClass);
}
}
}]);
return styleClassController;
}();