File: D:/HostingSpaces/SBogers27/dndin.nl/wwwroot/js/kms/core.js
'use strict';
//inject directives and services.
var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var app = angular.module('fileUpload', ['ngFileUpload']);
app.controller('fileUploadController', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
console.log('fileuploadcontroller loading');
//The files list
//Todo, extend with the files form the database
$scope.files = [];
//These are the fileIds, used for saving
$scope.dynamic = false;
$scope.uploadSizes = '';
$scope.maxImages;
$scope.errorMsg = {};
$scope.subFolder = false;
$scope.attributeKey = '';
$scope.forModel;
$scope.forModelId;
$scope.canUploadNewImage;
/**
* This function uploads the new files
* @param files
* @param errFiles
* @param maximages
* @param blockId
* @param tabId optional
*/
$scope.uploadFiles = function (files, errFiles, maximages, blockId, tabId) {
console.log("upload for block with blockId: " + blockId + " and tabKey: " + tabId);
console.log("uploadedFiles files:");
console.log(files);
//Get the model and the id where we are uploading images for. Should flow via a service but due to bad design and an upcoming newer angular version does not. todo: improve me
var htmlElement = document.querySelector("[ng-controller=KmsAttributeDynamicController]");
$scope.forModel = htmlElement.dataset.forModel;
$scope.forModelId = htmlElement.dataset.forModelId;
console.log("fileUploadController uploading files For model: " + $scope.forModel + " with id: " + $scope.forModelId + " and blockId: " + blockId);
if (typeof $scope.files == 'undefined') $scope.files = [];
if ($scope.files.length >= maximages) {
console.log("File upload not allowed. " + $scope.files.length + "/" + maximages + " uploaded");
return false;
}
//Set the files
$scope.errFiles = errFiles;
//Foreach each file
angular.forEach(files, function (file) {
//Push to true adds image at the back, false at the front
var push = true;
//Add the placeholder
var loadingImage = { loading: true, thumb_image_url: '/images/kms/loading.gif' };
if (push == true) {
$scope.files.push(loadingImage);
var imageKey = $scope.files.length - 1;
} else {
//Add at the front
$scope.files.unshift(loadingImage);
var imageKey = 0;
}
//Upload to the server
file.upload = Upload.upload({
url: '/kms/upload',
data: {
//Sent the data and the options
file: file,
uploadSizes: $scope.uploadSizes,
dynamic: $scope.dynamic,
subFolder: $scope.subFolder,
attribute_key: $scope.attributeKey,
forModelName: $scope.forModel,
forModelId: $scope.forModelId,
forBlockId: blockId,
forTabId: tabId
}
});
//After uploading
file.upload.then(function (response) {
$timeout(function () {
// delete $scope.files.loading
console.log(response);
//Set the response data
// file.result = response.data;
// file.result = response.data.uploaded[0];
// console.log("Thumb: "+response.data.uploaded.[0].thumb);
console.log("Image Id: " + response.data.uploaded[0].id);
//Add the file to the current files
$scope.files[imageKey] = response.data.uploaded[0];
console.log("$scope.files[" + imageKey + "] =");
console.log($scope.files[imageKey]);
//Reverse push
//Add the file to the current files
// $scope.files.unshift(file.result);
// $scope.setFileIds()
//Update fileids
var forBlockId = response.data.uploaded[0].forBlockId;
var blocksDataObject = $scope.getBlocksData(); //Defined in the KmsAttributeDynamicController
for (var key in blocksDataObject) {
console.log("Looping over blocks to find a block with id: " + forBlockId + ". Current block id: " + blocksDataObject[key].blockId);
// console.log(blocksDataObject[key]);
if (blocksDataObject.hasOwnProperty(key) === false || blocksDataObject[key].hasOwnProperty("blockId") === false) {
console.warn("Detected block data without a block id. Because of this, it is not possible to upload a file for that block. This does not mean that the uploaded image can be linked to the block your uploading currently for");
continue;
}
if (blocksDataObject[key].blockId == forBlockId) {
console.log("found block with id: " + forBlockId);
var data = [];
if (response.data.uploaded[0].forTabId) {
console.log("Uploaded an image for tab: " + response.data.uploaded[0].forTabId);
data = response.data.uploaded[0].id + "#" + response.data.uploaded[0].forTabId; //imageid#multipleimagesslot
} else {
console.log("Uploaded an image without tab: " + response.data.uploaded[0].id);
data = response.data.uploaded[0].id;
}
var fileIds = [];
if (blocksDataObject[key].hasOwnProperty('fileIds')) {
var length = blocksDataObject[key]['fileIds'].length;
//Determine if it is a single image or multiple images.
blocksDataObject[key]['fileIds'][length] = data;
console.log("Updating fileIds with image id: " + data);
} else {
console.log("Setting fileIds to a new array with image id: " + data);
blocksDataObject[key].fileIds = [data];
}
console.log("files.length = " + blocksDataObject[key].fileIds.length + " maxImages = " + $scope.maxImages);
$scope.canUploadNewImage = blocksDataObject[key].fileIds.length < $scope.maxImages;
}
$scope.setBlocksData(blocksDataObject);
}
});
}, function (response) {
if (response.status > 0) $scope.errorMsg = response.status + ': ' + response.data;
console.error("Error: " + $scope.errorMsg);
}, function (evt) {
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
});
};
$scope.deleteImage = function (index, blockId, tab_key) {
var idToDelete = $scope.files[index].id;
console.log("idToDelete: " + idToDelete + " from blockId: " + blockId);
//Delete the image
$scope.files.splice(index, 1);
console.log("Current image amount: " + $scope.files.length);
//Delete the image id
// $scope.setFileIds()
var blocksDataObject = $scope.getBlocksData(); //Defined in the KmsAttributeDynamicController
for (var blockIndex in blocksDataObject) {
if (blocksDataObject.hasOwnProperty(blockIndex) === false || blocksDataObject[blockIndex].hasOwnProperty("blockId") === false) {
console.warn("Detected block data without a block id. Because of this, it is not possible to upload a file for that block. This does not mean that the uploaded image can be linked to the block your uploading currently for");
continue;
}
if (blocksDataObject[blockIndex].blockId == blockId) {
console.log("found block with id: " + blockId);
if (blocksDataObject[blockIndex].hasOwnProperty('fileIdsToDelete') === false) blocksDataObject[blockIndex].fileIdsToDelete = [];
console.log("Current files to delete: " + blocksDataObject[blockIndex].fileIdsToDelete);
idToDelete = typeof tab_key !== 'undefined' ? idToDelete + "#" + tab_key : idToDelete;
for (var index in blocksDataObject[blockIndex].fileIds) {
var currentId = blocksDataObject[blockIndex].fileIds[index];
if (typeof tab_key !== 'undefined') {
console.log("Looping over the file ids to find an image with id: " + idToDelete + " for tab: " + tab_key + " (" + currentId + ")");
} else {
console.log("Looping over the file ids to find an image with id: " + idToDelete);
}
if (currentId == idToDelete) {
console.log("Image marked to delete on save: " + idToDelete);
blocksDataObject[blockIndex].fileIdsToDelete[blocksDataObject[blockIndex].fileIdsToDelete.length] = idToDelete;
blocksDataObject[blockIndex].fileIds.splice(index, 1);
if (typeof tab_key === 'undefined') {
$scope.canUploadNewImage = blocksDataObject[blockIndex].fileIds.length < $scope.maxImages;
} else {
var count = 0;
for (var index in blocksDataObject[blockIndex].fileIds) {
if (blocksDataObject[blockIndex].fileIds[index].split("#")[1] == tab_key) {
count++;
}
}
$scope.canUploadNewImage = count < $scope.maxImages;
}
break;
}
}
}
}
$scope.setBlocksData(blocksDataObject);
delete $scope.errorMsg.toMany;
};
// $scope.moveImage = function (index, direction) {
// var currentFile = $scope.files[index]
// var currentFileId = $scope.fileIds[index]
//
// if (direction == 'left') {
// $scope.files[index] = $scope.files[index - 1];
// $scope.files[index - 1] = currentFile;
// } else {
// $scope.files[index] = $scope.files[index + 1];
// $scope.files[index + 1] = currentFile;
// }
// $scope.setFileIds()
// };
$scope.initFiles = function (files, maxImages, tab_key) {
console.log("fileupload:initFiles: " + files + " maxImages: " + maxImages);
if (files) {
// //Strip out the image ids that do not belong to the tab we are processing for
var filesToUse = [];
if (typeof tab_key !== 'undefined') {
for (var index in files) {
var split = files[index].split("#");
if (split.length !== 2) continue; //The imageId did not contain a #
if (split[1] != tab_key) {
console.log("fileupload:initFiles: Ignoring image with id: " + split[0] + " because it belongs to tab " + split[1] + " and we are processing images for tab " + tab_key);
} else {
filesToUse[filesToUse.length] = files[index];
}
}
} else {
filesToUse = files;
}
if (filesToUse.length > 0) {
$.ajax({
type: "POST",
url: "/kms/getimagedata",
data: {
fileIds: filesToUse
},
success: function success(response) {
console.log("Retrieved files: ");
console.log(response);
// files must look like this files[index].id files[index].sizes
$scope.files = response;
// $scope.setFileIds();
if (typeof maxImages != 'undefined') {
$scope.maxImages = maxImages;
}
console.log("files.length < $scope.maxImages: " + filesToUse.length < $scope.maxImages);
$scope.canUploadNewImage = filesToUse.length < $scope.maxImages;
$scope.$apply();
},
error: function error() {
console.log("An error occured while retrieving image(s)");
},
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
dataType: 'json'
});
} else {
$scope.maxImages = maxImages;
$scope.canUploadNewImage = true;
$scope.files = [];
}
} else {
$scope.maxImages = maxImages;
$scope.canUploadNewImage = true;
$scope.files = [];
}
};
$scope.updateFiles = function (files) {
console.log("Updated files");
$scope.files = files;
};
// $scope.setFileIds = function () {
// var local_fileIds = [];
//
// angular.forEach($scope.files, function (file) {
// local_fileIds.push(file.id);
// });
//
// console.log("set file ids ($scope.fileIds):");
// console.log(local_fileIds);
// $scope.fileIds = local_fileIds
// };
// $scope.getFileCount = function () {
// return $scope.fileIds.length;
// };
$scope.sortableOptions = {
update: function update(e, ui) {
ui.item.sortable.cancel();
var originalIndex = ui.item.sortable.index;
var newIndex = ui.item.sortable.dropindex;
var oldImage = $scope.files[originalIndex];
$scope.files[originalIndex] = $scope.files[newIndex];
$scope.files[newIndex] = oldImage;
$scope.setFileIds();
}
};
console.log('fileuploadcontroller initialized');
}]);
'use strict';
angular.element(document).ready(function () {
// angular.element(document.querySelector('[ng-controller]')).scope().debug();
// //console.log('page loading completed');
});
angular.module('kms.dynamic-attribute', []).controller('KmsAttributeDynamicController', function ($scope, $element, $compile, $timeout) {
//console.log('KmsAttributeDynamicController initializing');
// var htmlElement = document.querySelector("[ng-controller=KmsAttributeDynamicController]");
//console.log("Controller element");
//console.log($($element)[0]);
var htmlElement = $($element)[0];
//For which model and id of the model the dynamic attribute works
$scope.forModel = htmlElement.dataset.forModel;
$scope.forModelId = htmlElement.dataset.forModelId;
//console.log("KmsAttributeDynamicController further initializing For model: "+$scope.forModel+" with id: "+$scope.forModelId);
$scope.key = htmlElement.dataset.key;
//console.log("Controller key: "+$scope.key);
var removeBlocks = function removeBlocks() {
// Remove the block list for re-render
angular.element('#' + $scope.key + '_blocks .inner').remove();
};
// Check if any blocks exists to prevent JSON.parse error
// Default is an empty array
$scope.blocks = [];
var html = $('#' + $scope.key + '_data', $element).html();
//console.log("JSON to parse (in element: #"+$scope.key+"_data): "+html);
if (html != '' && html != '""' && html != undefined) {
$scope.blocks = JSON.parse(html);
} else {}
//console.log("Element called: " + "#" + $scope.key + "_data does not have json data set");
//console.log('scope blocks');
//console.log($scope.blocks);
$scope.blockSettings = {};
var blockSettingsElement = document.getElementById('blockSettings');
if (blockSettingsElement) {
var block_settings = blockSettingsElement.value;
if (block_settings != '' && block_settings != '""') {
$scope.blockSettings = JSON.parse(block_settings);
}
} else {}
//console.log("No blocksettings element");
//console.log("blocksettings");
//console.log($scope.blockSettings);
$scope.blockTypes = getBlockTypes($scope.blockSettings);
$scope.addBlock = function (blockType) {
if (!angular.isUndefined(blockType)) {
$scope.blocks.push(angular.copy(blockType));
}
};
$scope.removeBlock = function (block) {
startToMove();
var index = $scope.blocks.indexOf(block);
$scope.blocks.splice(index, 1);
stopToMove();
};
$scope.upBlock = function (block) {
//load index from the block
var index = $scope.blocks.indexOf(block);
//if the index is 0 return
if (index < 1) return;
//Remove the editor
startToMove();
//Set the block index-1 to current index
$scope.blocks[index] = $scope.blocks[index - 1];
//set the triggerd block to index-1
$scope.blocks[index - 1] = block;
//enable the editor
stopToMove();
};
$scope.downBlock = function (block) {
//load the index from the block
var index = $scope.blocks.indexOf(block);
//If the block is the last return false
if (index >= $scope.blocks.length - 1) return;
//Remove the editor
startToMove();
//set the block +1 to the current index
$scope.blocks[index] = $scope.blocks[index + 1];
//set the triggerd block to index +1
$scope.blocks[index + 1] = block;
//enable the editor
stopToMove();
};
$scope.deleteImage = function (direction, block_key, image_key, tab_key) {
if (tab_key == null) {
$scope.blocks[block_key].images.splice(image_key, 1);
} else {
$scope.blocks[block_key].tab[tab_key].images.splice(image_key, 1);
}
};
$scope.deleteFile = function (block_key) {
delete $scope.blocks[block_key].file;
};
$scope.changeOrder = function (direction, block_key, image_key, tab_key) {
//load the index from the block
var index = image_key;
if (tab_key == null) {
var temp_image = $scope.blocks[block_key].images[image_key];
switch (direction) {
case 'left':
if (index == 0) return;
$scope.blocks[block_key].images[image_key] = $scope.blocks[block_key].images[image_key - 1];
$scope.blocks[block_key].images[image_key - 1] = temp_image;
break;
case 'right':
if (index + 1 == $scope.blocks[block_key].images.length) return;
$scope.blocks[block_key].images[image_key] = $scope.blocks[block_key].images[image_key + 1];
$scope.blocks[block_key].images[image_key + 1] = temp_image;
break;
}
} else {
var temp_image = $scope.blocks[block_key].tab[tab_key].images[image_key];
switch (direction) {
case 'left':
if (index == 0) return;
$scope.blocks[block_key].tab[tab_key].images[image_key] = $scope.blocks[block_key].tab[tab_key].images[image_key - 1];
$scope.blocks[block_key].tab[tab_key].images[image_key - 1] = temp_image;
break;
case 'right':
if (index + 1 == $scope.blocks[block_key].tab[tab_key].images.length) return;
$scope.blocks[block_key].tab[tab_key].images[image_key] = $scope.blocks[block_key].tab[tab_key].images[image_key + 1];
$scope.blocks[block_key].tab[tab_key].images[image_key + 1] = temp_image;
break;
}
}
};
/**
* Add new image tab
* @param block_index
*/
$scope.addImageTab = function (block_index) {
$scope.blocks[block_index].tab.push({ title: '' });
var new_index = $scope.blocks[block_index].tab.length;
//set the new tab as active (-1) arrays start at 0
$scope.setActiveTab(block_index, new_index - 1);
};
/**
* Remove image tab
* @param block_index
*/
$scope.removeImageTab = function (block_index, tab_index) {
$scope.blocks[block_index].tab.splice(tab_index, 1);
//set the active tab to 0
$scope.setActiveTab(block_index, 0);
};
$scope.setActiveTab = function (index, tab) {
$scope.blocks[index].active_tab = tab;
};
$scope.moveTab = function (direction, index, tab_index) {
var temptab = $scope.blocks[index].tab[tab_index];
switch (direction) {
case 'left':
if (tab_index == 0) return;
$scope.blocks[index].tab[tab_index] = $scope.blocks[index].tab[tab_index - 1];
$scope.blocks[index].tab[tab_index - 1] = temptab;
break;
case 'right':
if (tab_index + 1 == $scope.blocks[index].tab.length) return;
$scope.blocks[index].tab[tab_index] = $scope.blocks[index].tab[tab_index + 1];
$scope.blocks[index].tab[tab_index + 1] = temptab;
break;
}
};
$scope.setUniqueId = function (block_index) {
if (typeof $scope.blocks[block_index].blockId == 'undefined') {
var stamp = new Date().valueOf();
$scope.blocks[block_index].blockId = Math.round(stamp + Math.random() * 1000);
}
};
$scope.debug = function () {
//console.log('key: ' + $scope.key);
};
//console.log('KmsAttributeDynamicController initialized');
}).directive('block', function ($compile) {
return {
restrict: 'E',
template: '<div class="header">' + '<div class="start">' + '<div class="block-title">{{block.typeName}}</div>' + '<div class="buttons">' + '<div class="position-button up" ng-click="upBlock(block)"></div>' + '<div class="position-button down" ng-click="downBlock(block)"></div>' + '</div></div>' + '<div class="end">' + '<div class="btn btn-danger btn-trash" ng-click="removeBlock(block)"> </div>' + '</div></div>',
link: function link(scope, element, attr) {
switch (scope.block.typeSlug) {
case 'content-block':
// //console.log('rendering a content block with this data: '+scope.block);
scope.imageBoxId = scope.key + '-image-box-' + scope.$index;
scope.textBoxId = scope.key + '-text-box-' + scope.$index;
//console.log("Rendering content-block (afbeelding en tekst)");
//console.log(scope.block);
element.append($compile("<content-block></content-block>")(scope));
break;
case 'view-block':
element.append($compile("<view-block></view-block>")(scope));
break;
case 'page-link-block':
element.append($compile("<page-link-block></page-link-block>")(scope));
break;
case 'image-slider-block':
element.append($compile("<image-slider-block></image-slider-block>")(scope));
break;
case 'video-block':
element.append($compile("<video-block></video-block>")(scope));
break;
case 'file-block':
element.append($compile("<file-block></file-block>")(scope));
break;
case 'two-column-block':
scope.textBoxIds = [];
scope.textBoxIds.left = scope.key + '-text-box-' + scope.$index + '-left';
scope.textBoxIds.right = scope.key + '-text-box-' + scope.$index + '-right';
element.append($compile("<two-column-block></two-column-block>")(scope));
break;
case 'full-text-block':
scope.textBoxId = scope.key + '-text-box-' + scope.$index;
element.append($compile("<full-text-block></full-text-block>")(scope));
break;
case 'full-image-block':
element.append($compile("<full-image-block></full-image-block>")(scope));
break;
case 'multiple-images-block':
element.append($compile("<multiple-images-block></multiple-images-block>")(scope));
break;
}
// //console.log("block data element: "+attr.dataElement);
scope.dataElement = document.querySelector(attr.dataElement);
scope.getBlocksData = function () {
return JSON.parse(scope.dataElement.getAttribute("value"));
};
scope.setBlocksData = function (data) {
scope.dataElement.setAttribute("value", JSON.stringify(data));
scope.$parent.blocks = data;
};
}
};
}).directive('contentBlock', function ($timeout) {
var count = 0;
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-page-content-block',
link: function link(scope, element, attrs) {
scope.image = 'imageHolder';
scope.loopCount = count;
count++;
scope.loopCount = scope.key;
// //console.log("getting content block data");
// //console.log(scope.getBlocksData();
//initiate the tinyMce editor
initiateTinyMceWithDelay(scope, $timeout, 100);
scope.openBox = function (imageBoxId) {
$.colorbox({
href: '/kms/elfinder/standalonepopup/' + imageBoxId,
fastIframe: true,
iframe: true,
width: '70%',
height: '520px'
});
};
}
};
}).directive('viewBlock', function ($timeout) {
var count = 0;
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-view',
link: function link(scope) {}
};
}).directive('twoColumnBlock', function ($timeout) {
var count = 0;
return {
restrict: 'E',
templateUrl: '/kms/api/template/two-column-block',
link: function link(scope, element, attrs) {
scope.image = 'imageHolder', scope.loopCount = count;
count++;
scope.loopCount = scope.key;
//initiate the tinyMce editor
initiateTinyMceWithDelay(scope, $timeout, 100);
scope.openBox = function (imageBoxId) {
$.colorbox({
href: '/kms/elfinder/standalonepopup/' + imageBoxId,
fastIframe: true,
iframe: true,
width: '70%',
height: '520px'
});
};
}
};
}).directive('imageSliderBlock', function () {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-image-slider-block',
link: function link(node) {
////console.log(node);
}
};
}).directive('fullImageBlock', function () {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-full-image-block',
link: function link(node) {
////console.log(node);
}
};
}).directive('fullTextBlock', function ($timeout) {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-full-text-block',
link: function link(scope) {
//initiate the tinyMce editor
initiateTinyMceWithDelay(scope, $timeout, 100);
}
};
}).directive('multipleImagesBlock', function () {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-multiple-images-block',
link: function link(node) {
////console.log(node);
}
};
}).directive('pageLinkBlock', function ($http) {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-page-link-block',
link: function link(scope, element, attr) {
scope.pages = [];
$http.get('/kms/api/pages').then(function (response) {
// Adopt data
var pages = [];
var getChildren = function getChildren(node) {
for (var child in node) {
if (node[child].title) {
pages.push({
value: node[child].id,
label: node[child].title
});
}
getChildren(node[child].children);
}
};
getChildren(response.data);
// Set the data
scope.pages = pages;
});
}
};
}).directive('videoBlock', function () {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-video-block',
link: function link(node) {
////console.log(node);
}
};
}).directive('fileBlock', function () {
return {
restrict: 'E',
templateUrl: '/kms/api/template/dynamic-file-block',
link: function link(node) {
////console.log(node);
}
};
});
/**
* Callback function for ElFinder (hard to implement in angular?)
*
* @param filePath
* @param requestingElementId
*/
function processSelectedFile(filePath, requestingElementId) {
// Get the scope of the the element that is passed into ElFinder
var elementScope = $('#' + requestingElementId).parent().parent().scope();
elementScope.block.image = filePath;
elementScope.$apply();
}
/**
* This function will initiate the tinyMce editor on an block
* It the initiation will be delayed because of the angular
*
* @param $scope
* @param $timeout
*/
function initiateTinyMceWithDelay($scope, $timeout, delay) {
//if (tinymce) tinymce.remove();
$timeout(function () {
initiateTinyMce($scope, $scope.textBoxId);
if (typeof $scope.textBoxIds !== 'undefined') {
if ($scope.textBoxIds.left != null) initiateTinyMce($scope, $scope.textBoxIds.left, 'description', 'left');
if ($scope.textBoxIds.right != null) initiateTinyMce($scope, $scope.textBoxIds.right, 'description', 'right');
}
}, delay);
}
function initiateTinyMce($scope, field, blockElement, blockSubElement) {
if (typeof field === 'undefined') {
field = $scope.textboxId;
}
if (typeof blockElement === 'undefined') {
blockElement = 'description';
}
//textboxIds[] =
tinymce.init({
elements: field,
mode: 'exact',
skin: 'kms',
menubar: false,
statusbar: false,
plugins: ['code', 'paste', 'link', 'table'],
toolbar: 'styleselect | bold italic underline | bullist numlist | indent | link | code',
height: '200',
default_link_target: "_blank",
paste_as_text: true,
style_formats: [{ title: 'Titel 1', block: 'h1' }, { title: 'Titel 2', block: 'h2' }, { title: 'Titel 3', block: 'h3' }, { title: 'Titel 4', block: 'h4' }],
convert_urls: false,
// link_list: "/kms/file-list?key=komma_kms",
setup: function setup(editor) {
editor.on('change', function (e) {
editor.save();
if (typeof blockSubElement === 'undefined') {
$scope.block[blockElement] = editor.getContent();
} else {
$scope.block[blockElement][blockSubElement] = editor.getContent();
}
if (!$scope.$$phase) {
$scope.$apply();
}
});
// Update model on keypress
editor.on('KeyUp', function (e) {
editor.save();
if (typeof blockSubElement === 'undefined') {
$scope.block[blockElement] = editor.getContent();
} else {
$scope.block[blockElement][blockSubElement] = editor.getContent();
}
if (!$scope.$$phase) {
$scope.$apply();
}
});
}
});
}
function startToMove() {
$(document).find('textarea').each(function () {
tinyMCE.execCommand('mceFocus', false, $(this).attr('id'));
tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
});
}
function stopToMove() {
//todo: Reanbling ONLY works after a timeout.
setTimeout(function () {
$(document).find('textarea').each(function () {
tinymce.execCommand('mceAddEditor', true, $(this).attr('id'));
});
}, 100);
}
function getBlockTypes(blockSettings) {
var blocks = {
two_column_block: {
typeSlug: 'two-column-block',
code_name: '',
view: '',
typeName: 'Twee tekstkolommen',
status: true,
description: { left: '', right: '' },
textWidth: '50'
},
content_block: {
typeSlug: 'content-block',
code_name: '',
view: '',
typeName: 'Afbeelding en tekst',
status: true,
location: 'left',
textWidth: '66',
description: '',
subFolder: 'dynamic',
image: null,
max_images: 4,
link: '',
link_text: 'Lees meer'
},
view_block: {
typeSlug: 'view-block',
code_name: '',
view: '',
typeName: 'View',
status: true
},
full_image_block: {
typeSlug: 'full-image-block',
code_name: '',
view: '',
typeName: '100% Afbeelding',
subFolder: 'dynamic',
max_images: 2,
status: true,
image: null
},
full_text_block: {
typeSlug: 'full-text-block',
code_name: '',
view: '',
typeName: 'Een tekstkolom',
description: '',
status: true,
link: '',
link_text: 'Lees meer'
},
multiple_images_block: {
typeSlug: 'multiple-images-block',
code_name: '',
view: '',
typeName: 'Meerdere afbeeldingen',
tab: [{
title: 'Afbeelding 1', max_images: 1 }, {
title: 'Afbeelding 2a',
max_images: 2
}, {
title: 'Afbeelding 2b (optioneel)',
max_images: 1 }],
status: true,
location: 'left',
subFolder: 'dynamic',
textWidth: '66'
},
page_link_block: {
typeSlug: 'page-link-block',
code_name: '',
view: '',
typeName: 'Page-link block',
link_text: 'Lees meer',
special: 0,
status: true,
pageId: null
},
image_slider_block: {
typeSlug: 'image-slider-block',
code_name: '',
view: '',
typeName: 'Image gallery',
tab: [{ title: '' }],
subFolder: 'dynamic',
status: true,
pageId: null
},
video_block: {
typeSlug: 'video-block',
code_name: '',
view: '',
typeName: 'Video',
youtube: '',
status: true,
pageId: null
},
file_block: {
typeSlug: 'file-block',
code_name: '',
view: '',
typeName: 'Bestand block',
title: '',
special: 0,
download_text: 'Download',
file: '',
status: true,
pageId: null
}
};
var blockTypes = {};
angular.forEach(blockSettings, function (block, blockName) {
blockTypes[blockName] = angular.merge(blocks[blockName], block);
});
return blockTypes;
}
'use strict';
var attributes = {};
var app = angular.module('kms', ['ui.bootstrap', 'ngSanitize', 'kms.dynamic-attribute', 'fileUpload'
// 'ui.select',
// 'ui.date',
// 'ui.tree',
// 'ui.sortable',
// 'ui.utils.masks',
]);
app.controller('KmsEntities', ['$scope', '$element', function ($scope, $element) {
$scope.entities = [];
$scope.paginatedEntities = [];
$scope.isSorting = false;
$scope.isSearching = function () {
return $scope.searchEntitiesText.text.length > 1;
};
$scope.currentPage = 1;
$scope.numPerPage = 5;
$scope.maxSize = 5;
var entityList = $('.entities-list-items .entities-list-item', $element);
for (var i = 0; i < entityList.length; i++) {
var dataElement = entityList[i];
var dataObject = {
thumbHtml: $('.entities-item-pre', dataElement).html(),
text: $('.entities-item-text', dataElement).html(),
status: $('.entities-item-status', dataElement).html(),
link: $('a', dataElement).first().attr('href'),
active: $(dataElement).hasClass('active')
};
$scope.entities.push(dataObject);
}
$scope.activateSorting = function () {
$scope.isSorting = true;
};
$scope.deactivateSorting = function () {
$scope.isSorting = false;
};
$scope.$watch("currentPage + numPerPage", function () {
var begin = ($scope.currentPage - 1) * $scope.numPerPage,
end = begin + $scope.numPerPage;
$scope.paginatedEntities = $scope.entities.slice(begin, end);
});
}]);
app.controller('KmsEntity', ['$scope', '$element', function ($scope, $element) {
// console.log("attaching save to scope");
$scope.save = function () {
var button = document.querySelector('input[value="submit-cloaked"]');
// console.log(button);
button.click();
};
}]);
app.controller('SortableTree', ['$scope', '$http', '$attrs', function ($scope, $http, $attrs) {
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$scope.data = [];
$scope.treeOptions = {
dropped: function dropped(event) {
$http({
method: 'POST',
url: '/kms/api/' + $attrs.siteslug + '/' + $attrs.slug,
data: { "tree": angular.toJson($scope.data) }
}).then(function (response) {});
}
};
$scope.openLink = function (id) {
window.location = $scope.url + '/' + id;
};
$scope.toggle = function (scope) {
scope.toggle();
};
var getRootNodesScope = function getRootNodesScope() {
return angular.element(document.getElementById('tree-root').scope());
};
$scope.collapseAll = function () {
var scope = getRootNodesScope();
scope.collapseAll();
};
$scope.expandAll = function () {
var scope = getRootNodesScope();
scope.expandAll();
};
// console.log('/kms/api/' + $attrs.siteslug + '/' + $attrs.slug);
$http.get('/kms/api/' + $attrs.siteslug + '/' + $attrs.slug).then(function (response) {
// console.log("Kms.js SortableTree controller got data from '"+'/kms/api/' + $attrs.siteslug + '/' + $attrs.slug+"':");
// console.log(angular.toJson(response.data));
$scope.data = response.data[0]['children'];
});
}]);
app.controller('KmsAttributes', ['$scope', function ($scope) {
$scope.attributes = attributes;
// console.log("$scope.attributes (via KmsAttributes)");
// console.log($scope.attributes);
// $scope.createModelString = function (modelKey, $itemKey) {
//
//
// //Check if the modelKey is an array structure (field_name[x])
// var match = modelKey.match(/(.*)\[(.*)]/)
//
// //There is no match, so a basic key
// if (match == null) {
// //SEt the modelKey as modelString
// $scope.modelString = modelKey
// //ItemKy is null
// $scope.itemKey = null;
// //return and exit
// return $scope.modelString
// }
//
// //Set the match[2] as the itemKey
// var itemCounter = match[2];
//
// //If the itemKey is not undefined and itemkey is the string itemKey
// if (typeof($itemKey) != "undefined" && match[2] == 'itemKey') {
// //Set the $itemKey to the scope itemKey
// itemCounter = $itemKey
// }
// //Glue the parts together
// var modelString = match[1] + '_' + itemCounter
//
// //Set to the global modelString
// $scope.modelString = modelString;
// $scope.itemCounter = itemCounter;
//
// //Return the string
// return modelString
// }
/**
* Wrapper for Json.parse()
* So i can parse Json in blade
* @param value
*/
$scope.parse = function (value) {
//If there is no value return;
if (!value) {
console.log("Parse without a value");
return;
}
//If it is already an object, return the value
if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) == 'object') {
console.log("Parse value: " + value);
return value;
}
//Parse the string to a Json object
console.log("Parse string to Json: " + JSON.parse(value));
return JSON.parse(value);
};
$scope.convertToSlug = function (str) {
str = str.replace(/^\s+|\s+$/g, ''); // trim
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;";
var to = "aaaaaeeeeeiiiiooooouuuunc------";
for (var i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
return str;
};
}]);
app.controller('KmsAttributeTextFieldController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
}]);
app.controller('KmsAttributePasswordController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
//Set enabler true (show enable bottom)
$scope.enabler = true;
//Change the password field to a hidden field
$('.passwordField', $element).attr('type', 'hidden');
//Method called when clikced on the enable button
$scope.enablePasswordField = function () {
//Change the type of the password field to password
$('.passwordField', $element).attr('type', 'password');
//Disable the enable buttom
$scope.enabler = false;
};
}]);
app.controller('KmsAttributeDateController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
$('input[ui-date]', $element).datepicker({
changeYear: true,
changeMonth: true,
firstDay: 1,
dateFormat: 'dd-mm-yy'
});
}]);
app.controller('KmsAttributeCurrencyFieldController', ['$scope', '$element', '$locale', function ($scope, $element, $locale) {
$scope.attributes = attributes;
$scope.initCurrencyField = function (dec_value, currency) {
if (typeof currency !== 'undefined') {
//Set currencySymbol
$locale.NUMBER_FORMATS.CURRENCY_SYM = currency;
}
//Set the value an de dec_value
attributes[$scope.modelString] = { "value": dec_value / 100, "dec_value": dec_value };
$scope.$watch('attributes.' + $scope.modelString + '.value', function (newValue, oldValue) {
if (newValue === oldValue) return;
attributes[$scope.modelString].dec_value = newValue * 100;
});
};
}]);
app.controller('KmsAttributePercentageFieldController', ['$scope', '$element', '$timeout', function ($scope, $element, $timeout) {
$scope.attributes = attributes;
}]);
app.controller('KmsAttributeTextFieldCurrencyController', ['$scope', '$element', '$timeout', function ($scope, $element, $timeout) {
$scope.attributes = attributes;
var id = $('input', $element).attr('id'); // get the id of the hidden field
var taxSelectFieldId = $('[data-kms-tax-field]', $element).attr('data-kms-tax-field');
var taxFieldId = id + '_tax';
var noTaxFieldId = id + '_no_tax';
var parseCurrencyStringToCents = function parseCurrencyStringToCents(currencyString) {
var val = currencyString.toString();
val = val.replace(/[.]/g, '');
val = val.replace(/[,]/g, '.');
val = val.replace(/[^0-9\.]+/g, '');
val = val * 100;
return val;
};
var addTax = function addTax(value) {
if (attributes[taxSelectFieldId].selected) {
var factor = 1 + attributes[taxSelectFieldId].selected.fullValue.rate / 100;
return value * factor;
}
};
var subtractTax = function subtractTax(value) {
if (attributes[taxSelectFieldId].selected) {
var factor = 1 + attributes[taxSelectFieldId].selected.fullValue.rate / 100;
return value / factor;
}
};
$scope.$watch('attributes.' + taxFieldId, function (newValue, oldValue) {
if (newValue !== oldValue) {
$scope.attributes[id] = parseCurrencyStringToCents(newValue);
}
});
$scope.$watch('attributes.' + noTaxFieldId, function (newValue, oldValue) {
if (newValue !== oldValue) {
$scope.attributes[id] = Math.round(addTax(parseCurrencyStringToCents(newValue)));
}
});
var watcherMain = function watcherMain(newValue, oldVal) {
if ($.isNumeric($scope.attributes[id])) {
var $taxField = $('#' + taxFieldId);
var $noTaxField = $('#' + noTaxFieldId);
if (!$taxField.is(':focus')) {
$taxField.val($scope.attributes[id] / 100);
}
if (!$noTaxField.is(':focus')) {
$noTaxField.val(Math.round(subtractTax($scope.attributes[id])) / 100);
}
}
};
// Clear fields on blur if no value
$('#' + taxFieldId + ', #' + noTaxFieldId).blur(function (e) {
if ($scope.attributes[id] == 0) {
$('#' + taxFieldId + ', #' + noTaxFieldId).val(0);
}
});
$scope.$watch('attributes.' + id, watcherMain);
$scope.$watch('attributes.' + taxSelectFieldId + '.selected', watcherMain);
$scope.attributes[id] = $('input', $element).attr('value'); // get the value of the hidden field
$timeout(watcherMain, 500);
}]);
app.controller('KmsAttributeMultiSelectController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
$scope.selectData = [];
/**
* Initialize the choices for ui-select
*
* @param choices | string
* @returns {*}
*/
$scope.initChoices = function (choices) {
//If there are no choices;
if (!choices) return;
//If it is not already an object, make one from json
if ((typeof choices === 'undefined' ? 'undefined' : _typeof(choices)) != 'object') choices = JSON.parse(choices);
//Set the choices to the selectData
$scope.selectData = choices;
return choices;
};
$scope.setValue = function (values) {
if (!values) return;
// compare "values" array and "$scope.selectData" array
var result = [];
for (var i = 0; i < $scope.selectData.length; i++) {
var valueInElement = false;
for (var j = 0; j < values.length; j++) {
if ($scope.selectData[i].value == values[j]) {
valueInElement = true;
break;
}
}
if (valueInElement) result.push($scope.selectData[i]);
}
// $scope.attributes[id] = angular.toJson(values);
// $scope.attributes[id + '_select'] = result;
return result;
};
}]);
app.controller('KmsAttributeSlugController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
//Get the slugField key
var slugField = $('[data-kms-slug-field]', $element).attr('data-kms-slug-field');
//Change [[itemCounter]] with the $scope.itemCounter (fieldGroup)
slugField = slugField.replace('[[itemCounter]]', $scope.itemCounter);
//Watch the slugField
$scope.$watch('attributes.' + slugField, function (newValue, oldValue) {
//When nothing changes, do nothing
if (newValue === oldValue) return;
//Set the string converted to Slug to the field
attributes[$scope.modelString] = $scope.convertToSlug(attributes[slugField]);
});
}]);
app.controller('KmsAttributeFieldGroupController', ['$scope', '$element', function ($scope, $element) {
$scope.number = 0;
$scope.itemKey = 1;
$scope.maxFieldGroups = null;
$scope.getNumber = function () {
return new Array($scope.number);
};
$scope.addRow = function () {
if ($scope.itemKey >= $scope.maxFieldGroups) return;
//Add one to the itemKey
$scope.itemKey++;
//Addd one to the numbers
$scope.number++;
};
/**
* Initialize the given values
* @param itemKey | Amount (-1) of items fieldGroups
* @param maxFieldGroups | max fieldgroups
*/
$scope.init = function (itemKey, maxFieldGroups) {
//Items in the fieldGroup
$scope.itemKey = itemKey;
//Max items in fieldGroup
$scope.maxFieldGroups = maxFieldGroups;
//If it is a new, add a row
if (itemKey == 0) $scope.addRow();
};
}]);
app.controller('KmsAttributeRouteController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
var id = $('input', $element).attr('id');
attributes[id] = $('input', $element).attr('value');
//Get the name of the slugField
var slugField = $('[data-kms-slug-field]', $element).attr('data-kms-slug-field');
//Change [[itemCounter]] with the $scope.itemCounter (fieldGroup)
slugField = slugField.replace('[[itemCounter]]', $scope.itemCounter);
//Get the name of the parentField
var parentField = $('[data-kms-parent-field]', $element).attr('data-kms-parent-field');
//Set the languageId
var languageId = $('[data-kms-language-id]', $element).attr('data-kms-language-id');
//Set the structure
var structure = $('[data-kms-structure]', $element).attr('data-kms-structure');
/**
* This function generates the correct Route
* when a watched field is changed
*
* @param newValue
* @param oldValue
*/
var parseStructure = function parseStructure(newValue, oldValue) {
//If the value is the same, stop and return
if (newValue === oldValue) return;
//Create an empty parentSlug string
var parentSlug = '';
// todo: make this work
//Check if the parentField exist in then attributes
if (attributes[parentField]) {
//Check if the parentField has an selected.routes object
if (!attributes[parentField].selected.routes) {
//If not trow an error
console.error('Routes are not set in the ' + parentField + 'field');
}
//Set the routes for the current language to parentSlug
parentSlug = attributes[parentField].selected.routes[languageId];
}
//Create newRoute
var newRoute = '';
//Replace {{parentSlugs}} with the parentSlug
newRoute = structure.replace('{{parentSlugs}}', parentSlug);
//Replace {{slug}} with the Slug
newRoute = newRoute.replace('{{slug}}', $scope.convertToSlug(newValue));
//Set the new route to the attribute of the current $scope.modelString
attributes[$scope.modelString] = newRoute;
};
//Set a watch on the slugField, and execute the parseStructure method on a change
$scope.$watch('attributes.' + slugField, parseStructure);
//If there is an parentField
if (attributes[parentField]) {
//Set a watch on the parentField, and execute the parseStructure method on a change
$scope.$watch('attributes.' + parentField + '.selected', parseStructure);
}
}]);
app.controller('KmsAttributeSorterController', ['$scope', '$element', function ($scope, $element) {
$scope.attributes = attributes;
}]);
app.filter("multiWordFilter", ['$filter', function ($filter) {
console.log('hoi');
return function (inputArray, searchText) {
var wordArray = searchText ? searchText.toLowerCase().split(/\s+/) : [];
var wordCount = wordArray.length;
for (var i = 0; i < wordCount; i++) {
// Hack for filtering on text parameter: {text:wordArray[i]}
inputArray = $filter('filter')(inputArray, { text: wordArray[i] });
}
return inputArray;
};
}]);
app.filter('valuesToArrayFilter', function () {
return function (input) {
if (!input) return;
var output = input.map(function (a) {
return a.value;
});
return output;
};
});
/**
* AngularJS default filter with the following expression:
* "person in people | filter: {name: $select.search, age: $select.search}"
* performs a AND between 'name: $select.search' and 'age: $select.search'.
* We want to perform a OR.
*/
app.filter('propsFilter', function () {
return function (items, props) {
var out = [];
if (angular.isArray(items)) {
items.forEach(function (item) {
var itemMatches = false;
var keys = Object.keys(props);
for (var i = 0; i < keys.length; i++) {
var prop = keys[i];
var text = props[prop].toLowerCase();
if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
itemMatches = true;
break;
}
}
if (itemMatches) {
out.push(item);
}
});
} else {
// Let the output be the input untouched
out = items;
}
return out;
};
});
var IsJsonString = function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
};
$(function () {
var activeListItem = $('#sidebar .navigation li.active');
var activeListItemParents = activeListItem.parents();
var activeListItemParentsLength = activeListItemParents.length;
for (var i = 0; i <= activeListItemParentsLength; i++) {
var node = activeListItemParents[i];
if (node && node.tagName == 'LI' && node.classList.contains('has-sub-items')) {
node.classList.add('active');
}
}
var siteListItems = document.querySelectorAll('#sidebar .navigation .has-sub-items');
var siteListItemsLength = siteListItems.length;
for (var i = 0; i < siteListItemsLength; i++) {
var siteListItem = siteListItems[i].querySelector('span');
siteListItem.addEventListener('click', function () {
this.parentNode.classList.toggle('active');
});
}
});
(function ($) {
// TinyMCE
tinymce.init({
selector: 'textarea.tiny-mce',
skin: 'kms',
menubar: false,
statusbar: false,
plugins: ['code', 'paste', 'link'],
toolbar: 'styleselect | bold italic underline | bullist numlist | indent | link image | code',
height: '200',
paste_as_text: true,
style_formats: [{ title: 'Titel 1', block: 'h1' }, { title: 'Titel 2', block: 'h2' }, { title: 'Titel 3', block: 'h3' }, { title: 'Titel 4', block: 'h4' }],
convert_urls: false
// link_list: "/kms/file-list?key=komma_kms",
});
// Hierarchical list
$('.entities-list-item .dropdown-icon').click(function (e) {
e.preventDefault();
if ($(this).parent().parent().hasClass('open')) {
//$('.animate-to-triangle', this)[0].beginElement();
$(this).parent().parent().removeClass('open');
} else {
//$('.animate-to-minus', this)[0].beginElement();
$(this).parent().parent().addClass('open');
}
});
var toggled = true;
// Scroll to active item in list
$(window).load(function () {
if ($('#entity-form .lock').hasClass('open')) {
toggled = false;
$('#entity-form').find('input, textarea').attr('disabled', toggled);
}
var $container = $('#entities .entities-list');
var $activeListItem = $('.entities-list-item.active', $container).first();
if ($activeListItem.length == 0) return;
var top = $activeListItem.position().top;
$container.scrollTop(top);
$('.site-brand-name input').attr('placeholder', $('#global_name').val());
});
$('#global_name').change(function () {
$('.site-brand-name input').attr('placeholder', $(this).val());
});
//error accordian
$('.error-accordion .collapsible-ul').hide();
$('.error-accordion h3').click(function () {
$(this).parent().find('.collapsible-ul').toggle();
});
//$('.order-status.selectize').selectize();
// Product category selector
//$('#productCategorySelector').selectize();
//$('#selectYearAndMonthForm select').selectize();
$('#selectYearAndMonthForm select').change(function () {
var location = '/kms/orders/voltooid?month=' + $('#selectYearAndMonthForm select#orderMonthSelector').val() + '&year=' + $('#selectYearAndMonthForm select#orderYearSelector').val();
window.location = location;
});
$('#productCategorySelector').change(function () {
window.location = '/kms/products?category=' + encodeURIComponent(this.value);
});
// Flash messages
var hideFlashMessage = function hideFlashMessage() {
$('#flash-message').fadeOut();
};
$('#flash-message').click(function () {
hideFlashMessage();
});
setTimeout(function () {
hideFlashMessage();
}, 5000);
//var toggled = true;
$('#entity-form .lock').click(function () {
$(this).toggleClass('open');
toggled = !toggled;
$(this).parents('#entity-form').find('input, textarea').attr('disabled', toggled);
});
/* grab important elements */
var sortInput = jQuery('#sort_order');
var submit = jQuery('#autoSubmit');
var messageBox = jQuery('#message-box');
var list = jQuery('.fieldGroupItems');
/* create requesting function to avoid duplicate code */
/* worker function */
var fnSubmit = function fnSubmit(save) {
var sortOrder = [];
list.children('li').each(function () {
sortOrder.push(jQuery(this).data('id'));
});
sortInput.val(sortOrder.join(','));
console.log(sortInput.val());
if (save) {
request();
}
};
/* store values */
list.children('li').each(function () {
var li = jQuery(this);
li.data('id', li.attr('title')).attr('title', '');
});
/* sortables */
list.sortable({
opacity: 0.7,
update: function update() {}
});
/* ajax form submission */
jQuery('#dd-form').bind('submit', function (e) {
if (e) e.preventDefault();
fnSubmit(true);
});
})(jQuery);
/**
* Fills an ul element with data retrieved from an api and makes the items searchable.
/* The data to and from the api has this structure for example.
*
* [
* {
* id:1
* title:false
* thumbnail:false
* status: "active"
* routes: []
* children: [
* {
* id: 12
* title: "Thuis"
* thumbnail: false
* routes: [{
* 40: "en/Homenew",
* 104: "nl/Thuisnew"
* }]
* }
* ]
* }
* ]
*/
var SearchController = function () {
function SearchController(sectionId, selector, inputSelector, mainUlId, resultCounterId) {
_classCallCheck(this, SearchController);
this.apiUrl = '';
this.data = '';
this.dataToLoad = '';
this.editEntitiesUrl = '';
this.initialized = false;
this.sectionId = sectionId;
this.selector = selector;
this.mainUlId = mainUlId;
this.resultCounterId = resultCounterId;
this.disabled = true;
this.inputSelector = inputSelector;
this.listItemClass = 'entities-list-item';
//The class that is added to li items that must be visible because they match (a part) of the search value).
//This is also the class applied to the rootUl if any results are found.
this.visibleClass = 'active';
this.invisibleClass = 'hide';
this.section = document.getElementById(this.sectionId);
var rootUl = document.querySelector(this.selector);
this.siteSlug = rootUl.dataset.siteSlug;
this.slug = rootUl.dataset.slug;
this.activeId = rootUl.dataset.activeId;
}
/**
* Initializes the controller so that it knows where it can get its data from,
* where it needs to direct users when they click on an item and from which ul it
* should create a sortable ul
*
* @param dataSource A string|Object
* @param editEntitiesUrl A string
*
* In case of the data source being an object it must look like this:
* {
* data: [{
* id: null,
* routes: []
* status: "",
* title: "",
* children: [
* {
* id: "2",
* routes: []
* status: "",
* title: "My username"
* children: []
* }
* ]
* }]
* }
*/
_createClass(SearchController, [{
key: 'init',
value: function init(dataSource, editEntitiesUrl) {
if (typeof dataSource === "string") {
this.apiUrl = dataSource;
} else {
this.dataToLoad = dataSource;
}
this.editEntitiesUrl = editEntitiesUrl;
this.initialized = true;
}
/**
* Returns a promise that resolves with the root ul that then will contain the items retrieved from the api
*/
}, {
key: 'load',
value: function load() {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
var self = this;
return new Promise(function (resolve, reject) {
if (self.initialized === false) {
reject('Please initialize the controller with the init method first.');
}
if (self.apiUrl !== '' && self.dataToLoad === '') {
axios.get(self.apiUrl).then(function (response) {
if (!response.data) {
reject('The sortable did not get any data from the api');
return;
}
// console.log(response);
/** @var Array[] menuItemArrays*/
response.data[0].children.forEach(function (itemObject) {
/** @var array htmlElements **/
var htmlElements = self.createHtmlElement(itemObject);
htmlElements.forEach(function (element) {
document.querySelector(self.selector).append(element);
});
});
// console.log(document.querySelector(self.selector));
self.initializeSearch();
resolve(document.querySelector(self.selector));
}).catch(function (error) {
reject(error);
});
} else if (self.apiUrl === '' && self.dataToLoad !== '') {
// console.log('data children');
// console.log(self.dataToLoad.data[0].children);
self.dataToLoad.data[0].children.forEach(function (itemObject) {
var htmlElements = self.createHtmlElement(itemObject);
htmlElements.forEach(function (element) {
document.querySelector(self.selector).append(element);
});
});
self.initializeSearch();
resolve(document.querySelector(self.selector));
}
});
}
/**
* Initialize search functionality on the ul this searchable does its job for
*/
}, {
key: 'initializeSearch',
value: function initializeSearch() {
var _this = this;
var section = this.section;
var input = document.querySelector(this.inputSelector);
var searchUl = document.querySelector(this.selector);
var resultCounter = document.getElementById(this.resultCounterId);
//handles searching
input.addEventListener('keyup', function (event) {
var mainUl = document.getElementById(_this.mainUlId);
var resultsCount = 0;
var filterValue = input.value.toLowerCase();
var noSearchValue = filterValue == '' ? true : false;
var listItems = searchUl.querySelectorAll('li');
var listItemsCount = listItems.length;
// console.log(listItemsCount);
for (var i = 0; i < listItemsCount; i++) {
var itemValue = listItems[i].dataset.title.toLowerCase();
if (itemValue.indexOf(filterValue) > -1 && noSearchValue === false) {
//item found
resultsCount++;
listItems[i].classList.add(_this.visibleClass);
} else {
//item not found
listItems[i].classList.remove(_this.visibleClass);
}
}
if (resultsCount > 0) {
// searchUl.parentNode.classList.add(this.visibleClass);
// mainUl.classList.add(this.invisibleClass);
} else {
// searchUl.parentNode.classList.remove(this.visibleClass);
// mainUl.classList.remove(this.invisibleClass);
}
resultCounter.innerHTML = resultsCount + "";
if (!noSearchValue) {
section.classList.add(_this.visibleClass);
mainUl.classList.add(_this.invisibleClass);
} else {
section.classList.remove(_this.visibleClass);
mainUl.classList.remove(_this.invisibleClass);
}
});
searchUl.classList.remove(this.visibleClass);
}
/**
* Creates a menu item (HTMLElement) and sub menu items if necessary
*
* @param data
* @param items array Used internally. Humans must not touch this
* @param currentTreeLevel string Used internally. Humans must not touch this
* @returns {Array}
*/
}, {
key: 'createHtmlElement',
value: function createHtmlElement(data) {
var items = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var currentTreeLevel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
var self = this;
var activeId = self.activeId;
var id = data.id;
var title = data.title;
var children = data.children;
var status = data.status;
var thumbnail = data.thumbnail;
var breadcrumb = currentTreeLevel;
var treeBreadcrumb = currentTreeLevel !== "" ? currentTreeLevel + " | " + title : title;
// console.log(breadcrumb);
// console.log(data);
//Render all child html items first
var childItems = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var object = _step.value;
childItems.push(this.createHtmlElement(object, items, treeBreadcrumb));
}
//Displays a red or green line in front of the item depending on if the status (class) is active or not
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var colorStatusHtml = '\n <span class="color-status" data-status-type="' + status + '">\n \n </span>\n ';
//Displays the items icon thumbnail OR the first character of its title
var iconHtml = '\n <div class="icon" ' + (thumbnail ? 'style="background-image: url(\'' + thumbnail + '\');"' : '') + ' >\n ' + (thumbnail ? '' : '<span>' + (title ? title.substring(0, 1) : '') + '</span>') + '\n </div>\n ';
//The main item html that has all other items
var listIem = '\n <li data-title="' + title + '" class="' + this.listItemClass + ' ' + (id == activeId ? 'active' : '') + '"> \n <a href="' + this.editEntitiesUrl + '/' + id + '">\n ' + colorStatusHtml + '\n ' + iconHtml + '\n <p data-breadcrumb="' + breadcrumb + '">' + title + '</p>\n </a>\n </li> \n ';
//Render it to a real html element
var domParser = new DOMParser();
var document = domParser.parseFromString(listIem, "text/html");
items.push(document.body.firstChild);
// console.log('rendered item: ');
// console.log(items);
//And then add the children inside
if (childItems.length > 0) {
// console.log('adding rendered childitems');
childItems.forEach(function (element) {
items.push(element[0]);
});
}
// console.log('items result:');
// console.log(items);
//and return it
return items;
}
}]);
return SearchController;
}();
/**
* Fills an ul element with data retrieved from an api and makes the items draggable so that you can sort them.
* Also updates the api with the new positions of the items. The data to and from the api has this structure for example.
*
* [
* {
* id:1
* title:false
* thumbnail:false
* status: "active"
* routes: []
* children: [
* {
* id: 12
* title: "Thuis"
* thumbnail: false
* routes: [{
* 40: "en/Homenew",
* 104: "nl/Thuisnew"
* }]
* }
* ]
* }
* ]
*/
var SortableController = function () {
function SortableController(selector) {
_classCallCheck(this, SortableController);
this.apiUrl = '';
this.editEntitiesUrl = '';
this.initialized = false;
this.selector = selector;
this.disabled = true;
this.listItemClass = 'entities-list-item';
var rootUl = document.querySelector(this.selector);
this.siteSlug = rootUl.dataset.siteSlug;
this.slug = rootUl.dataset.slug;
this.activeId = rootUl.dataset.activeId;
}
/**
* Initializes the controller so that it knows where it can get its data from,
* where it needs to direct users when they click on an item and from which ul it
* should create a sortable ul
*
* @param apiUrl A string
* @param editEntitiesUrl A string
*/
_createClass(SortableController, [{
key: 'init',
value: function init(apiUrl, editEntitiesUrl) {
this.apiUrl = apiUrl;
this.editEntitiesUrl = editEntitiesUrl;
var itemsThatHaveSubUl = document.querySelectorAll(this.selector + " li ul");
itemsThatHaveSubUl.forEach(function (node, index) {
// console.log('clicked ul');
node.style.display = node.style.display !== 'none' ? 'none' : '';
});
this.initialized = true;
}
}, {
key: 'updateSortableJavascript',
value: function updateSortableJavascript() {
// console.log("Updating all sortable elements with these selectors: '" + this.selector+" .sortable' AND '"+this.selector+"'");
$('.sortable').sortable({
connectWith: ".sortable",
placeholder: "sortable-placeholder",
disabled: this.disabled
});
var itemsThatHaveSubUl = document.querySelectorAll(this.selector + " li ul");
itemsThatHaveSubUl.forEach(function (node, index) {
// console.log('clicked ul');
// node.style.display = node.style.display !== 'none' ? 'none' : '';
});
}
/**
* Makes the rootUl sortable
*/
}, {
key: 'enableSortable',
value: function enableSortable() {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
this.disabled = false;
$(this.selector).sortable({
disabled: this.disabled
}).addClass('sorting');
this.updateSortableJavascript();
}
/**
* Diables the rootUl so that it cannot be sorted
*/
}, {
key: 'disableSortable',
value: function disableSortable() {
// if (this.initialized === false) { console.error('Please initialize the controller with the init method first.'); return; }
this.disabled = true;
$(this.selector).sortable({
disabled: this.disabled
}).removeClass('sorting');
this.save();
}
/**
* Saves the item data to the api
*/
}, {
key: 'save',
value: function save() {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
var itemsJson = this.itemsToJson(document.querySelector(this.selector));
itemsJson = JSON.stringify(itemsJson);
var apiJson = {
"tree": itemsJson
};
axios.post(this.apiUrl, apiJson).then(function (response) {
// console.log('Successfully stored the sort order to the api: ');
// console.log(response);
}).catch(function (error) {
// console.error('Could not save sortable sort order to api because an error occured: ');
console.error(error);
});
}
/**
* Converts the rootUl back to json for saving it
*
* @param htmlElement HTMLElement Root ul
* @return null|[] if something went wrong null, or an array containing json items if successfull.
*/
}, {
key: 'itemsToJson',
value: function itemsToJson(htmlElement) {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
var jsonArray = [];
var error = false;
//find all child li items
var listItems = htmlElement.querySelectorAll(':scope > li.' + this.listItemClass);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = listItems[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var listItem = _step2.value;
var elementJson = listItem.dataset.json;
if (!elementJson) {
console.error('One or more li HTMLElements with class "' + this.listItemClass + '" did not have data-json attribute set while it should.');
error = true;
}
var currentItemJson = JSON.parse(listItem.dataset.json);
var childUl = listItem.querySelector('ul');
if (childUl) {
currentItemJson.children = this.itemsToJson(childUl);
if (!currentItemJson.children) error = true;
} else {
currentItemJson.children = [];
}
jsonArray.push(currentItemJson);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
if (error) return null;
return jsonArray;
}
/**
* Returns a promise that resolves with the root ul that then will contain the items retrieved from the api
*/
}, {
key: 'load',
value: function load() {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
self = this;
return new Promise(function (resolve, reject) {
if (self.initialized === false) {
reject('Please initialize the controller with the init method first.');
}
axios.get(self.apiUrl).then(function (response) {
if (!response.data) {
reject('The sortable did not get any data from the api');
return;
}
/** @var HTMLElement[] menuItems*/
var menuItems = [];
response.data[0].children.forEach(function (itemObject) {
menuItems.push(self.createHtmlElement(itemObject));
});
menuItems.forEach(function (htmlElementItem) {
document.querySelector(self.selector).appendChild(htmlElementItem);
});
self.updateSortableJavascript();
resolve(document.querySelector(self.selector));
}).catch(function (error) {
reject(error);
});
});
}
/**
* Removes all children from the ul
*/
}, {
key: 'clearRootUl',
value: function clearRootUl() {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
var rootUl = document.querySelector(this.selector);
while (rootUl.firstChild) {
rootUl.removeChild(rootUl.firstChild);
}
}
/**
* Creates a menu item (HTMLElement) and sub menu items if necessary
*
* @param data
* @returns {HTMLElement}
*/
}, {
key: 'createHtmlElement',
value: function createHtmlElement(data) {
if (this.initialized === false) {
console.error('Please initialize the controller with the init method first.');return;
}
self = this;
var activeId = self.activeId;
var id = data.id;
var title = data.title;
var thumbnail = data.thumbnail;
var children = data.children;
var status = data.status;
var routes = data.routes;
//Generate json data representing that element
var routesForElement = {};
for (var routeProperty in routes) {
if (!routes.hasOwnProperty(routeProperty)) continue;
routesForElement[routeProperty] = routes[routeProperty];
}
if (routesForElement == {}) routesForElement = [];
var elementJson = {
id: data.id,
title: data.title,
thumbnail: data.thumbnail,
routes: routesForElement,
status: data.status
};
elementJson = JSON.stringify(elementJson);
//Render all child html items first
var childItems = [];
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = children[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var object = _step3.value;
childItems.push(this.createHtmlElement(object));
}
//Displays a red or green line in front of the item depending on if the status (class) is active or not
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
var colorStatusHtml = '\n <span class="color-status" data-status-type="' + status + '">\n \n </span>\n ';
//Displays the items icon thumbnail OR the first character of its title
var iconHtml = '\n <div class="icon" ' + (thumbnail ? 'style="background-image: url(\'' + thumbnail + '\');"' : '') + ' >\n ' + (thumbnail ? '' : '<span>' + (title ? title.substring(0, 1) : '') + '</span>') + '\n </div>\n ';
//The main item html that has all other items
var listIem = '\n <li data-json=\'' + elementJson + '\' class="' + this.listItemClass + ' ' + (id == activeId ? 'active' : '') + '"> \n <a href="' + this.editEntitiesUrl + '/' + id + '">\n ' + colorStatusHtml + '\n ' + iconHtml + '\n <p>' + title + '</p>\n </a>\n </li> \n ';
//Render it to a real html element
var domParser = new DOMParser();
var document = domParser.parseFromString(listIem, "text/html");
var node = document.body.firstChild;
//And add the children inside
if (childItems.length > 0) {
var subList = document.createElement('ul');
subList.className = 'sortable';
// console.log('rendered childItems');
// console.log(childItems);
childItems.forEach(function (element) {
subList.appendChild(element);
});
node.appendChild(subList);
}
//and return it
return node;
}
}]);
return SortableController;
}();
var ConfirmationController = function () {
/**
* ConfirmationController constructor
*
* @param selector
* @param headerText
* @param message
* @param confirmText
* @param cancelText
*/
function ConfirmationController(selector, headerText, message, confirmText, cancelText) {
_classCallCheck(this, ConfirmationController);
if (ConfirmationController.selectorValid(selector) === false) {
console.error('The selector "' + selector + '" isn\'t valid. Did not enable the confirmation functionality for that selector');
return;
}
ConfirmationController.headerText = headerText;
ConfirmationController.message = message;
ConfirmationController.confirmText = confirmText;
ConfirmationController.cancelText = cancelText;
ConfirmationController.button = document.querySelector(selector);
ConfirmationController.promptElement = this.createPrompt();
document.body.appendChild(ConfirmationController.promptElement);
this.addListenersToButton(ConfirmationController.button);
this.addListenersToModalButtons();
}
/**
* Adds listeners to the button that the selector from the constructor references to.
* So that the button works
*
* @param button
*/
_createClass(ConfirmationController, [{
key: 'addListenersToButton',
value: function addListenersToButton(button) {
button.addEventListener('click', function (controller) {
return function (clickEvent) {
clickEvent.preventDefault();
controller.showConfirmationPrompt(true);
};
}(this));
}
/**
* Add listeners to the modals buttons.
* Usually the yes no buttons.
*/
}, {
key: 'addListenersToModalButtons',
value: function addListenersToModalButtons() {
if (!ConfirmationController.promptElement) console.error('First create the modal with the createPrompt method');
var confirmButton = ConfirmationController.promptElement.querySelector('button.confirm');
var cancelButton = ConfirmationController.promptElement.querySelector('button.cancel');
var shader = ConfirmationController.promptElement.querySelector('div.shader');
// console.log(confirmButton);
// console.log(cancelButton);
confirmButton.addEventListener('click', this.confirmClicked.bind(this));
cancelButton.addEventListener('click', this.cancelClicked.bind(this));
shader.addEventListener('click', this.cancelClicked.bind(this));
}
}, {
key: 'confirmClicked',
value: function confirmClicked(mouseEvent) {
mouseEvent.preventDefault();
console.log(ConfirmationController.button);
var form = this.findForm(ConfirmationController.button);
console.log(form);
if (form) form.submit();
this.showConfirmationPrompt(false);
}
}, {
key: 'cancelClicked',
value: function cancelClicked(mouseEvent) {
mouseEvent.preventDefault();
this.showConfirmationPrompt(false);
}
/**
* Retrieves an HTML element and starts traversing up into the dom to find the first form the element is in.
* Returns the form or false if it cannot be found
* @param element
*/
}, {
key: 'findForm',
value: function findForm(element) {
if (!element.parentNode) return false;
if (element.parentNode.tagName === 'FORM') return element.parentNode;
return this.findForm(element.parentNode);
}
/**
* Create a div that represents a prompt
*
* @returns {HTMLDivElement}
*/
}, {
key: 'createPrompt',
value: function createPrompt() {
var html = '<div class="modal">' + '<div class="header"><h4>' + ConfirmationController.headerText + '</h4></div>' + '<div class="body">' + '<p class="message">' + ConfirmationController.message + '</p>' + '<div class="buttons">' + '<button class="confirm">' + ConfirmationController.confirmText + '</button>' + '<button class="cancel">' + ConfirmationController.cancelText + '</button>' + '</div>' + '</div>' + '</div>' + '</div>' + '<div class="shader"></div>';
var promptElement = document.createElement("div");
promptElement.setAttribute('id', 'confirmBox');
promptElement.innerHTML = html;
return promptElement;
}
/**
* Show or hides the confirmation prompt by adding a hidden class to it.
*/
}, {
key: 'showConfirmationPrompt',
value: function showConfirmationPrompt(show) {
ConfirmationController.promptElement.classList.add('show');
if (!show) ConfirmationController.promptElement.classList.remove('show');
}
/**
* Returns true when a selector references a button tag or an input tag with type button.
* false if not
*
* @param selector
* @returns {boolean}
*/
}], [{
key: 'selectorValid',
value: function selectorValid(selector) {
var button = document.querySelector(selector);
if (!button) return false;
if (button.tagName !== 'BUTTON' && button.tagName !== 'INPUT') return false;
if (button.tagName === "INPUT") if (button.getAttribute('type').toLowerCase() !== 'button' && button.getAttribute('type').toLowerCase() !== 'submit') return false;
return true;
}
}]);
return ConfirmationController;
}();
var TabsController = function () {
/**
* The tab controller can obviously control tabs.
* You just have to have a couple of divs that hold the content. These divs must all have a class name that
* corresponds to the value of constructor parameter tabContentIdAndClassAndPrefix. And they all must have an id
* that also starts with the value of tabContentIdAndClassAndPrefix followed by the tab slug.
*
* You can specify if you have an hidden input field that needs to be updated with the curent tab slug. You do that
* with the tabSlugInputSelector.
*
* Content tab divs and buttons will also receive an active state class to make them visible / stand out when present
* or hidden / to background. You can specify this class name with the activeClass parameter.
*
* The tabButtonGroupSelector selects an element that holds the tab buttons to switch tabs. This element must have an
* ul element that holds li elements containing a elements.
*
* The reactToUrlHashChange parameter controls if the controller should react if the hash part of the url did change.
*
* @param tabContentIdAndClassAndPrefix stringseelc
* @param tabButtonGroupSelector string
* @param activeClass string
* @param reactToUrlHashChange
* @param tabSlugInputSelector string
*/
function TabsController() {
var tabContentIdAndClassAndPrefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'tab';
var tabButtonGroupSelector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '.tab-buttons';
var activeClass = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'active';
var reactToUrlHashChange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var tabSlugInputSelector = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
_classCallCheck(this, TabsController);
this.tabContentDivsClassAndIdPrefix = tabContentIdAndClassAndPrefix;
this.tabSlugInputId = tabSlugInputSelector;
this.activeClass = activeClass;
this.reactToUrlHashChange = reactToUrlHashChange;
if (reactToUrlHashChange) this.addListenerForHashChange(reactToUrlHashChange);
}
/**
* Opens the tab by using the tab slug
*
* @param tabSlug
*/
_createClass(TabsController, [{
key: 'openTab',
value: function openTab(tabSlug) {
//Remove trailing / on the left hand side
tabSlug = this.removeLeftHandSlashInSlug(tabSlug);
if (!tabSlug) {
console.error("TabsController: Could not open tab with an empty slug");return;
}
this.updateTabSlugInput(tabSlug);
this.showTabContentForTabWithSlug(tabSlug);
this.makeTabButtonActiveForSlug(tabSlug);
}
/**
* Removes a / at the beginning of a tab slug
*
* @param tabSlug
*/
}, {
key: 'removeLeftHandSlashInSlug',
value: function removeLeftHandSlashInSlug(tabSlug) {
return tabSlug.replace(/^\/(.*)/, '$1');
}
/**
* Updates a usually hidden input field holding the tab slug with a new slug
*
* @param newSlug string
*/
}, {
key: 'updateTabSlugInput',
value: function updateTabSlugInput(newSlug) {
if (this.tabSlugInputId === undefined) return;
var element = document.querySelector(this.tabSlugInputId);
if (element) element.value = newSlug;
}
}, {
key: 'makeTabButtonActiveForSlug',
value: function makeTabButtonActiveForSlug(slug) {
$('.entity-tabs >ul >li').removeClass('active');
$('.entity-tabs >ul >li a[href="#' + slug + '"]').parent().addClass('active');
}
/**
* Shows the tab content div with the specified slug and hides the other content div tabs.
* It does this by adding and removing classes (the active class you specified in the constructor)
*
* @param slug string
*/
}, {
key: 'showTabContentForTabWithSlug',
value: function showTabContentForTabWithSlug(slug) {
var _this2 = this;
//Remove the active class from all tab content classes
document.querySelectorAll('.' + this.tabContentDivsClassAndIdPrefix).forEach(function (element) {
element.classList.remove(_this2.activeClass);
});
//Add the active class to the tab that has the correct slug appended to the IdPrefix
var activeTab = document.querySelector("#" + this.tabContentDivsClassAndIdPrefix + "-" + slug);
if (!activeTab) {
console.error("TabsController: Could not make content tab active. It should have an ID with: #" + this.tabContentDivsClassAndIdPrefix + "-" + slug);return;
}
activeTab.classList.add(this.activeClass);
}
/**
* Adds or disables listening for hashchange events to update tabs
*
* @param boolean
*/
}, {
key: 'addListenerForHashChange',
value: function addListenerForHashChange(boolean) {
if (boolean) {
window.addEventListener('hashchange', this.hashChanged.bind(this));
window.addEventListener('load', this.hashChanged.bind(this));
} else {
window.removeEventListener('hashchange', this.hashChanged);
window.removeEventListener('load', this.hashChanged);
}
}
/**
* Called automatically by an internal listener (controlled by the addListenerForHashChange method)
*/
}, {
key: 'hashChanged',
value: function hashChanged(event) {
var tabSlug = window.location.hash.substring(1);
if (tabSlug) {
this.openTab(tabSlug);
return;
}
var tabSlugElement = document.querySelector(this.tabSlugInputId);
if (!tabSlugElement) return;
this.openTab(tabSlugElement.value);
}
}]);
return TabsController;
}();