Files
eapim-admin/WebContent/js/jsuites.layout.js
T
Rinjae c54ef1903f init
2025-09-05 17:16:26 +09:00

2562 lines
81 KiB
JavaScript

/**
* (c) jSuites Javascript Web Components (v3.9.3)
*
* Website: https://jsuites.net
* Description: Create amazing web based applications.
*
* MIT License
*
*/
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.jSuites = factory();
}(this, (function () {
'use strict';
jSuites.crop = (function(el, options) {
var obj = {};
obj.options = {};
// Default configuration
var defaults = {
area: [ 800, 600 ],
crop: [ 200, 150 ],
value: null,
onload: null,
onchange: null,
remoteParser: null,
allowResize: true,
text: {
extensionNotAllowed:'The extension is not allowed',
imageTooSmall:'The resolution is too low, try a image with a better resolution. width > 800px',
}
};
// Loop through our object
for (var property in defaults) {
if (options && options.hasOwnProperty(property)) {
obj.options[property] = options[property];
} else {
obj.options[property] = defaults[property];
}
}
// Default for mobile
if (jSuites.getWindowWidth() < 800) {
if (! obj.options.area[0]) {
obj.options.area[0] = window.clientWidth * 2;
}
if (! obj.options.area[1]) {
obj.options.area[1] = window.clientHeight * 2;
}
}
el.classList.add('jcrop');
// Upload icon
el.classList.add('jupload');
// Area
el.style.width = obj.options.area[0] + 'px';
el.style.height = obj.options.area[1] + 'px';
// Area do crop
var crop = document.createElement('div');
crop.classList.add('jcrop-area');
el.appendChild(crop);
// Canvas editor
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
el.appendChild(canvas);
// Image
var drawImage = function() {
if (el.clientHeight > image.height) {
var pointY = (el.clientHeight - image.height) / 2;
} else {
var pointY = 0;
}
if (el.clientWidth > image.width) {
var pointX = (el.clientWidth - image.width) / 2;
} else {
var pointX = 0;
}
image.left = pointX;
image.top = pointY;
context.translate(pointX, pointY);
context.drawImage(image, 0, 0, image.width, image.height);
}
var image = new Image();
image.onload = function onload() {
obj.resetCanvas();
var w = obj.options.area[0] / this.naturalWidth;
var h = obj.options.area[1] / this.naturalHeight;
// Proportion
var p = this.naturalHeight > this.naturalWidth ? h : w;
// Image size
this.width = this.naturalWidth * p;
this.height = this.naturalHeight * p;
// Do adjustment
canvas.width = obj.options.area[0];
canvas.height = obj.options.area[1];
if (this.width > canvas.width) {
canvas.width = this.width;
}
if (this.height > canvas.height) {
canvas.height = this.height;
}
drawImage();
// Edition model
el.classList.add('jcrop_edition');
// Reset selection on desktop only
if (jSuites.getWindowWidth() > 800) {
obj.resetCropSelection();
} else {
crop.classList.add('mobile');
}
// Onchange
if (typeof(obj.options.onchange) == 'function') {
obj.options.onchange(el, image);
}
};
// Properties
var properties = {
zoom: {
origin: { x: null, y: null, },
scale: 1,
},
contrast: 0,
brightness: 0,
rotate: 0,
saturation: 0,
};
var secondCanvas = document.createElement('canvas');
var secondContext = secondCanvas.getContext('2d');
var secondImage = document.createElement('img');
// Reload filters
var refreshFilters = function() {
secondCanvas.width = image.width;
secondCanvas.height = image.height;
secondContext.clearRect(0, 0, secondContext.width, secondContext.height);
secondImage.width = secondCanvas.width;
secondImage.height = secondCanvas.height;
if (image) {
//drawImage();
secondContext.drawImage(image, 0, 0, image.width, image.height);
}
// Performs the contrast, if its value is different from the initial
if (properties.contrast) {
runContrast();
}
// Performs the brightness, if its value is different from the initial
if (properties.brightness) {
runBrightness();
}
if (properties.greyScale) {
runGreyScale();
}
if (properties.saturation) {
runSaturation();
}
secondImage.src = secondCanvas.toDataURL(obj.getImageType);
secondImage.onload = function() {
context.drawImage(secondImage, 0, 0, secondImage.width, secondImage.height);
}
}
/**
* Reset crop to the initial conditions
*/
obj.resetCropSelection = function() {
crop.style.left = (obj.options.area[0]/2 - obj.options.crop[0]/2) + 'px';
crop.style.top = (obj.options.area[1]/2 - obj.options.crop[1]/2) + 'px';
crop.style.width = obj.options.crop[0] + 'px';
crop.style.height = obj.options.crop[1] + 'px';
crop.style.zIndex = 1;
}
obj.getCropSelection = function() {
obj.getSelectionCoordinates();
}
// Reset canvas
obj.resetCanvas = function() {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0,0,canvas.width,canvas.height);
}
// Reset all the properties
obj.reset = function() {
// Reset canvas
obj.resetCanvas();
// Reset state
properties = {
zoom: {
origin: { x: null, y: null },
scale: 1,
},
contrast: 0,
brightness: 0,
rotate: 0,
greyScale: 0,
saturation: 0,
}
// Stop edition
el.classList.remove('jcrop_edition')
}
// Apply the contrast on the image data
var runContrast = function() {
var contrast = properties.contrast;
var imageData = secondContext.getImageData(0, 0, secondCanvas.width, secondCanvas.height);
var data = imageData.data; // Note: original dataset modified directly!
contrast *= 255;
var factor = (contrast + 255) / (255.01 - contrast); //add .1 to avoid /0 error.
for (var i = 0; i < data.length; i+=4) {
data[i] = factor * (data[i] - 128) + 128;
data[i+1] = factor * (data[i+1] - 128) + 128;
data[i+2] = factor * (data[i+2] - 128) + 128;
}
secondContext.putImageData(imageData, 0, 0);
return imageData; //optional (e.g. for filter function chaining)
}
// Change the contrast and apply that to the image
obj.contrast = function(val) { // contrast input as percent; range [-1..1]
if (! Number.isNaN(parseFloat(val))) {
properties.contrast = val;
}
refreshFilters();
}
// Apply the brightness on the image data
var runBrightness = function () { // brightness input as percent; range [-1..1]
var brightness = properties.brightness;
var imageData = secondContext.getImageData(0, 0, secondCanvas.width, secondCanvas.height);
var data = imageData.data; // Note: original dataset modified directly!
brightness *= 255;
for (var i = 0; i < data.length; i+=4) {
data[i] += brightness;
data[i+1] += brightness;
data[i+2] += brightness;
}
secondContext.putImageData(imageData, 0, 0);
return imageData; //optional (e.g. for filter function chaining)
}
// Change the brightness and apply that to the image
obj.brightness = function(val) {
if (! Number.isNaN(parseFloat(val))) {
properties.brightness = val;
}
refreshFilters();
}
/**
* Returns the current image type
*/
obj.getImageType = function() {
var dataType = image.src.substr(0,20);
if(dataType.includes('data')){
return dataType.split('/')[1].split(';')[0];
}
return null;
}
/**
* Returns cropped area coordinates
*/
obj.getSelectionCoordinates = function() {
return {
left: crop.offsetLeft,
top: crop.offsetTop,
right: crop.offsetLeft + crop.clientWidth,
bottom: crop.offsetTop + crop.clientHeight
}
}
/**
* Returns cropped image on canvas
*/
obj.getCroppedImage = function() {
return jSuites.image.create({
extension: obj.getImageType(),
file: obj.getCroppedContent(),
name: '',
size: '',
});
}
/**
* Get cropped base64 content
*/
obj.getCroppedContent = function() {
var coordinates = obj.getSelectionCoordinates();
var canvasCropped = document.createElement('canvas');
var contextCropped = canvasCropped.getContext('2d');
canvasCropped.width = crop.clientWidth;
canvasCropped.height = crop.clientHeight;
// Get cropped selection
var imageData = context.getImageData(coordinates.left, coordinates.top, crop.clientWidth, crop.clientHeight);
contextCropped.putImageData(imageData,0,0);
return canvasCropped.toDataURL(obj.getImageType());
}
/**
* Get cropped as blob
*/
obj.getCroppedAsBlob = function(callback) {
if (! typeof(callback) == 'function') {
console.error('Callback not defined')
return false;
}
var coordinates = obj.getSelectionCoordinates();
var canvasCropped = document.createElement('canvas');
var contextCropped = canvasCropped.getContext('2d');
canvasCropped.width = crop.clientWidth;
canvasCropped.height = crop.clientHeight;
// Get cropped selection
var imageData = context.getImageData(coordinates.left, coordinates.top, crop.clientWidth, crop.clientHeight);
contextCropped.putImageData(imageData,0,0);
// Callback
canvasCropped.toBlob(callback);
}
/**
* Returns the current image on canvas
*/
obj.getImage = function() {
return image;
}
/**
* Returns the attachment input
*/
obj.getFileInput = function() {
return attachmentInput;
}
/**
* Returns the current canvas
*/
obj.getCanvas = function() {
return canvas;
}
/**
* Load a image from the computer
*/
obj.addFromFile = function(file) {
var type = file.type.split('/');
if (type[0] == 'image') {
var imageFile = new FileReader();
imageFile.addEventListener("load", function (v) {
image.src = v.srcElement.result;
});
imageFile.readAsDataURL(file);
} else {
alert(text.extentionNotAllowed);
}
}
/**
* Load a image from a remote URL
*/
obj.addFromUrl = function(src) {
if (src.substr(0,4) != 'data' && ! obj.options.remoteParser) {
console.error('remoteParser not defined in your initialization');
} else {
src = obj.options.remoteParser + src;
image.src = src;
}
}
// Runs image movements
var runMove = function() {
context.translate(image.left, image.top);
}
// Reload resizers and filters
var refreshResizers = function() {
// Clear canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
runMove();
// Performs the zoom, if its value is different from the initial
if (properties.zoom.scale !== 1) {
runZoom();
}
// Performs the rotation, if its value is different from the initial
if (properties.rotate) {
runRotate();
}
// Calls the filter reloader
if (properties.brightness || properties.contrast) {
context.drawImage(secondImage, 0, 0, secondImage.width, secondImage.height);
} else {
context.drawImage(image, 0, 0, image.width, image.height);
}
}
// Apply the zoom on the image
var runZoom = function() {
context.translate((properties.zoom.origin.x - image.left), (properties.zoom.origin.y - image.top));
context.scale(properties.zoom.scale, properties.zoom.scale);
context.translate(-(properties.zoom.origin.x - image.left), -(properties.zoom.origin.y - image.top));
}
/**
* Change the zoom and apply that to the image
* @param mixed value / null to refresh or int for a new percentage of zoom
*/
obj.zoom = function(value) {
if (value) {
properties.zoom.scale = value;
}
refreshResizers();
}
// Apply the rotations on the image
var runRotate = function() {
var value = properties.rotate;
value *= 180;
context.translate(image.width / 2, image.height / 2);
context.rotate(value * Math.PI / 180);
context.translate(- image.width / 2, - image.height / 2);
}
// Change the rotation and apply that to the image
obj.rotate = function(val) { // rotate input as percent; range [-1..1]
if (! Number.isNaN(parseFloat(val))) {
properties.rotate = val;
}
refreshResizers();
}
// HTML element to load a image from the computer
var attachmentInput = document.createElement('input');
attachmentInput.type = 'file';
attachmentInput.setAttribute('accept', 'image/*');
attachmentInput.onchange = function() {
for (var i = 0; i < this.files.length; i++) {
obj.addFromFile(this.files[i]);
}
}
/** Events start here **/
var editorAction = null;
var editorMouseUp = function(e) {
editorAction = false;
}
var editorMouseDown = function(e) {
if (e.target.classList.contains('jcrop-area')) {
var rect = e.target.getBoundingClientRect();
var offsetX = (e.target.style.left !== '') ? e.target.style.left : '0px';
var offsetY = (e.target.style.top !== '') ? e.target.style.top : '0px';
if (e.target.style.cursor) {
editorAction = {
e: e.target,
x: e.clientX,
y: e.clientY,
w: rect.width,
h: rect.height,
d: e.target.style.cursor,
xOffset: e.clientX - parseInt(offsetX.slice(0, offsetX.length - 2)),
yOffset: e.clientY - parseInt(offsetY.slice(0, offsetY.length - 2)),
}
if (! e.target.style.width) {
e.target.style.width = rect.width + 'px';
}
if (! e.target.style.height) {
e.target.style.height = rect.height + 'px';
}
var s = window.getSelection();
if (s.rangeCount) {
for (var i = 0; i < s.rangeCount; i++) {
s.removeRange(s.getRangeAt(i));
}
}
} else {
e.target.style.cursor = 'move';
// Tracking for moving
editorAction = {
e: e.target,
x: e.clientX,
y: e.clientY,
w: rect.width,
h: rect.height,
d: e.target.style.cursor,
xOffset: e.clientX - parseInt(offsetX.slice(0, offsetX.length - 2)),
yOffset: e.clientY - parseInt(offsetY.slice(0, offsetY.length - 2)),
}
}
} else {
editorAction = true;
}
}
var editorMouseMove = function(e) {
if (e.target.classList.contains('jcrop-area') && obj.options.allowResize == true) {
var rect = e.target.getBoundingClientRect();
if (e.clientY - rect.top < 5) {
if (rect.width - (e.clientX - rect.left) < 5) {
e.target.style.cursor = 'ne-resize';
} else if (e.clientX - rect.left < 5) {
e.target.style.cursor = 'nw-resize';
} else {
e.target.style.cursor = 'n-resize';
}
} else if (rect.height - (e.clientY - rect.top) < 5) {
if (rect.width - (e.clientX - rect.left) < 5) {
e.target.style.cursor = 'se-resize';
} else if (e.clientX - rect.left < 5) {
e.target.style.cursor = 'sw-resize';
} else {
e.target.style.cursor = 's-resize';
}
} else if (rect.width - (e.clientX - rect.left) < 5) {
e.target.style.cursor = 'e-resize';
} else if (e.clientX - rect.left < 5) {
e.target.style.cursor = 'w-resize';
} else {
if (! e.which) {
e.target.style.cursor = '';
}
}
}
// Change position or size
if (e.which == 1 && editorAction && editorAction.d) {
if (editorAction.d == 'move') {
// Change the position of the cropper
var cropOffsetX = e.clientX - editorAction.xOffset;
var cropOffsetY = e.clientY - editorAction.yOffset;
if (cropOffsetX < 0) {
editorAction.e.style.left = '0px';
} else if (cropOffsetX > el.offsetWidth - crop.offsetWidth - 2) {
editorAction.e.style.left = el.offsetWidth - crop.offsetWidth - 2 + 'px';
} else {
editorAction.e.style.left = cropOffsetX + 'px';
}
if (cropOffsetY < 0) {
editorAction.e.style.top = '0px';
} else if (cropOffsetY > el.offsetHeight - crop.offsetHeight - 2){
editorAction.e.style.top = el.offsetHeight - crop.offsetHeight - 2 + 'px';
} else {
editorAction.e.style.top = cropOffsetY + 'px';
}
} else {
// Change the size of the cropper
if (editorAction.d == 'e-resize' || editorAction.d == 'ne-resize' || editorAction.d == 'se-resize') {
// Handles size changes involving the right side of the cropper
var newWidth = editorAction.w + e.clientX - editorAction.x;
var offset = editorAction.e.style.left.slice(0, editorAction.e.style.left.length - 2);
if (newWidth < obj.options.crop[0]) {
editorAction.e.style.width = obj.options.crop[0] + 'px';
} else if (newWidth + parseInt(offset) > el.offsetWidth - 2) {
editorAction.e.style.width = el.offsetWidth - offset - 2 + 'px';
} else {
editorAction.e.style.width = editorAction.w + e.clientX - editorAction.x + 'px';
}
} else if (editorAction.d == 'w-resize' || editorAction.d == 'nw-resize' || editorAction.d == 'sw-resize') {
// Handles size changes involving the left side of the cropper
var newOffset = e.clientX - editorAction.xOffset;
var newWidth = editorAction.x + editorAction.w - e.clientX;
if (newWidth < obj.options.crop[0]) {
editorAction.e.style.left = editorAction.x + editorAction.w - obj.options.crop[0] - editorAction.xOffset + 'px';
editorAction.e.style.width = obj.options.crop[0] + 'px';
} else if (newOffset < 0) {
editorAction.e.style.left = '0px';
editorAction.e.style.width = editorAction.x + editorAction.w - editorAction.xOffset + 'px';
} else {
editorAction.e.style.left = newOffset + 'px';
editorAction.e.style.width = newWidth + 'px';
}
}
if (editorAction.d == 's-resize' || editorAction.d == 'se-resize' || editorAction.d == 'sw-resize') {
// Handles size changes involving the top side of the cropper
var newHeight = editorAction.h + e.clientY - editorAction.y;
var offset = editorAction.e.style.top.slice(0, editorAction.e.style.top.length - 2);
if (newHeight < obj.options.crop[1]) {
editorAction.e.style.height = obj.options.crop[1] + 'px';
} else if (newHeight + parseInt(offset) > el.offsetHeight - 2) {
editorAction.e.style.height = el.offsetHeight - parseInt(offset) - 2 + 'px';
} else {
editorAction.e.style.height = newHeight + 'px';
}
} else if (editorAction.d == 'n-resize' || editorAction.d == 'ne-resize' || editorAction.d == 'nw-resize') {
// Handles size changes involving the bottom side of the cropper
var newOffset = e.clientY - editorAction.yOffset;
var newHeight = editorAction.h + editorAction.y - e.clientY;
if (newHeight < obj.options.crop[1]) {
editorAction.e.style.top = editorAction.y + editorAction.h - obj.options.crop[1] - editorAction.yOffset + 'px';
editorAction.e.style.height = obj.options.crop[1] + 'px';
} else if (newOffset < 0) {
editorAction.e.style.top = '0px';
editorAction.e.style.height = editorAction.y + editorAction.h - editorAction.yOffset + 'px';
} else {
editorAction.e.style.top = newOffset + 'px';
editorAction.e.style.height = newHeight + 'px';
}
}
}
}
}
// image state to change its current position in el container (mobile only)
var imageState = {
mousedown: false,
mouseX: 0,
mouseY: 0
}
var touchstartListener = function(e) {
if (! e.target.classList.contains('jcrop-area')) {
imageState.mousedown = true;
}
if (e.changedTouches && e.changedTouches[0]) {
imageState.mouseX = e.changedTouches[0].clientX;
imageState.mouseY = e.changedTouches[0].clientY;
} else {
imageState.mouseX = e.clientX;
imageState.mouseY = e.clientY;
}
}
var imageMoveListener = function(e) {
if (el.classList.contains('jcrop_edition')) {
// Mark position
if (e.changedTouches && e.changedTouches[0]) {
var x = e.changedTouches[0].clientX;
var y = e.changedTouches[0].clientY;
} else {
var x = e.clientX;
var y = e.clientY;
}
var currentX = x;
var newX = currentX - imageState.mouseX;
imageState.mouseX = currentX;
var currentY = y;
var newY = currentY - imageState.mouseY;
imageState.mouseY = currentY;
if (imageState.mousedown) {
image.left += newX/properties.zoom.scale;
image.top += newY/properties.zoom.scale;
refreshResizers();
}
e.preventDefault();
}
}
el.addEventListener('mouseup', editorMouseUp);
el.addEventListener('mousedown', editorMouseDown);
el.addEventListener('mousemove', editorMouseMove);
el.addEventListener('touchstart',touchstartListener);
el.addEventListener('touchmove', imageMoveListener);
el.addEventListener('mousedown',touchstartListener);
document.addEventListener('mouseup', function(e) {
imageState.mousedown = false;
});
el.addEventListener('mousemove', imageMoveListener);
el.addEventListener("dblclick", function(e) {
jSuites.click(attachmentInput);
});
el.addEventListener('dragenter', function(e) {
el.style.border = '1px dashed #000';
});
el.addEventListener('dragleave', function(e) {
el.style.border = '1px solid #eee';
});
el.addEventListener('dragstop', function(e) {
el.style.border = '1px solid #eee';
});
el.addEventListener('dragover', function(e) {
e.preventDefault();
});
el.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
var html = (e.originalEvent || e).dataTransfer.getData('text/html');
var file = (e.originalEvent || e).dataTransfer.files;
if (file.length) {
for (var i = 0; i < e.dataTransfer.files.length; i++) {
obj.addFromFile(e.dataTransfer.files[i]);
}
} else if (html) {
// Create temp element
var div = document.createElement('div');
div.innerHTML = html;
// Extract images
var img = div.querySelector('img');
if (img) {
obj.addFromUrl(img.src);
}
}
el.style.border = '1px solid #eee';
return false;
});
el.addEventListener("wheel", function(e) {
if (el.classList.contains('jcrop_edition')) {
// Update scale
if (e.deltaY > 0) {
if (properties.zoom.scale > 0.1) {
properties.zoom.scale *= 0.9;
}
} else {
if (properties.zoom.scale < 5) {
properties.zoom.scale *= 1.1;
}
}
properties.zoom.scale = parseFloat(properties.zoom.scale.toFixed(2));
// Update coordinates
var rect = el.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
// Zoom on the image
var c = context.getImageData(x, y, 1, 1).data;
if (c[3] != 0) {
properties.zoom.origin.x = x;
properties.zoom.origin.y = y;
} else {
}
// Apply zoom
obj.zoom();
e.preventDefault();
}
});
// mobile events
el.addEventListener("click", function(e) {
if (! el.classList.contains('jcrop_edition')) {
jSuites.click(attachmentInput);
}
});
// Onchange
if (typeof(obj.options.onload) == 'function') {
obj.options.onload(el, obj);
}
// Initial image
if (obj.options.value) {
image.src = obj.options.value;
}
el.crop = obj;
return obj;
});
jSuites.login = (function(el, options) {
var obj = {};
obj.options = {};
// Default configuration
var defaults = {
url: window.location.href,
prepareRequest: null,
accessToken: null,
deviceToken: null,
facebookUrl: null,
facebookAuthentication: null,
maxHeight: null,
onload: null,
onsuccess: null,
onerror: null,
message: null,
logo: null,
newProfile: false,
newProfileUrl: false,
newProfileLogin: false,
fullscreen: false,
newPasswordValidation: null,
};
// Loop through our object
for (var property in defaults) {
if (options && options.hasOwnProperty(property)) {
obj.options[property] = options[property];
} else {
obj.options[property] = defaults[property];
}
}
// Message console container
if (! obj.options.message) {
var messageElement = document.querySelector('.message');
if (messageElement) {
obj.options.message = messageElement;
}
}
// Action
var action = null;
// Container
var container = document.createElement('form');
el.appendChild(container);
// Logo
var divLogo = document.createElement('div');
divLogo.className = 'jlogin-logo'
container.appendChild(divLogo);
if (obj.options.logo) {
var logo = document.createElement('img');
logo.src = obj.options.logo;
divLogo.appendChild(logo);
}
// Code
var labelCode = document.createElement('label');
labelCode.innerHTML = 'Please enter here the code received';
var inputCode = document.createElement('input');
inputCode.type = 'number';
inputCode.id = 'code';
inputCode.setAttribute('maxlength', 6);
var divCode = document.createElement('div');
divCode.appendChild(labelCode);
divCode.appendChild(inputCode);
// Hash
var inputHash = document.createElement('input');
inputHash.type = 'hidden';
inputHash.name = 'h';
var divHash = document.createElement('div');
divHash.appendChild(inputHash);
// Recovery
var inputRecovery = document.createElement('input');
inputRecovery.type = 'hidden';
inputRecovery.name = 'recovery';
inputRecovery.value = '1';
var divRecovery = document.createElement('div');
divRecovery.appendChild(inputRecovery);
// Login
var labelLogin = document.createElement('label');
labelLogin.innerHTML = 'Login';
var inputLogin = document.createElement('input');
inputLogin.type = 'text';
inputLogin.name = 'login';
inputLogin.setAttribute('autocomplete', 'off');
inputLogin.onkeyup = function() {
this.value = this.value.toLowerCase().replace(/[^a-zA-Z0-9_+]+/gi, '');
}
var divLogin = document.createElement('div');
divLogin.appendChild(labelLogin);
divLogin.appendChild(inputLogin);
// Name
var labelName = document.createElement('label');
labelName.innerHTML = 'Name';
var inputName = document.createElement('input');
inputName.type = 'text';
inputName.name = 'name';
var divName = document.createElement('div');
divName.appendChild(labelName);
divName.appendChild(inputName);
// Email
var labelUsername = document.createElement('label');
labelUsername.innerHTML = 'E-mail';
var inputUsername = document.createElement('input');
inputUsername.type = 'text';
inputUsername.name = 'username';
inputUsername.setAttribute('autocomplete', 'new-username');
var divUsername = document.createElement('div');
divUsername.appendChild(labelUsername);
divUsername.appendChild(inputUsername);
// Password
var labelPassword = document.createElement('label');
labelPassword.innerHTML = 'Password';
var inputPassword = document.createElement('input');
inputPassword.type = 'password';
inputPassword.name = 'password';
inputPassword.setAttribute('autocomplete', 'new-password');
var divPassword = document.createElement('div');
divPassword.appendChild(labelPassword);
divPassword.appendChild(inputPassword);
divPassword.onkeydown = function(e) {
if (e.keyCode == 13) {
obj.execute();
}
}
// Repeat password
var labelRepeatPassword = document.createElement('label');
labelRepeatPassword.innerHTML = 'Repeat the new password';
var inputRepeatPassword = document.createElement('input');
inputRepeatPassword.type = 'password';
inputRepeatPassword.name = 'password';
var divRepeatPassword = document.createElement('div');
divRepeatPassword.appendChild(labelRepeatPassword);
divRepeatPassword.appendChild(inputRepeatPassword);
// Remember checkbox
var labelRemember = document.createElement('label');
labelRemember.innerHTML = 'Remember me on this device';
var inputRemember = document.createElement('input');
inputRemember.type = 'checkbox';
inputRemember.name = 'remember';
inputRemember.value = '1';
labelRemember.appendChild(inputRemember);
var divRememberButton = document.createElement('div');
divRememberButton.className = 'rememberButton';
divRememberButton.appendChild(labelRemember);
// Login button
var actionButton = document.createElement('input');
actionButton.type = 'button';
actionButton.value = 'Log In';
actionButton.onclick = function() {
obj.execute();
}
var divActionButton = document.createElement('div');
divActionButton.appendChild(actionButton);
// Cancel button
var cancelButton = document.createElement('div');
cancelButton.innerHTML = 'Cancel';
cancelButton.className = 'cancelButton';
cancelButton.onclick = function() {
obj.requestAccess();
}
var divCancelButton = document.createElement('div');
divCancelButton.appendChild(cancelButton);
// Captcha
var labelCaptcha = document.createElement('label');
labelCaptcha.innerHTML = 'Please type here the code below';
var inputCaptcha = document.createElement('input');
inputCaptcha.type = 'text';
inputCaptcha.name = 'captcha';
var imageCaptcha = document.createElement('img');
var divCaptcha = document.createElement('div');
divCaptcha.className = 'jlogin-captcha';
divCaptcha.appendChild(labelCaptcha);
divCaptcha.appendChild(inputCaptcha);
divCaptcha.appendChild(imageCaptcha);
// Facebook
var facebookButton = document.createElement('div');
facebookButton.innerHTML = 'Login with Facebook';
facebookButton.className = 'facebookButton';
var divFacebookButton = document.createElement('div');
divFacebookButton.appendChild(facebookButton);
divFacebookButton.onclick = function() {
obj.requestLoginViaFacebook();
}
// Forgot password
var inputRequest = document.createElement('span');
inputRequest.innerHTML = 'Request a new password';
var divRequestButton = document.createElement('div');
divRequestButton.className = 'requestButton';
divRequestButton.appendChild(inputRequest);
divRequestButton.onclick = function() {
obj.requestNewPassword();
}
// Create a new Profile
var inputNewProfile = document.createElement('span');
inputNewProfile.innerHTML = 'Create a new profile';
var divNewProfileButton = document.createElement('div');
divNewProfileButton.className = 'newProfileButton';
divNewProfileButton.appendChild(inputNewProfile);
divNewProfileButton.onclick = function() {
obj.newProfile();
}
el.className = 'jlogin';
if (obj.options.fullscreen == true) {
el.classList.add('jlogin-fullscreen');
}
/**
* Show message
*/
obj.showMessage = function(data) {
var message = (typeof(data) == 'object') ? data.message : data;
if (typeof(obj.options.showMessage) == 'function') {
obj.options.showMessage(data);
} else {
jSuites.alert(data);
}
}
/**
* New profile
*/
obj.newProfile = function() {
container.innerHTML = '';
container.appendChild(divLogo);
if (obj.options.newProfileLogin) {
container.appendChild(divLogin);
}
container.appendChild(divName);
container.appendChild(divUsername);
container.appendChild(divActionButton);
if (obj.options.facebookAuthentication == true) {
container.appendChild(divFacebookButton);
}
container.appendChild(divCancelButton);
// Reset inputs
inputLogin.value = '';
inputUsername.value = '';
inputPassword.value = '';
// Button
actionButton.value = 'Create new profile';
// Action
action = 'newProfile';
}
/**
* Request the email with the recovery instructions
*/
obj.requestNewPassword = function() {
if (Array.prototype.indexOf.call(container.children, divCaptcha) >= 0) {
var captcha = true;
}
container.innerHTML = '';
container.appendChild(divLogo);
container.appendChild(divRecovery);
container.appendChild(divUsername);
if (captcha) {
container.appendChild(divCaptcha);
}
container.appendChild(divActionButton);
container.appendChild(divCancelButton);
actionButton.value = 'Request a new password';
inputRecovery.value = 1;
// Action
action = 'requestNewPassword';
}
/**
* Confirm recovery code
*/
obj.codeConfirmation = function() {
container.innerHTML = '';
container.appendChild(divLogo);
container.appendChild(divHash);
container.appendChild(divCode);
container.appendChild(divActionButton);
container.appendChild(divCancelButton);
actionButton.value = 'Confirm code';
inputRecovery.value = 2;
// Action
action = 'codeConfirmation';
}
/**
* Update my password
*/
obj.changeMyPassword = function(hash) {
container.innerHTML = '';
container.appendChild(divLogo);
container.appendChild(divHash);
container.appendChild(divPassword);
container.appendChild(divRepeatPassword);
container.appendChild(divActionButton);
container.appendChild(divCancelButton);
actionButton.value = 'Change my password';
inputHash.value = hash;
// Action
action = 'changeMyPassword';
}
/**
* Request access default method
*/
obj.requestAccess = function() {
container.innerHTML = '';
container.appendChild(divLogo);
container.appendChild(divUsername);
container.appendChild(divPassword);
container.appendChild(divActionButton);
if (obj.options.facebookAuthentication == true) {
container.appendChild(divFacebookButton);
}
container.appendChild(divRequestButton);
container.appendChild(divRememberButton);
container.appendChild(divRequestButton);
if (obj.options.newProfile == true) {
container.appendChild(divNewProfileButton);
}
// Button
actionButton.value = 'Login';
// Password
inputPassword.value = '';
// Email persistence
if (window.localStorage.getItem('username')) {
inputUsername.value = window.localStorage.getItem('username');
inputPassword.focus();
} else {
inputUsername.focus();
}
// Action
action = 'requestAccess';
}
/**
* Request login via facebook
*/
obj.requestLoginViaFacebook = function() {
if (typeof(deviceNotificationToken) == 'undefined') {
FB.getLoginStatus(function(response) {
if (! response.status || response.status != 'connected') {
FB.login(function(response) {
if (response.authResponse) {
obj.execute({ f:response.authResponse.accessToken });
} else {
obj.showMessage('Not authorized by facebook');
}
}, {scope: 'public_profile,email'});
} else {
obj.execute({ f:response.authResponse.accessToken });
}
}, true);
} else {
jDestroy = function() {
fbLogin.removeEventListener('loadstart', jStart);
fbLogin.removeEventListener('loaderror', jError);
fbLogin.removeEventListener('exit', jExit);
fbLogin.close();
fbLogin = null;
}
jStart = function(event) {
var url = event.url;
if (url.indexOf("access_token") >= 0) {
setTimeout(function(){
var u = url.match(/=(.*?)&/);
if (u[1].length > 32) {
obj.execute({ f:u[1] });
}
jDestroy();
},500);
}
if (url.indexOf("error=access_denied") >= 0) {
setTimeout(jDestroy ,500);
// Not authorized by facebook
obj.showMessage('Not authorized by facebook');
}
}
jError = function(event) {
jDestroy();
}
jExit = function(event) {
jDestroy();
}
fbLogin = window.open(obj.options.facebookUrl, "_blank", "location=no,closebuttoncaption=Exit,disallowoverscroll=yes,toolbar=no");
fbLogin.addEventListener('loadstart', jStart);
fbLogin.addEventListener('loaderror', jError);
fbLogin.addEventListener('exit', jExit);
}
// Action
action = 'requestLoginViaFacebook';
}
// Perform request
obj.execute = function(data) {
// New profile
if (action == 'newProfile') {
var pattern = new RegExp(/^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/);
if (! inputUsername.value || ! pattern.test(inputUsername.value)) {
var message = 'Invalid e-mail address';
}
var pattern = new RegExp(/^[a-zA-Z0-9\_\-\.\s+]+$/);
if (! inputLogin.value || ! pattern.test(inputLogin.value)) {
var message = 'Invalid username, please use only characters and numbers';
}
if (message) {
obj.showMessage(message);
return false;
}
} else if (action == 'changeMyPassword') {
if (inputPassword.value.length < 3) {
var message = 'Password is too short';
} else if (inputPassword.value != inputRepeatPassword.value) {
var message = 'Password should match';
} else {
if (typeof(obj.options.newPasswordValidation) == 'function') {
var val = obj.options.newPasswordValidation(obj, inputPassword.value, inputPassword.value);
if (val != undefined) {
message = val;
}
}
}
if (message) {
obj.showMessage(message);
return false;
}
}
// Keep email
if (inputUsername.value != '') {
window.localStorage.setItem('username', inputUsername.value);
}
// Captcha
if (Array.prototype.indexOf.call(container.children, divCaptcha) >= 0) {
if (inputCaptcha.value == '') {
obj.showMessage('Please enter the captch code below');
return false;
}
}
// Url
var url = obj.options.url;
// Device token
if (obj.options.deviceToken) {
url += '?token=' + obj.options.deviceToken;
}
// Callback
var onsuccess = function(result) {
if (result) {
// Successfully response
if (result.success == 1) {
// Recovery process
if (action == 'requestNewPassword') {
obj.codeConfirmation();
} else if (action == 'codeConfirmation') {
obj.requestAccess();
} else if (action == 'newProfile') {
obj.requestAccess();
// New profile
result.newProfile = true;
}
// Token
if (result.token) {
// Set token
obj.options.accessToken = result.token;
// Save token
window.localStorage.setItem('Access-Token', result.token);
}
}
// Show message
if (result.message) {
// Show message
obj.showMessage(result.message)
}
// Request captcha code
if (! result.data) {
if (Array.prototype.indexOf.call(container.children, divCaptcha) >= 0) {
divCaptcha.remove();
}
} else {
container.insertBefore(divCaptcha, divActionButton);
imageCaptcha.setAttribute('src', 'data:image/png;base64,' + result.data);
}
// Give time to user see the message
if (result.hash) {
// Change password
obj.changeMyPassword(result.hash);
} else if (result.url) {
// App initialization
if (result.success == 1) {
if (typeof(obj.options.onsuccess) == 'function') {
obj.options.onsuccess(result);
} else {
if (result.message) {
setTimeout(function() { window.location.href = result.url; }, 2000);
} else {
window.location.href = result.url;
}
}
} else {
if (typeof(obj.options.onerror) == 'function') {
obj.options.onerror(result);
}
}
}
}
}
// Password
if (! data) {
var data = jSuites.form.getElements(el, true);
// Encode passworfd
if (data.password) {
data.password = jSuites.sha512(data.password);
}
// Recovery code
if (Array.prototype.indexOf.call(container.children, divCode) >= 0 && inputCode.value) {
data.h = jSuites.sha512(inputCode.value);
}
}
// Loading
el.classList.add('jlogin-loading');
// Url
var url = (action == 'newProfile' && obj.options.newProfileUrl) ? obj.options.newProfileUrl : obj.options.url;
// Remote call
jSuites.ajax({
url: url,
method: 'POST',
dataType: 'json',
data: data,
success: function(result) {
// Remove loading
el.classList.remove('jlogin-loading');
// Callback
onsuccess(result);
},
error: function(result) {
// Error
el.classList.remove('jlogin-loading');
if (typeof(obj.options.onerror) == 'function') {
obj.options.onerror(result);
}
}
});
}
var queryString = window.location.href.split('?');
if (queryString[1] && queryString[1].length == 130 && queryString[1].substr(0,2) == 'h=') {
obj.changeMyPassword(queryString[1].substr(2));
} else {
obj.requestAccess();
}
return obj;
});
jSuites.login.sha512 = jSuites.sha512;
jSuites.menu = (function(el, options) {
var obj = {};
obj.show = function() {
el.style.display = 'block';
jSuites.animation.slideLeft(el, 1);
}
obj.hide = function() {
jSuites.animation.slideLeft(el, 0, function() {
el.style.display = '';
});
}
obj.load = function() {
if (localStorage) {
var menu = el.querySelectorAll('nav');
for (var i = 0; i < menu.length; i++) {
menu[i].classList.remove('selected');
if (menu[i].getAttribute('data-id')) {
var state = localStorage.getItem('jmenu-' + menu[i].getAttribute('data-id'));
if (state === null || state == 1) {
menu[i].classList.add('selected');
}
}
}
var href = localStorage.getItem('jmenu-href');
if (href) {
var menu = document.querySelector('.jmenu a[href="'+ href +'"]');
if (menu) {
menu.classList.add('selected');
}
}
}
}
obj.select = function(o) {
var menu = el.querySelectorAll('nav a');
for (var i = 0; i < menu.length; i++) {
menu[i].classList.remove('selected');
}
o.classList.add('selected');
}
var actionDown = function(e) {
if (e.target.tagName == 'H2') {
if (e.target.parentNode.classList.contains('selected')) {
e.target.parentNode.classList.remove('selected');
localStorage.setItem('jmenu-' + e.target.parentNode.getAttribute('data-id'), 0);
} else {
e.target.parentNode.classList.add('selected');
localStorage.setItem('jmenu-' + e.target.parentNode.getAttribute('data-id'), 1);
}
} else if (e.target.tagName == 'A') {
// Mark link as selected
obj.select(e.target);
// Keep the refernce in case load the page again
localStorage.setItem('jmenu-href', e.target.getAttribute('href'));
// Close menu if is oped
obj.hide();
}
}
if ('ontouchstart' in document.documentElement === true) {
el.addEventListener('touchstart', actionDown);
} else {
el.addEventListener('mousedown', actionDown);
}
// Add close action
var i = document.createElement('i');
i.className = 'material-icons small-screen-only close';
i.innerText = 'close';
i.onclick = function() {
obj.hide();
}
el.appendChild(i);
// Add menu class
el.classList.add('jmenu');
/*var h1 = window.innerHeight;
var h2 = el.offsetTop;
// Add the scroll
jSuites.scroll(el, {
//height: (h1 - h2) + 'px'
height: '1000px',
});*/
// Load state
obj.load();
// Keep reference
el.menu = obj;
return obj;
});
jSuites.signature = (function(el, options) {
var obj = {};
obj.options = {};
// Default configuration
var defaults = {
width: '100%',
height: '120px',
lineWidth: 3,
onchange: null,
value: null,
readonly: false,
}
// Loop through our object
for (var property in defaults) {
if (options && options.hasOwnProperty(property)) {
obj.options[property] = options[property];
} else {
obj.options[property] = defaults[property];
}
}
el.style.width = obj.options.width;
el.style.height = obj.options.height;
el.classList.add('jsignature');
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
el.appendChild(canvas);
// Position
var x = null;
var y = null;
// Coordinates
var coordinates = [];
obj.setValue = function(c) {
obj.reset();
ctx.beginPath();
ctx.lineWidth = obj.options.lineWidth;
ctx.lineCap = 'round';
ctx.strokeStyle = '#000';
ctx.moveTo(c[0][0], c[0][1]);
for (var i = 1; i < c.length; i++) {
ctx.lineTo(c[i][0], c[i][1]);
ctx.stroke();
}
}
obj.getValue = function() {
return coordinates;
}
obj.reset = function() {
coordinates = [];
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
var setPosition = function(e) {
// Mark position
if (e.changedTouches && e.changedTouches[0]) {
var rect = e.target.getBoundingClientRect();
x = e.changedTouches[0].clientX - rect.x;
y = e.changedTouches[0].clientY - rect.y;
} else {
x = e.offsetX;
y = e.offsetY;
}
}
var resize = function() {
ctx.canvas.width = el.offsetWidth;
ctx.canvas.height = el.offsetHeight;
}
var draw = function(e) {
if (x == null || obj.options.readonly == true) {
return false;
} else {
e = e || window.event;
if (e.buttons) {
var mouseButton = e.buttons;
} else if (e.button) {
var mouseButton = e.button;
} else {
var mouseButton = e.which;
}
coordinates.push([ x, y ]);
ctx.beginPath();
ctx.lineWidth = obj.options.lineWidth;
ctx.lineCap = 'round';
ctx.strokeStyle = '#000';
ctx.moveTo(x, y);
setPosition(e);
ctx.lineTo(x, y);
ctx.stroke();
e.preventDefault();
e.stopPropagation();
}
}
var finalize = function() {
x = null;
y = null;
}
window.addEventListener('resize', resize);
if ('ontouchmove' in document.documentElement === true) {
el.addEventListener('touchstart', setPosition);
el.addEventListener('touchmove', draw);
el.addEventListener('touchend', finalize);
} else {
el.addEventListener('mousedown', setPosition);
el.addEventListener('mousemove', draw);
el.addEventListener('mouseup', finalize);
}
resize();
if (obj.options.value) {
obj.setValue(obj.options.value);
}
el.signature = obj;
return obj;
});
jSuites.template = (function(el, options) {
var obj = {};
obj.options = {};
// Default configuration
var defaults = {
url: null,
data: null,
filter: null,
pageNumber: 0,
numberOfPages: 0,
template: null,
render: null,
noRecordsFound: 'No records found',
containerClass: null,
// Searchable
search: null,
searchInput: true,
searchPlaceHolder: '',
searchValue: '',
// Remote search
remoteData: null,
// Pagination page number of items
pagination: null,
onload: null,
onchange: null,
onsearch: null,
onclick: null,
}
// Loop through our object
for (var property in defaults) {
if (options && options.hasOwnProperty(property)) {
obj.options[property] = options[property];
} else {
obj.options[property] = defaults[property];
}
}
// Reset content
el.innerHTML = '';
// Input search
if (obj.options.search && obj.options.searchInput == true) {
// Timer
var searchTimer = null;
// Search container
var searchContainer = document.createElement('div');
searchContainer.className = 'jtemplate-results';
obj.searchInput = document.createElement('input');
obj.searchInput.value = obj.options.searchValue;
obj.searchInput.onkeyup = function(e) {
// Clear current trigger
if (searchTimer) {
clearTimeout(searchTimer);
}
// Prepare search
searchTimer = setTimeout(function() {
obj.search(obj.searchInput.value.toLowerCase());
searchTimer = null;
}, 300)
}
searchContainer.appendChild(obj.searchInput);
el.appendChild(searchContainer);
if (obj.options.searchPlaceHolder) {
obj.searchInput.setAttribute('placeholder', obj.options.searchPlaceHolder);
}
}
// Pagination container
if (obj.options.pagination) {
var pagination = document.createElement('div');
pagination.className = 'jtemplate-pagination';
el.appendChild(pagination);
}
// Content
var container = document.createElement('div');
if (obj.options.containerClass) {
container.className = obj.options.containerClass;
}
container.classList.add ('jtemplate-content');
el.appendChild(container);
// Data container
var searchResults = null;
obj.updatePagination = function() {
// Reset pagination container
if (pagination) {
pagination.innerHTML = '';
}
// Create pagination
if (obj.options.pagination > 0 && obj.options.numberOfPages > 1) {
// Number of pages
var numberOfPages = obj.options.numberOfPages;
// Controllers
if (obj.options.pageNumber < 6) {
var startNumber = 1;
var finalNumber = numberOfPages < 10 ? numberOfPages : 10;
} else if (numberOfPages - obj.options.pageNumber < 5) {
var startNumber = numberOfPages - 9;
var finalNumber = numberOfPages;
if (startNumber < 1) {
startNumber = 1;
}
} else {
var startNumber = obj.options.pageNumber - 4;
var finalNumber = obj.options.pageNumber + 5;
}
// First
if (startNumber > 1) {
var paginationItem = document.createElement('div');
paginationItem.innerHTML = '<';
paginationItem.title = 1;
pagination.appendChild(paginationItem);
}
// Get page links
for (var i = startNumber; i <= finalNumber; i++) {
var paginationItem = document.createElement('div');
paginationItem.innerHTML = i;
pagination.appendChild(paginationItem);
if (obj.options.pageNumber == i - 1) {
paginationItem.style.fontWeight = 'bold';
}
}
// Last
if (finalNumber < numberOfPages) {
var paginationItem = document.createElement('div');
paginationItem.innerHTML = '>';
paginationItem.title = numberOfPages - 1;
pagination.appendChild(paginationItem);
}
}
}
/**
* Append data to the template and add to the DOMContainer
* @param data
* @param contentDOMContainer
*/
obj.setContent = function(a, b) {
var c = obj.options.template[Object.keys(obj.options.template)[0]](a);
if ((c instanceof Element || c instanceof HTMLDocument)) {
b.appendChild(c);
} else {
b.innerHTML = c;
}
}
obj.addItem = function(data, beginOfDataSet) {
// Append itens
var content = document.createElement('div');
// Append data
if (beginOfDataSet) {
obj.options.data.unshift(data);
} else {
obj.options.data.push(data);
}
// If is empty remove indication
if (container.classList.contains('jtemplate-empty')) {
container.classList.remove('jtemplate-empty');
container.innerHTML = '';
}
// Get content
obj.setContent(data, content);
// Add animation
jSuites.animation.fadeIn(content.children[0]);
// Add and do the animation
if (beginOfDataSet) {
container.prepend(content.children[0]);
} else {
container.append(content.children[0]);
}
// Onchange method
if (typeof(obj.options.onchange) == 'function') {
obj.options.onchange(el, obj.options.data);
}
}
obj.removeItem = function(element) {
if (Array.prototype.indexOf.call(container.children, element) > -1) {
// Remove data from array
var index = obj.options.data.indexOf(element.dataReference);
if (index > -1) {
obj.options.data.splice(index, 1);
}
// Remove element from DOM
jSuites.animation.fadeOut(element, function() {
element.parentNode.removeChild(element);
if (! container.innerHTML) {
container.classList.add('jtemplate-empty');
container.innerHTML = obj.options.noRecordsFound;
}
});
} else {
console.error('Element not found');
}
}
obj.setData = function(data) {
if (data) {
obj.options.pageNumber = 1;
obj.options.searchValue = '';
// Set data
obj.options.data = data;
// Reset any search results
searchResults = null;
// Render new data
obj.render();
// Onchange method
if (typeof(obj.options.onchange) == 'function') {
obj.options.onchange(el, obj.options.data);
}
}
}
obj.appendData = function(data, pageNumber) {
if (pageNumber) {
obj.options.pageNumber = pageNumber;
}
var execute = function(data) {
// Concat data
obj.options.data.concat(data);
// Number of pages
if (obj.options.pagination > 0) {
obj.options.numberOfPages = Math.ceil(obj.options.data.length / obj.options.pagination);
}
var startNumber = 0;
var finalNumber = data.length;
// Append itens
var content = document.createElement('div');
for (var i = startNumber; i < finalNumber; i++) {
obj.setContent(data[i], content)
content.children[0].dataReference = data[i]; // TODO: data[i] or i?
container.appendChild(content.children[0]);
}
}
if (obj.options.url && obj.options.remoteData == true) {
// URL
var url = obj.options.url;
// Data
var ajaxData = {};
// Options for backend search
if (obj.options.remoteData) {
// Search value
if (obj.options.searchValue) {
ajaxData.q = obj.options.searchValue;
}
// Page number
if (obj.options.pageNumber) {
ajaxData.p = obj.options.pageNumber;
}
// Number items per page
if (obj.options.pagination) {
ajaxData.t = obj.options.pagination;
}
}
// Remote loading
jSuites.ajax({
url: url,
method: 'GET',
data: ajaxData,
dataType: 'json',
success: function(data) {
execute(data);
}
});
} else {
if (! obj.options.data) {
console.log('TEMPLATE: no data or external url defined');
} else {
execute(data);
}
}
}
obj.renderTemplate = function() {
// Data container
var data = searchResults ? searchResults : obj.options.data;
// Data filtering
if (typeof(obj.options.filter) == 'function') {
data = obj.options.filter(data);
}
// Reset pagination
obj.updatePagination();
if (! data.length) {
container.innerHTML = obj.options.noRecordsFound;
container.classList.add('jtemplate-empty');
} else {
// Reset content
container.classList.remove('jtemplate-empty');
// Create pagination
if (obj.options.pagination && data.length > obj.options.pagination) {
var startNumber = (obj.options.pagination * obj.options.pageNumber);
var finalNumber = (obj.options.pagination * obj.options.pageNumber) + obj.options.pagination;
if (data.length < finalNumber) {
var finalNumber = data.length;
}
} else {
var startNumber = 0;
var finalNumber = data.length;
}
// Append itens
var content = document.createElement('div');
for (var i = startNumber; i < finalNumber; i++) {
// Get content
obj.setContent(data[i], content);
content.children[0].dataReference = data[i];
container.appendChild(content.children[0]);
}
}
}
obj.render = function(pageNumber, forceLoad) {
// Update page number
if (pageNumber != undefined) {
obj.options.pageNumber = pageNumber;
} else {
if (! obj.options.pageNumber && obj.options.pagination > 0) {
obj.options.pageNumber = 0;
}
}
// Render data into template
var execute = function() {
// Render new content
if (typeof(obj.options.render) == 'function') {
container.innerHTML = obj.options.render(obj);
} else {
container.innerHTML = '';
}
// Load data
obj.renderTemplate();
// Onload
if (typeof(obj.options.onload) == 'function') {
obj.options.onload(el, obj);
}
}
if (obj.options.url && (obj.options.remoteData == true || forceLoad)) {
// URL
var url = obj.options.url;
// Data
var ajaxData = {};
// Options for backend search
if (obj.options.remoteData) {
// Search value
if (obj.options.searchValue) {
ajaxData.q = obj.options.searchValue;
}
// Page number
if (obj.options.pageNumber) {
ajaxData.p = obj.options.pageNumber;
}
// Number items per page
if (obj.options.pagination) {
ajaxData.t = obj.options.pagination;
}
}
// Remote loading
jSuites.ajax({
url: url,
method: 'GET',
dataType: 'json',
data: ajaxData,
success: function(data) {
// Search and keep data in the client side
if (data.hasOwnProperty("total")) {
obj.options.numberOfPages = Math.ceil(data.total / obj.options.pagination);
obj.options.data = data.data;
} else {
// Number of pages
if (obj.options.pagination > 0) {
obj.options.numberOfPages = Math.ceil(data.length / obj.options.pagination);
}
obj.options.data = data;
}
// Load data for the user
execute();
}
});
} else {
if (! obj.options.data) {
console.log('TEMPLATE: no data or external url defined');
} else {
// Number of pages
if (obj.options.pagination > 0) {
if (searchResults) {
obj.options.numberOfPages = Math.ceil(searchResults.length / obj.options.pagination);
} else {
obj.options.numberOfPages = Math.ceil(obj.options.data.length / obj.options.pagination);
}
}
// Load data for the user
execute();
}
}
}
obj.search = function(query) {
obj.options.pageNumber = 0;
obj.options.searchValue = query ? query : '';
// Filter data
if (obj.options.remoteData == true || ! query) {
searchResults = null;
} else {
var test = function(o, query) {
for (var key in o) {
var value = o[key];
if ((''+value).toLowerCase().search(query) >= 0) {
return true;
}
}
return false;
}
searchResults = obj.options.data.filter(function(item) {
return test(item, query);
});
}
obj.render();
if (typeof(obj.options.onsearch) == 'function') {
obj.options.onsearch(el, obj, query);
}
}
obj.refresh = function() {
obj.render();
}
obj.reload = function() {
obj.render(0, true);
}
el.addEventListener('mousedown', function(e) {
if (e.target.parentNode.classList.contains('jtemplate-pagination')) {
var index = e.target.innerText;
if (index == '<') {
obj.render(0);
} else if (index == '>') {
obj.render(e.target.getAttribute('title'));
} else {
obj.render(parseInt(index)-1);
}
e.preventDefault();
}
});
el.addEventListener('click', function(e) {
if (typeof(obj.options.onclick) == 'function') {
obj.options.onclick(el, obj, e);
}
});
el.template = obj;
// Render data
obj.render(0, true);
return obj;
});
jSuites.timeline = (function(el, options) {
var obj = {};
obj.options = {};
// Two digits
var two = function(value) {
value = '' + value;
if (value.length == 1) {
value = '0' + value;
}
return value;
}
// Default date format
if (! options.date) {
var date = new Date();
var y = date.getFullYear();
var m = two(date.getMonth() + 1);
date = y + '-' + m;
}
// Default configurations
var defaults = {
url: null,
data: [],
date: date,
months: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
onaction: null,
text: {
noInformation: '<div class="jtimeline-message">No information for this period</div>',
}
};
// Loop through our object
for (var property in defaults) {
if (options && options.hasOwnProperty(property)) {
obj.options[property] = options[property];
} else {
obj.options[property] = defaults[property];
}
}
// Add class
el.classList.add('jtimeline');
// Header
var timelineHeader = document.createElement('div');
timelineHeader.className = 'jtimeline-header';
var timelineLabel = document.createElement('div');
timelineLabel.className = 'jtimeline-label';
var timelineNavigation = document.createElement('div');
timelineNavigation.className = 'jtimeline-navigation';
// Labels
var timelineMonth = document.createElement('div');
timelineMonth.className = 'jtimeline-month';
timelineMonth.innerHTML = '';
timelineLabel.appendChild(timelineMonth);
var timelineYear = document.createElement('div');
timelineYear.className = 'jtimeline-year';
timelineYear.innerHTML = '';
timelineLabel.appendChild(timelineYear);
// Navigation
var timelinePrev = document.createElement('div');
timelinePrev.className = 'jtimeline-prev';
timelinePrev.innerHTML = '<i class="material-icons">keyboard_arrow_left</i>';
timelineNavigation.appendChild(timelinePrev);
var timelineNext = document.createElement('div');
timelineNext.className = 'jtimeline-next';
timelineNext.innerHTML = '<i class="material-icons">keyboard_arrow_right</i>';
timelineNavigation.appendChild(timelineNext);
timelineHeader.appendChild(timelineLabel);
timelineHeader.appendChild(timelineNavigation);
// Data container
var timelineContainer = document.createElement('div');
timelineContainer.className = 'jtimeline-container';
// Append headers
el.appendChild(timelineHeader);
el.appendChild(timelineContainer);
// Date
if (obj.options.date.length > 7) {
obj.options.date = obj.options.date.substr(0, 7)
}
// Action
var action = function(o) {
// Get item
var item = o.parentNode.parentNode.parentNode.parentNode;
// Get id
var id = item.getAttribute('data-id');
}
obj.setData = function(rows) {
var data = [];
for (var i = 0; i < rows.length; i++) {
var d = rows[i].date.substr(0,7);
// Create the object if not exists
if (! data[d]) {
data[d] = [];
}
// Create array
data[d].push(rows[i]);
};
obj.options.data = data;
obj.render(obj.options.date);
}
obj.add = function(data) {
var date = data.date.substr(0,7);
// Create the object if not exists
if (! obj.options.data[date]) {
obj.options.data[date] = [];
}
// Format date
data.date = data.date.substr(0,10);
// Append data
obj.options.data[date].push(data);
// Reorder
obj.options.data[date] = obj.options.data[date].order();
// Render
obj.render(date);
}
obj.remove = function(item) {
var index = item.getAttribute('data-index');
var date = item.getAttribute('data-date');
jSuites.animation.fadeOut(item, function() {
item.remove();
});
obj.options.data[date].splice(index, 1);
}
obj.reload = function() {
var date = obj.options.date
obj.render(date);
}
obj.render = function(date) {
// Filter
if (date.length > 7) {
var date = date.substr(0,7);
}
// Update current date
obj.options.date = date;
// Reset data
timelineContainer.innerHTML = '';
// Days
var timelineDays = [];
// Itens
if (! obj.options.data[date]) {
timelineContainer.innerHTML = obj.options.text.noInformation;
} else {
for (var i = 0; i < obj.options.data[date].length; i++) {
var v = obj.options.data[date][i];
var d = v.date.split('-');
// Item container
var timelineItem = document.createElement('div');
timelineItem.className = 'jtimeline-item';
timelineItem.setAttribute('data-id', v.id);
timelineItem.setAttribute('data-index', i);
timelineItem.setAttribute('data-date', date);
// Date
var timelineDateContainer = document.createElement('div');
timelineDateContainer.className = 'jtimeline-date-container';
var timelineDate = document.createElement('div');
if (! timelineDays[d[2]]) {
timelineDate.className = 'jtimeline-date jtimeline-date-bullet';
timelineDate.innerHTML = d[2];
} else {
timelineDate.className = 'jtimeline-date';
timelineDate.innerHTML = '';
}
timelineDateContainer.appendChild(timelineDate);
var timelineContent = document.createElement('div');
timelineContent.className = 'jtimeline-content';
// Title
if (! v.title) {
v.title = v.subtitle ? v.subtitle : 'Information';
}
var timelineTitleContainer = document.createElement('div');
timelineTitleContainer.className = 'jtimeline-title-container';
timelineContent.appendChild(timelineTitleContainer);
var timelineTitle = document.createElement('div');
timelineTitle.className = 'jtimeline-title';
timelineTitle.innerHTML = v.title;
timelineTitleContainer.appendChild(timelineTitle);
var timelineControls = document.createElement('div');
timelineControls.className = 'jtimeline-controls';
timelineTitleContainer.appendChild(timelineControls);
var timelineEdit = document.createElement('i');
timelineEdit.className = 'material-icons timeline-edit';
timelineEdit.innerHTML = 'edit';
timelineEdit.onclick = function() {
if (typeof(obj.options.onaction) == 'function') {
obj.options.onaction(obj, this);
}
}
if (v.author == 1) {
timelineControls.appendChild(timelineEdit);
}
var timelineSubtitle = document.createElement('div');
timelineSubtitle.className = 'jtimeline-subtitle';
timelineSubtitle.innerHTML = v.subtitle ? v.subtitle : '';
timelineContent.appendChild(timelineSubtitle);
// Text
var timelineText = document.createElement('div');
timelineText.className = 'jtimeline-text';
timelineText.innerHTML = v.text;
timelineContent.appendChild(timelineText);
// Tag
var timelineTags = document.createElement('div');
timelineTags.className = 'jtimeline-tags';
timelineContent.appendChild(timelineTags);
if (v.tags) {
var createTag = function(name, color) {
var timelineTag = document.createElement('div');
timelineTag.className = 'jtimeline-tag';
timelineTag.innerHTML = name;
if (color) {
timelineTag.style.backgroundColor = color;
}
return timelineTag;
}
if (typeof(v.tags) == 'string') {
var t = createTag(v.tags);
timelineTags.appendChild(t);
} else {
for (var j = 0; j < v.tags.length; j++) {
var t = createTag(v.tags[j].text, v.tags[j].color);
timelineTags.appendChild(t);
}
}
}
// Day
timelineDays[d[2]] = true;
// Append Item
timelineItem.appendChild(timelineDateContainer);
timelineItem.appendChild(timelineContent);
timelineContainer.appendChild(timelineItem);
};
}
// Update labels
var d = date.split('-');
timelineYear.innerHTML = d[0];
timelineMonth.innerHTML = obj.options.monthsFull[parseInt(d[1]) - 1];
}
obj.next = function() {
// Update current date
var d = obj.options.date.split('-');
// Next month
d[1]++;
// Next year
if (d[1] > 12) {
d[0]++;
d[1] = 1;
}
date = d[0] + '-' + (d[1] < 10 ? '0' + d[1] : d[1]);
// Animation
jSuites.animation.slideLeft(timelineContainer, 0, function() {
obj.render(date);
jSuites.animation.slideRight(timelineContainer, 1);
});
}
obj.prev = function() {
// Update current date
var d = obj.options.date.split('-');
// Next month
d[1]--;
// Next year
if (d[1] < 1) {
d[0]--;
d[1] = 12;
}
date = d[0] + '-' + (d[1] < 10 ? '0' + d[1] : d[1]);
// Animation
jSuites.animation.slideRight(timelineContainer, 0, function() {
obj.render(date);
jSuites.animation.slideLeft(timelineContainer, 1);
});
}
obj.load = function() {
// Init
if (obj.options.url) {
jSuites.ajax({
url: obj.options.url,
type: 'GET',
dataType:'json',
success: function(data) {
// Timeline data
obj.setData(data);
}
});
} else {
// Timeline data
obj.setData(obj.options.data);
}
}
obj.reload = function() {
obj.load();
}
obj.load();
var timelineMouseUpControls = function(e) {
if (e.target.classList.contains('jtimeline-next') || e.target.parentNode.classList.contains('jtimeline-next')) {
obj.next();
} else if (e.target.classList.contains('jtimeline-prev') || e.target.parentNode.classList.contains('jtimeline-prev')) {
obj.prev();
}
}
if ('ontouchend' in document.documentElement === true) {
el.addEventListener("touchend", timelineMouseUpControls);
} else {
el.addEventListener("mouseup", timelineMouseUpControls);
}
// Add global events
el.addEventListener("swipeleft", function(e) {
obj.next();
e.preventDefault();
e.stopPropagation();
});
el.addEventListener("swiperight", function(e) {
obj.prev();
e.preventDefault();
e.stopPropagation();
});
// Orderby
Array.prototype.order = function() {
return this.slice(0).sort(function(a, b) {
var valueA = a.date;
var valueB = b.date;
return (valueA > valueB) ? 1 : (valueA < valueB) ? -1 : 0;
});
}
el.timeline = obj;
return obj;
});
return jSuites;
})));