This commit is contained in:
Tony Air 2019-05-23 20:02:50 +07:00
parent 4fa466157f
commit 5358afd5ec
15 changed files with 1623 additions and 1623 deletions

View File

@ -5,258 +5,258 @@ import Events from '../_events';
import Spinner from './_ui.spinner'; import Spinner from './_ui.spinner';
const AjaxUI = (($) => { const AjaxUI = (($) => {
// Constants // Constants
const G = window; const G = window;
const D = document; const D = document;
const $Html = $('html'); const $Html = $('html');
const $Body = $('body'); const $Body = $('body');
const NAME = 'jsAjaxUI'; const NAME = 'jsAjaxUI';
const DATA_KEY = NAME; const DATA_KEY = NAME;
class AjaxUI { class AjaxUI {
// Constructor // Constructor
constructor(element) { constructor(element) {
this._element = element; this._element = element;
const $element = $(this._element); const $element = $(this._element);
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
$element.bind('click', function(e) { $element.bind('click', function(e) {
e.preventDefault(); e.preventDefault();
const $this = $(this); const $this = $(this);
$('.ajax').each(function() { $('.ajax').each(function() {
const $this = $(this); const $this = $(this);
$this.removeClass('active'); $this.removeClass('active');
$this.parents('.nav-item').removeClass('active'); $this.parents('.nav-item').removeClass('active');
}); });
$this.addClass('loading'); $this.addClass('loading');
AjaxUI.load($this.attr('href'), () => { AjaxUI.load($this.attr('href'), () => {
$this.removeClass('loading'); $this.removeClass('loading');
$this.parents('.nav-item').addClass('active'); $this.parents('.nav-item').addClass('active');
$this.addClass('active'); $this.addClass('active');
}); });
}); });
}
// Public methods
static load(url, callback) {
// show spinner
Spinner.show(() => {
$Body.removeClass('loaded');
});
// update document location
G.MainUI.updateLocation(url);
const absoluteLocation = G.URLDetails['base'] + G.URLDetails['relative'].substring(1);
if (absoluteLocation !== G.location.href) {
G.history.pushState({
ajax: true,
page: absoluteLocation,
}, document.title, absoluteLocation);
}
$.ajax({
sync: false,
async: true,
url,
dataType: 'json',
method: 'GET',
cache: false,
error(jqXHR) {
console.warn(`AJAX request failure: ${jqXHR.statusText}`);
G.location.href = url;
// google analytics
if (typeof G.ga === 'function') {
G.ga('send', 'event', 'error', 'AJAX ERROR', jqXHR.statusText);
}
},
success(data, status, jqXHR) {
AjaxUI.process(data, jqXHR, callback);
// google analytics
if (typeof G.ga === 'function') {
G.ga('set', {
page: G.URLDetails['relative'] + G.URLDetails['hash'],
title: jqXHR.getResponseHeader('X-Title'),
});
G.ga('send', 'pageview');
}
},
});
}
static process(data, jqXHR, callback) {
const css = jqXHR.getResponseHeader('X-Include-CSS').split(',') || [];
const js = jqXHR.getResponseHeader('X-Include-JS').split(',') || [];
// Replace HTML regions
if (typeof(data.regions) === 'object') {
for (const key in data.regions) {
if (typeof(data.regions[key]) === 'string') {
AjaxUI.replaceRegion(data.regions[key], key);
}
}
}
// remove already loaded scripts
$('link[type="text/css"]').each(function() {
const i = css.indexOf($(this).attr('href'));
if (i > -1) {
css.splice(i, 1);
} else if (!$Body.data('unload-blocked')) {
console.log(`Unloading: ${ $(this).attr('href')}`);
$(this).remove();
}
});
$('script[type="text/javascript"]').each(function() {
const i = js.indexOf($(this).attr('src'));
if (i > -1) {
js.splice(i, 1);
} else if (!$Body.data('unload-blocked')) {
console.log(`Unloading: ${ $(this).attr('src')}`);
$(this).remove();
}
});
// preload CSS
this.preload(css).then(() => {
const $head = $('head');
css.forEach((el) => {
$head.append(`<link rel="stylesheet" type="text/css" href="${el}" />`);
});
// preload JS
this.preload(js, 'script').then(() => {
js.forEach((el) => {
$Body.append(`<script type="text/javascript" charset="UTF-8" src="${el}"></script>`);
});
console.log('New page is loaded!');
// trigger events
if (typeof(data.events) === 'object') {
for (const eventName in data.events) {
$(D).trigger(eventName, [data.events[eventName]]);
}
}
if (typeof callback !== 'undefined') {
callback();
}
$(G).trigger(Events.AJAX);
});
});
}
static preload(items, type = 'text', cache = true, itemCallback = false) {
if (!items.length) {
return $.Deferred().resolve().promise();
}
const dfds = [];
items.forEach((url, i) => {
const dfd = $.Deferred();
$.ajax({
dataType: type,
cache,
url,
}).always(() => {
dfd.resolve();
if (itemCallback) {
itemCallback(i, url);
}
});
dfds.push(dfd);
});
// return a master promise object which will resolve when all the deferred objects have resolved
return $.when(...dfds);
}
static replaceRegion(html, key) {
const $region = $(`[data-ajax-region="${key}"]`);
if ($region.length) {
$region.empty().append(html);
} else {
console.warn('Region returned without class or id!');
}
}
dispose() {
const $element = $(this._element);
$element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new AjaxUI(this);
$element.data(DATA_KEY, data);
}
});
}
} }
// jQuery interface // Public methods
$.fn[NAME] = AjaxUI._jQueryInterface; static load(url, callback) {
$.fn[NAME].Constructor = AjaxUI; // show spinner
$.fn[NAME].noConflict = function() { Spinner.show(() => {
$.fn[NAME] = JQUERY_NO_CONFLICT; $Body.removeClass('loaded');
return AjaxUI._jQueryInterface; });
};
// auto-apply // update document location
$('.ajax').ready(() => { G.MainUI.updateLocation(url);
$('.ajax').jsAjaxUI();
});
// AJAX update browser title const absoluteLocation = G.URLDetails['base'] + G.URLDetails['relative'].substring(1);
$(D).on('layoutRefresh', (e, data) => { if (absoluteLocation !== G.location.href) {
D.title = data.Title; G.history.pushState({
ajax: true,
page: absoluteLocation,
}, document.title, absoluteLocation);
}
$Html.attr('class', ''); $.ajax({
if (data.ClassName) { sync: false,
$Html.addClass(data.ClassName); async: true,
url,
dataType: 'json',
method: 'GET',
cache: false,
error(jqXHR) {
console.warn(`AJAX request failure: ${jqXHR.statusText}`);
G.location.href = url;
// google analytics
if (typeof G.ga === 'function') {
G.ga('send', 'event', 'error', 'AJAX ERROR', jqXHR.statusText);
}
},
success(data, status, jqXHR) {
AjaxUI.process(data, jqXHR, callback);
// google analytics
if (typeof G.ga === 'function') {
G.ga('set', {
page: G.URLDetails['relative'] + G.URLDetails['hash'],
title: jqXHR.getResponseHeader('X-Title'),
});
G.ga('send', 'pageview');
}
},
});
}
static process(data, jqXHR, callback) {
const css = jqXHR.getResponseHeader('X-Include-CSS').split(',') || [];
const js = jqXHR.getResponseHeader('X-Include-JS').split(',') || [];
// Replace HTML regions
if (typeof(data.regions) === 'object') {
for (const key in data.regions) {
if (typeof(data.regions[key]) === 'string') {
AjaxUI.replaceRegion(data.regions[key], key);
}
} }
//data.Link = (data.Link === '/home/') ? '/' : data.Link; }
});
// Back/Forward functionality // remove already loaded scripts
G.onpopstate = function(event) { $('link[type="text/css"]').each(function() {
const $existingLink = $(`a[href^="${ D.location }"]`); const i = css.indexOf($(this).attr('href'));
if (i > -1) {
if (event.state !== null && event.state.ajax) { css.splice(i, 1);
console.log('GOBACK (AJAX state)'); } else if (!$Body.data('unload-blocked')) {
AjaxUI.load(event.state.page); console.log(`Unloading: ${ $(this).attr('href')}`);
} else if ($existingLink.length && $existingLink.hasClass('ajax')) { $(this).remove();
console.log('GOBACK (AJAX link)');
$existingLink.trigger('click');
} else {
console.log('GOBACK (HTTP)');
G.location.href = D.location;
} }
}; });
return AjaxUI; $('script[type="text/javascript"]').each(function() {
const i = js.indexOf($(this).attr('src'));
if (i > -1) {
js.splice(i, 1);
} else if (!$Body.data('unload-blocked')) {
console.log(`Unloading: ${ $(this).attr('src')}`);
$(this).remove();
}
});
// preload CSS
this.preload(css).then(() => {
const $head = $('head');
css.forEach((el) => {
$head.append(`<link rel="stylesheet" type="text/css" href="${el}" />`);
});
// preload JS
this.preload(js, 'script').then(() => {
js.forEach((el) => {
$Body.append(`<script type="text/javascript" charset="UTF-8" src="${el}"></script>`);
});
console.log('New page is loaded!');
// trigger events
if (typeof(data.events) === 'object') {
for (const eventName in data.events) {
$(D).trigger(eventName, [data.events[eventName]]);
}
}
if (typeof callback !== 'undefined') {
callback();
}
$(G).trigger(Events.AJAX);
});
});
}
static preload(items, type = 'text', cache = true, itemCallback = false) {
if (!items.length) {
return $.Deferred().resolve().promise();
}
const dfds = [];
items.forEach((url, i) => {
const dfd = $.Deferred();
$.ajax({
dataType: type,
cache,
url,
}).always(() => {
dfd.resolve();
if (itemCallback) {
itemCallback(i, url);
}
});
dfds.push(dfd);
});
// return a master promise object which will resolve when all the deferred objects have resolved
return $.when(...dfds);
}
static replaceRegion(html, key) {
const $region = $(`[data-ajax-region="${key}"]`);
if ($region.length) {
$region.empty().append(html);
} else {
console.warn('Region returned without class or id!');
}
}
dispose() {
const $element = $(this._element);
$element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new AjaxUI(this);
$element.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = AjaxUI._jQueryInterface;
$.fn[NAME].Constructor = AjaxUI;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return AjaxUI._jQueryInterface;
};
// auto-apply
$('.ajax').ready(() => {
$('.ajax').jsAjaxUI();
});
// AJAX update browser title
$(D).on('layoutRefresh', (e, data) => {
D.title = data.Title;
$Html.attr('class', '');
if (data.ClassName) {
$Html.addClass(data.ClassName);
}
//data.Link = (data.Link === '/home/') ? '/' : data.Link;
});
// Back/Forward functionality
G.onpopstate = function(event) {
const $existingLink = $(`a[href^="${ D.location }"]`);
if (event.state !== null && event.state.ajax) {
console.log('GOBACK (AJAX state)');
AjaxUI.load(event.state.page);
} else if ($existingLink.length && $existingLink.hasClass('ajax')) {
console.log('GOBACK (AJAX link)');
$existingLink.trigger('click');
} else {
console.log('GOBACK (HTTP)');
G.location.href = D.location;
}
};
return AjaxUI;
})($); })($);
export default AjaxUI; export default AjaxUI;

View File

@ -3,88 +3,88 @@ import $ from 'jquery';
import Events from '../_events'; import Events from '../_events';
const CarouselUI = (($) => { const CarouselUI = (($) => {
// Constants // Constants
const NAME = 'CarouselUI'; const NAME = 'CarouselUI';
class CarouselUI { class CarouselUI {
// Static methods // Static methods
static each(callback) { static each(callback) {
$('.js-carousel').each(function(i, e) { $('.js-carousel').each((i, e) => {
callback(i, $(e)); callback(i, $(e));
}); });
}
static init() {
this.dispose();
this.each((i, e) => {
const $e = $(e),
id = `Carousel${i}`;
$e.attr('id', id);
$e.data('id', i);
const $items = $(e).find('.carousel-item'),
count = $items.length;
if (!count) {
return;
}
// create carousel-controls
if ($e.data('indicators')) {
const $indicators = $('<ol class="carousel-indicators"></ol>');
$indicators.append('<li data-target="#' + id + '" data-slide-to="0" class="active"></li>');
for (let i = 1; i < count; i++) {
$indicators.append('<li data-target="#' + id + '" data-slide-to="' + i + '"></li>');
}
$e.prepend($indicators);
}
// create arrows
if ($e.data('arrows')) {
$e.prepend('<i class="carousel-control-prev" data-target="#' + id + '" role="button" data-slide="prev"><i class="fas fa-chevron-left" aria-hidden="true"></i><i class="sr-only">Previous</i></i>');
$e.prepend('<i class="carousel-control-next" data-target="#' + id + '" role="button" data-slide="next"><i class="fas fa-chevron-right" aria-hidden="true"></i><i class="sr-only">Next</i></i>');
}
// init carousel
$e.carousel();
// init touch swipes
$e.hammer().bind('swipeleft', (event) => {
$(event.target).carousel('next');
});
$e.hammer().bind('swiperight', (event) => {
$(event.target).carousel('prev');
});
$e.hammer().bind('panleft', (event) => {
$(event.target).carousel('next');
});
$e.hammer().bind('panright', (event) => {
$(event.target).carousel('prev');
});
$e.hammer().bind('tap', (event) => {
$(event.target).carousel('next');
});
});
}
static dispose() {
this.each((i, e) => {
$(e).carousel('dispose');
});
}
} }
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { static init() {
CarouselUI.init(); this.dispose();
});
return CarouselUI; this.each((i, e) => {
const $e = $(e),
id = `Carousel${i}`;
$e.attr('id', id);
$e.data('id', i);
const $items = $(e).find('.carousel-item'),
count = $items.length;
if (!count) {
return;
}
// create carousel-controls
if ($e.data('indicators')) {
const $indicators = $('<ol class="carousel-indicators"></ol>');
$indicators.append(`<li data-target="#${ id }" data-slide-to="0" class="active"></li>`);
for (let i = 1; i < count; i++) {
$indicators.append(`<li data-target="#${ id }" data-slide-to="${ i }"></li>`);
}
$e.prepend($indicators);
}
// create arrows
if ($e.data('arrows')) {
$e.prepend(`<i class="carousel-control-prev" data-target="#${ id }" role="button" data-slide="prev"><i class="fas fa-chevron-left" aria-hidden="true"></i><i class="sr-only">Previous</i></i>`);
$e.prepend(`<i class="carousel-control-next" data-target="#${ id }" role="button" data-slide="next"><i class="fas fa-chevron-right" aria-hidden="true"></i><i class="sr-only">Next</i></i>`);
}
// init carousel
$e.carousel();
// init touch swipes
$e.hammer().bind('swipeleft', (event) => {
$(event.target).carousel('next');
});
$e.hammer().bind('swiperight', (event) => {
$(event.target).carousel('prev');
});
$e.hammer().bind('panleft', (event) => {
$(event.target).carousel('next');
});
$e.hammer().bind('panright', (event) => {
$(event.target).carousel('prev');
});
$e.hammer().bind('tap', (event) => {
$(event.target).carousel('next');
});
});
}
static dispose() {
this.each((i, e) => {
$(e).carousel('dispose');
});
}
}
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
CarouselUI.init();
});
return CarouselUI;
})($); })($);
export default CarouselUI; export default CarouselUI;

View File

@ -5,175 +5,175 @@ import Events from "../_events";
import SpinnerUI from './_ui.spinner'; import SpinnerUI from './_ui.spinner';
const FormBasics = (($) => { const FormBasics = (($) => {
// Constants // Constants
const NAME = 'jsFormBasics'; const NAME = 'jsFormBasics';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $('html, body');
class FormBasics { class FormBasics {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
ui._element = element; ui._element = element;
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
const $fields = $element.find('input,textarea,select'); const $fields = $element.find('input,textarea,select');
const $selectFields = $element.find('select:not([readonly])'); const $selectFields = $element.find('select:not([readonly])');
const $radioOptions = $element.find('input[type="radio"]'); const $radioOptions = $element.find('input[type="radio"]');
const separator = ', '; const separator = ', ';
$selectFields.each((i, el) => { $selectFields.each((i, el) => {
const $el = $(el); const $el = $(el);
const maxOptions = $el.data('max-options') || false; const maxOptions = $el.data('max-options') || false;
$el.selectpicker($.extend({ $el.selectpicker($.extend({
iconBase: 'fas', iconBase: 'fas',
tickIcon: 'fa-check', tickIcon: 'fa-check',
virtualScroll: false, virtualScroll: false,
dropupAuto: false, dropupAuto: false,
size: 10, size: 10,
maxOptions: maxOptions, maxOptions,
}, $el.data(), { }, $el.data(), {
multipleSeparator: separator, multipleSeparator: separator,
})); }));
// wrap options // wrap options
$el.on('rendered.bs.select', () => { $el.on('rendered.bs.select', () => {
if (!$el.val().length) { if (!$el.val().length) {
return true; return true;
} }
const $container = $el.parent().find('.filter-option-inner-inner'); const $container = $el.parent().find('.filter-option-inner-inner');
const val = $container.text(); const val = $container.text();
const vals = val.split(separator); const vals = val.split(separator);
let html = ''; let html = '';
vals.forEach((opt) => { vals.forEach((opt) => {
const $opt = $el.find('option').filter((i, e) => { const $opt = $el.find('option').filter((i, e) => {
return $(e).text() === opt; return $(e).text() === opt;
}); });
html += '<span class="option" data-val=' + $opt.attr('value') + '>' + opt + html += `<span class="option" data-val=${ $opt.attr('value') }>${ opt
' <i class="fas fa-times btn-remove"></i></span>'; } <i class="fas fa-times btn-remove"></i></span>`;
}); });
$container.html(html); $container.html(html);
// remove value // remove value
$container.find('.option').on('click', (e) => { $container.find('.option').on('click', (e) => {
e.preventDefault(); e.preventDefault();
const $opt = $(e.currentTarget); const $opt = $(e.currentTarget);
const val = $opt.data('val').toString(); const val = $opt.data('val').toString();
//$opt.remove(); //$opt.remove();
let vals = $el.selectpicker('val'); const vals = $el.selectpicker('val');
const i = vals.indexOf(val); const i = vals.indexOf(val);
if (i > -1) { if (i > -1) {
vals.splice(i, 1); vals.splice(i, 1);
$el.selectpicker('val', vals); $el.selectpicker('val', vals);
} }
}); });
}); });
// FIX: hidden picker // FIX: hidden picker
$el.selectpicker('render'); $el.selectpicker('render');
$el.selectpicker('refresh'); $el.selectpicker('refresh');
$el.selectpicker('toggle'); $el.selectpicker('toggle');
document.activeElement.blur(); document.activeElement.blur();
//$el.selectpicker('show'); //$el.selectpicker('show');
//$el.selectpicker('hide'); //$el.selectpicker('hide');
/*$el.parents('.field.dropdown').find('.dropdown-toggle').click(); /*$el.parents('.field.dropdown').find('.dropdown-toggle').click();
$el.parents('.field.dropdown').find('.dropdown-toggle').click(); $el.parents('.field.dropdown').find('.dropdown-toggle').click();
$el.parents('.field.dropdown').find('.dropdown-toggle').blur();*/ $el.parents('.field.dropdown').find('.dropdown-toggle').blur();*/
}); });
$fields.each((e, el) => { $fields.each((e, el) => {
const $el = $(el); const $el = $(el);
if ($el.hasClass('required') || $el.attr('aria-required')) { if ($el.hasClass('required') || $el.attr('aria-required')) {
$el.closest('.field').addClass('required'); $el.closest('.field').addClass('required');
}
});
$radioOptions.each((e, el) => {
const $el = $(el);
if ($el.is(':checked')) {
$el.parents('.radio').addClass('checked');
}
});
$radioOptions.on('change', (e) => {
const $el = $(e.currentTarget);
const $parent = $el.parents('.radio');
$parent.siblings('.radio').removeClass('checked');
if ($el.is(':checked')) {
$parent.addClass('checked');
}
});
$element.on('submit', (e) => {
SpinnerUI.show();
});
$element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_BASICS);
} }
});
// Public methods $radioOptions.each((e, el) => {
dispose() { const $el = $(el);
const $element = $(this._element);
$element.removeClass(`${NAME}-active`); if ($el.is(':checked')) {
$.removeData(this._element, DATA_KEY); $el.parents('.radio').addClass('checked');
this._element = null;
} }
});
static _jQueryInterface() { $radioOptions.on('change', (e) => {
return this.each(function() { const $el = $(e.currentTarget);
// attach functionality to element const $parent = $el.parents('.radio');
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) { $parent.siblings('.radio').removeClass('checked');
data = new FormBasics(this); if ($el.is(':checked')) {
$element.data(DATA_KEY, data); $parent.addClass('checked');
}
});
} }
});
$element.on('submit', (e) => {
SpinnerUI.show();
});
$element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_BASICS);
} }
// jQuery interface // Public methods
$.fn[NAME] = FormBasics._jQueryInterface; dispose() {
$.fn[NAME].Constructor = FormBasics; const $element = $(this._element);
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormBasics._jQueryInterface;
};
// auto-apply $element.removeClass(`${NAME}-active`);
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $.removeData(this._element, DATA_KEY);
$('form').each((i, el) => { this._element = null;
const $el = $(el); }
// skip some forms static _jQueryInterface() {
if ($el.hasClass('no-validation')) { return this.each(function() {
return true; // attach functionality to element
} const $element = $(this);
let data = $element.data(DATA_KEY);
$el.jsFormBasics(); if (!data) {
}); data = new FormBasics(this);
$element.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = FormBasics._jQueryInterface;
$.fn[NAME].Constructor = FormBasics;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormBasics._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('form').each((i, el) => {
const $el = $(el);
// skip some forms
if ($el.hasClass('no-validation')) {
return true;
}
$el.jsFormBasics();
}); });
});
return FormBasics; return FormBasics;
})($); })($);
export default FormBasics; export default FormBasics;

View File

@ -11,219 +11,219 @@ import 'exif-js/exif.js';
const CroppieUI = (($) => { const CroppieUI = (($) => {
const NAME = 'jsCroppieUI'; const NAME = 'jsCroppieUI';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const G = window; const G = window;
const D = document; const D = document;
const jqteOptions = { const jqteOptions = {
color: false, color: false,
fsize: false, fsize: false,
funit: 'em', funit: 'em',
format: false, format: false,
rule: false, rule: false,
source: false, source: false,
sub: false, sub: false,
sup: false, sup: false,
}; };
class CroppieUI { class CroppieUI {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $el = $(element); const $el = $(element);
ui.$el = $el; ui.$el = $el;
$el.data(DATA_KEY, this); $el.data(DATA_KEY, this);
ui.input = $el.find('input[type="file"]'); ui.input = $el.find('input[type="file"]');
//ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />'); //ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />');
ui.width = ui.input.data('width'); ui.width = ui.input.data('width');
ui.height = ui.input.data('height'); ui.height = ui.input.data('height');
$el.append( $el.append(
'<div class="cropper-wrap"><div class="cropper-container"></div>' + '<div class="cropper-wrap"><div class="cropper-container"></div>' +
'<a href="#" class="btn-remove"><i class="fas fa-times"></i> Remove</a></div>' '<a href="#" class="btn-remove"><i class="fas fa-times"></i> Remove</a></div>'
); );
//$el.append(ui.inputData); //$el.append(ui.inputData);
ui.uploadCropWrap = $el.find('.cropper-wrap'); ui.uploadCropWrap = $el.find('.cropper-wrap');
ui.uploadCrop = ui.uploadCropWrap.find('.cropper-container'); ui.uploadCrop = ui.uploadCropWrap.find('.cropper-container');
const ratio = ui.width / (ui.uploadCrop.width() - 32); const ratio = ui.width / (ui.uploadCrop.width() - 32);
ui.uploadCrop.croppie({ ui.uploadCrop.croppie({
enableExif: true, enableExif: true,
enforceBoundary: false, enforceBoundary: false,
viewport: { viewport: {
width: ui.width / ratio, width: ui.width / ratio,
height: ui.height / ratio, height: ui.height / ratio,
} },
}); });
ui.uploadCrop.hide(); ui.uploadCrop.hide();
ui.input.on('change', (e) => { ui.input.on('change', (e) => {
this.readFile(e.currentTarget); this.readFile(e.currentTarget);
}); });
$el.find('.btn-remove').on('click', (e) => { $el.find('.btn-remove').on('click', (e) => {
e.preventDefault(); e.preventDefault();
ui.uploadCrop.removeClass('ready'); ui.uploadCrop.removeClass('ready');
$el.find('.croppie-image').remove(); $el.find('.croppie-image').remove();
ui.$el.find('input[type="file"]').val(''); ui.$el.find('input[type="file"]').val('');
ui.$el.find('input[type="file"]').change(); ui.$el.find('input[type="file"]').change();
ui.uploadCropWrap.hide(); ui.uploadCropWrap.hide();
}); });
}
readFile(input) {
const ui = this;
const $el = ui.$el;
const $form = $el.closest('form');
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = (e) => {
ui.uploadCrop.addClass('ready');
ui.uploadCrop.croppie('bind', {
url: e.target.result,
});
ui.uploadCrop.show();
ui.uploadCropWrap.show();
} }
readFile(input) { reader.readAsDataURL(input.files[0]);
const ui = this;
const $el = ui.$el;
const $form = $el.closest('form');
if (input.files && input.files[0]) { $form.on('submit', (e) => {
const reader = new FileReader(); //$(input).val('');
SpinnerUI.show();
reader.onload = (e) => { if (!ui.uploadCrop.hasClass('ready')) {
ui.uploadCrop.addClass('ready'); return true;
ui.uploadCrop.croppie('bind', { }
url: e.target.result
});
ui.uploadCrop.show(); ui.uploadCrop.croppie('result', {
ui.uploadCropWrap.show(); type: 'blob',
size: {
width: ui.width,
height: ui.height,
},
format: 'png',
}).then((blob) => {
const form = e.currentTarget;
const data = new FormData(form);
const name = $(input).attr('name');
data.delete('BackURL');
data.delete(name);
data.append(name, blob, `${name }-image.png`);
data.append('ajax', '1');
if (!$(form).data('jsFormValidate').validate()) {
return false;
}
$.ajax({
url: $(form).attr('action'),
data,
processData: false,
contentType: false,
type: $(form).attr('method'),
success: function(data) {
let IS_JSON = false;
let json = {};
try {
IS_JSON = true;
json = $.parseJSON(data);
} catch (e) {
IS_JSON = false;
} }
reader.readAsDataURL(input.files[0]); if (IS_JSON) {
/*for (let k in json) {
$form.on('submit', (e) => {
//$(input).val('');
SpinnerUI.show();
if (!ui.uploadCrop.hasClass('ready')) {
return true;
}
ui.uploadCrop.croppie('result', {
type: 'blob',
size: {
width: ui.width,
height: ui.height
},
format: 'png'
}).then((blob) => {
const form = e.currentTarget;
const data = new FormData(form);
const name = $(input).attr('name');
data.delete('BackURL');
data.delete(name);
data.append(name, blob, name + '-image.png');
data.append('ajax', '1');
if (!$(form).data('jsFormValidate').validate()) {
return false;
}
$.ajax({
url: $(form).attr('action'),
data: data,
processData: false,
contentType: false,
type: $(form).attr('method'),
success: function(data) {
let IS_JSON = false;
let json = {};
try {
IS_JSON = true;
json = $.parseJSON(data);
} catch (e) {
IS_JSON = false;
}
if (IS_JSON) {
/*for (let k in json) {
$form.find('select[name="' + k + '"],input[name="' + k + '"],textarea[name="' + k + '"]').setError(true, json[k]); $form.find('select[name="' + k + '"],input[name="' + k + '"],textarea[name="' + k + '"]').setError(true, json[k]);
}*/ }*/
if (typeof json['status'] !== 'undefined') { if (typeof json['status'] !== 'undefined') {
if (json['status'] === 'success') { if (json['status'] === 'success') {
MainUI.alert(json['message'], json['status']); MainUI.alert(json['message'], json['status']);
if (typeof json['link'] !== 'undefined') { if (typeof json['link'] !== 'undefined') {
setTimeout(() => { setTimeout(() => {
G.location = json['link']; G.location = json['link'];
}, 2000); }, 2000);
} else { } else {
//G.location.reload(false); //G.location.reload(false);
} }
} else if (json['status'] === 'error') { } else if (json['status'] === 'error') {
MainUI.alert(json['message'], json['status']); MainUI.alert(json['message'], json['status']);
} }
} }
if (typeof json['form'] !== 'undefined') { if (typeof json['form'] !== 'undefined') {
$(form).replaceWith(json['form']); $(form).replaceWith(json['form']);
} }
} else { } else {
$(form).replaceWith(data); $(form).replaceWith(data);
//G.location.reload(false); //G.location.reload(false);
}
SpinnerUI.hide();
$(G).trigger(Events.AJAX);
}
});
//ui.inputData.val(data);
});
e.preventDefault();
});
} else {
console.log('Sorry - your browser doesn\'t support the FileReader API');
}
}
static dispose() {
console.log(`Destroying: ${NAME}`);
}
static _jQueryInterface() {
return this.each((i, el) => {
// attach functionality to element
const $el = $(el);
let data = $el.data(DATA_KEY);
if (!data) {
data = new CroppieUI(el);
$el.data(DATA_KEY, data);
} }
SpinnerUI.hide();
$(G).trigger(Events.AJAX);
},
}); });
}
//ui.inputData.val(data);
});
e.preventDefault();
});
} else {
console.log('Sorry - your browser doesn\'t support the FileReader API');
}
} }
// jQuery interface static dispose() {
$.fn[NAME] = CroppieUI._jQueryInterface; console.log(`Destroying: ${NAME}`);
$.fn[NAME].Constructor = CroppieUI; }
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return CroppieUI._jQueryInterface;
};
// auto-apply static _jQueryInterface() {
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { return this.each((i, el) => {
$('.field.croppie').jsCroppieUI(); // attach functionality to element
}); const $el = $(el);
let data = $el.data(DATA_KEY);
return CroppieUI; if (!data) {
data = new CroppieUI(el);
$el.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = CroppieUI._jQueryInterface;
$.fn[NAME].Constructor = CroppieUI;
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return CroppieUI._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('.field.croppie').jsCroppieUI();
});
return CroppieUI;
})($); })($);
export default CroppieUI; export default CroppieUI;

View File

@ -6,87 +6,87 @@ import 'bootstrap-datepicker/dist/js/bootstrap-datepicker.js';
import 'bootstrap-timepicker/js/bootstrap-timepicker.js'; import 'bootstrap-timepicker/js/bootstrap-timepicker.js';
const DatetimeUI = (($) => { const DatetimeUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const $Body = $('body'); const $Body = $('body');
const NAME = 'jsDatetimeUI'; const NAME = 'jsDatetimeUI';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const datepickerOptions = { const datepickerOptions = {
autoclose: true, autoclose: true,
startDate: 0, startDate: 0,
//todayBtn: true, //todayBtn: true,
todayHighlight: true, todayHighlight: true,
clearBtn: true, clearBtn: true,
}; };
class DatetimeUI { class DatetimeUI {
constructor(el) { constructor(el) {
const ui = this; const ui = this;
const $el = $(el); const $el = $(el);
ui._el = el; ui._el = el;
// datepicker // datepicker
if ($el.hasClass('date') || $el.attr('type') === 'date') { if ($el.hasClass('date') || $el.attr('type') === 'date') {
const defaultDate = ($el.attr('name').toLowerCase().indexOf('end') !== -1) ? const defaultDate = ($el.attr('name').toLowerCase().indexOf('end') !== -1) ?
'+4d' : '+4d' :
'+3d'; '+3d';
$el.attr('readonly', 'true'); $el.attr('readonly', 'true');
$el.datepicker($.extend(datepickerOptions, { $el.datepicker($.extend(datepickerOptions, {
defaultViewDate: defaultDate, defaultViewDate: defaultDate,
multidate: $el.data('multidate'), multidate: $el.data('multidate'),
})); }));
} else } else
// timepicker // timepicker
if ($el.hasClass('time') || $el.attr('type') === 'time') { if ($el.hasClass('time') || $el.attr('type') === 'time') {
$el.attr('readonly', 'true'); $el.attr('readonly', 'true');
$el.timepicker({ $el.timepicker({
defaultTime: $el.data('default-time'), defaultTime: $el.data('default-time'),
icons: { icons: {
up: 'fas fa-chevron-up', up: 'fas fa-chevron-up',
down: 'fas fa-chevron-down' down: 'fas fa-chevron-down',
} },
}); });
} }
}
static dispose() {
console.log(`Destroying: ${NAME}`);
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $el = $(this);
let data = $el.data(DATA_KEY);
if (!data) {
data = new DatetimeUI(this);
$el.data(DATA_KEY, data);
}
});
}
} }
// jQuery interface static dispose() {
$.fn[NAME] = DatetimeUI._jQueryInterface; console.log(`Destroying: ${NAME}`);
$.fn[NAME].Constructor = DatetimeUI; }
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return DatetimeUI._jQueryInterface;
};
// auto-apply static _jQueryInterface() {
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { return this.each(function() {
$('input.date, input.time,input[type="date"], input[type="time"]').jsDatetimeUI(); // attach functionality to element
}); const $el = $(this);
let data = $el.data(DATA_KEY);
return DatetimeUI; if (!data) {
data = new DatetimeUI(this);
$el.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = DatetimeUI._jQueryInterface;
$.fn[NAME].Constructor = DatetimeUI;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return DatetimeUI._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('input.date, input.time,input[type="date"], input[type="time"]').jsDatetimeUI();
});
return DatetimeUI;
})($); })($);
export default DatetimeUI; export default DatetimeUI;

View File

@ -10,71 +10,71 @@ import '../../thirdparty/jquery-te/jquery-te.js';
const JqteUI = (($) => { const JqteUI = (($) => {
const NAME = 'jsJqteUI'; const NAME = 'jsJqteUI';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const jqteOptions = { const jqteOptions = {
color: false, color: false,
fsize: false, fsize: false,
funit: 'em', funit: 'em',
format: false, format: false,
rule: false, rule: false,
source: false, source: false,
sub: false, sub: false,
sup: false, sup: false,
}; };
class JqteUI { class JqteUI {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
const validationUI = $element.data('jsFormValidateField'); const validationUI = $element.data('jsFormValidateField');
ui._element = element; ui._element = element;
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
$element.jqte(jqteOptions); $element.jqte(jqteOptions);
// dynamic error control // dynamic error control
if (validationUI) { if (validationUI) {
$element.parents('.jqte').find('.jqte_editor').on('change', (e) => { $element.parents('.jqte').find('.jqte_editor').on('change', (e) => {
validationUI.validate(); validationUI.validate();
}); });
} }
}
static dispose() {
console.log(`Destroying: ${NAME}`);
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new JqteUI(this);
$element.data(DATA_KEY, data);
}
});
}
} }
// jQuery interface static dispose() {
$.fn[NAME] = JqteUI._jQueryInterface; console.log(`Destroying: ${NAME}`);
$.fn[NAME].Constructor = JqteUI; }
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return JqteUI._jQueryInterface;
};
// auto-apply static _jQueryInterface() {
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { return this.each(function() {
$('textarea.jqte-field').jsJqteUI(); // attach functionality to element
}); const $element = $(this);
let data = $element.data(DATA_KEY);
return JqteUI; if (!data) {
data = new JqteUI(this);
$element.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = JqteUI._jQueryInterface;
$.fn[NAME].Constructor = JqteUI;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return JqteUI._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('textarea.jqte-field').jsJqteUI();
});
return JqteUI;
})($); })($);
export default JqteUI; export default JqteUI;

View File

@ -4,200 +4,200 @@ import LANG from '../lang/_en';
import FormValidateField from "./_ui.form.validate.field"; import FormValidateField from "./_ui.form.validate.field";
const SteppedForm = (($) => { const SteppedForm = (($) => {
// Constants // Constants
const NAME = 'jsSteppedForm'; const NAME = 'jsSteppedForm';
const DATA_KEY = NAME; const DATA_KEY = NAME;
class SteppedForm { class SteppedForm {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
if (!$element.find('.steps-counter').length) { if (!$element.find('.steps-counter').length) {
$element.prepend(LANG['en'][NAME]['STEPCOUNTER']); $element.prepend(LANG['en'][NAME]['STEPCOUNTER']);
} }
if (!$element.find('.steps-buttons').length) { if (!$element.find('.steps-buttons').length) {
$element.append(LANG['en'][NAME]['STEPBUTTONS']); $element.append(LANG['en'][NAME]['STEPBUTTONS']);
} }
ui._currentStepCounter = $element.find('.steps-counter .current-step'); ui._currentStepCounter = $element.find('.steps-counter .current-step');
ui._totalStepsCounter = $element.find('.steps-counter .total-steps'); ui._totalStepsCounter = $element.find('.steps-counter .total-steps');
ui._steps = $element.find('.step'); ui._steps = $element.find('.step');
ui._stepNext = $element.find('.step-next'); ui._stepNext = $element.find('.step-next');
ui._stepPrev = $element.find('.step-prev'); ui._stepPrev = $element.find('.step-prev');
ui._actions = $element.children('.btn-toolbar,.form-actions'); ui._actions = $element.children('.btn-toolbar,.form-actions');
ui._element = element; ui._element = element;
ui._currentStep = 1; ui._currentStep = 1;
ui._totalSteps = ui._steps.last().data('step') || ui._steps.length; ui._totalSteps = ui._steps.last().data('step') || ui._steps.length;
ui._stepsOrder = []; ui._stepsOrder = [];
ui._totalStepsCounter.text(ui._totalSteps); ui._totalStepsCounter.text(ui._totalSteps);
// check if one of the steps already has an error // check if one of the steps already has an error
const $hasError = ui._steps const $hasError = ui._steps
.find('.field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good') .find('.field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good')
.first(); .first();
if ($hasError.length) { if ($hasError.length) {
const $modal = $element.parents('.modal'); const $modal = $element.parents('.modal');
// show modal // show modal
if ($modal.length && typeof $modal.modal !== 'undefined') { if ($modal.length && typeof $modal.modal !== 'undefined') {
$modal.modal('show'); $modal.modal('show');
}
ui._currentStep = $hasError.parents('.step').data('step') || ui._currentStep;
}
//
ui.step('.step[data-step="' + ui._currentStep + '"]');
ui._stepNext.on('click', (e) => {
e.preventDefault();
ui.next();
});
ui._stepPrev.on('click', (e) => {
e.preventDefault();
ui.prev();
});
$element.find('.step-toggle').on('click', (e) => {
const $el = $(e.currentTarget);
e.preventDefault();
ui.step($el.data('target'));
});
$element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_STEPPED);
} }
// Public methods ui._currentStep = $hasError.parents('.step').data('step') || ui._currentStep;
dispose() { }
const ui = this; //
const $element = $(ui._element);
$element.removeClass(`${NAME}-active`); ui.step(`.step[data-step="${ ui._currentStep }"]`);
$.removeData(ui._element, DATA_KEY);
ui._element = null;
}
next() { ui._stepNext.on('click', (e) => {
const ui = this; e.preventDefault();
ui.next();
});
if (ui._currentStep >= ui._totalSteps) { ui._stepPrev.on('click', (e) => {
return; e.preventDefault();
} ui.prev();
});
ui.step('.step[data-step="' + (ui._currentStep + 1) + '"]'); $element.find('.step-toggle').on('click', (e) => {
} const $el = $(e.currentTarget);
prev() { e.preventDefault();
const ui = this; ui.step($el.data('target'));
});
if (ui._currentStep <= 1) { $element.addClass(`${NAME}-active`);
return; $element.trigger(Events.FORM_INIT_STEPPED);
}
ui.step(ui._stepsOrder[ui._currentStep - 1]);
}
step(target) {
const ui = this;
const $element = $(ui._element);
const $target = $element.find(target);
const targetStep = parseInt($target.data('step'));
// validate current step
let valid = true;
if (targetStep > ui._currentStep) {
ui.currentStep().find('input,textarea,select').each((i, el) => {
const $el = $(el);
const fieldUI = $el.data('jsFormValidateField');
if (fieldUI && !fieldUI.validate()) {
valid = false;
}
});
}
if (!valid) {
return false;
}
//
if (parseInt($target.data('step')) <= '1') {
ui._stepPrev.hide();
$element.trigger(Events.FORM_STEPPED_FIRST_STEP);
} else {
ui._stepPrev.show();
}
if (parseInt($target.data('step')) >= ui._totalSteps) {
ui._stepNext.hide();
ui._actions.show();
$element.trigger(Events.FORM_STEPPED_LAST_STEP);
} else {
ui._stepNext.show();
ui._actions.hide();
}
ui._currentStep = targetStep;
ui._stepsOrder[ui._currentStep] = $target;
ui._steps.removeClass('active');
$target.addClass('active');
ui._currentStepCounter.text(ui._currentStep);
$target.trigger(Events.FORM_STEPPED_NEW_STEP);
$element.trigger(Events.FORM_STEPPED_NEW_STEP);
}
currentStep() {
const ui = this;
const $element = $(ui._element);
return $element.find('.step.active');
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new SteppedForm(this);
$element.data(DATA_KEY, data);
}
});
}
} }
// jQuery interface // Public methods
$.fn[NAME] = SteppedForm._jQueryInterface; dispose() {
$.fn[NAME].Constructor = SteppedForm; const ui = this;
$.fn[NAME].noConflict = function() { const $element = $(ui._element);
$.fn[NAME] = JQUERY_NO_CONFLICT;
return SteppedForm._jQueryInterface;
};
// auto-apply $element.removeClass(`${NAME}-active`);
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $.removeData(ui._element, DATA_KEY);
$('.form-stepped').jsSteppedForm(); ui._element = null;
}); }
return SteppedForm; next() {
const ui = this;
if (ui._currentStep >= ui._totalSteps) {
return;
}
ui.step(`.step[data-step="${ ui._currentStep + 1 }"]`);
}
prev() {
const ui = this;
if (ui._currentStep <= 1) {
return;
}
ui.step(ui._stepsOrder[ui._currentStep - 1]);
}
step(target) {
const ui = this;
const $element = $(ui._element);
const $target = $element.find(target);
const targetStep = parseInt($target.data('step'));
// validate current step
let valid = true;
if (targetStep > ui._currentStep) {
ui.currentStep().find('input,textarea,select').each((i, el) => {
const $el = $(el);
const fieldUI = $el.data('jsFormValidateField');
if (fieldUI && !fieldUI.validate()) {
valid = false;
}
});
}
if (!valid) {
return false;
}
//
if (parseInt($target.data('step')) <= '1') {
ui._stepPrev.hide();
$element.trigger(Events.FORM_STEPPED_FIRST_STEP);
} else {
ui._stepPrev.show();
}
if (parseInt($target.data('step')) >= ui._totalSteps) {
ui._stepNext.hide();
ui._actions.show();
$element.trigger(Events.FORM_STEPPED_LAST_STEP);
} else {
ui._stepNext.show();
ui._actions.hide();
}
ui._currentStep = targetStep;
ui._stepsOrder[ui._currentStep] = $target;
ui._steps.removeClass('active');
$target.addClass('active');
ui._currentStepCounter.text(ui._currentStep);
$target.trigger(Events.FORM_STEPPED_NEW_STEP);
$element.trigger(Events.FORM_STEPPED_NEW_STEP);
}
currentStep() {
const ui = this;
const $element = $(ui._element);
return $element.find('.step.active');
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new SteppedForm(this);
$element.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = SteppedForm._jQueryInterface;
$.fn[NAME].Constructor = SteppedForm;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return SteppedForm._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('.form-stepped').jsSteppedForm();
});
return SteppedForm;
})($); })($);
export default SteppedForm; export default SteppedForm;

View File

@ -2,147 +2,147 @@ import $ from 'jquery';
import Events from "../_events"; import Events from "../_events";
const FormStorage = (($) => { const FormStorage = (($) => {
// Constants // Constants
const NAME = 'jsFormStorage'; const NAME = 'jsFormStorage';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const STORAGE = window.localStorage; const STORAGE = window.localStorage;
class FormStorage { class FormStorage {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
const $elements = $element.find('input, textarea, select'); const $elements = $element.find('input, textarea, select');
const setRangeValues = function(el) { const setRangeValues = function(el) {
let $el = $(el); const $el = $(el);
$el.siblings('.value').text($el.val()); $el.siblings('.value').text($el.val());
}; };
ui._element = element; ui._element = element;
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
// restore form data from localStorage // restore form data from localStorage
$elements.each((i, el) => { $elements.each((i, el) => {
const $el = $(el); const $el = $(el);
const id = $el.attr('id'); const id = $el.attr('id');
const type = $el.attr('type'); const type = $el.attr('type');
const val = STORAGE.getItem(NAME + id); const val = STORAGE.getItem(NAME + id);
if (type === 'file') { if (type === 'file') {
return true; return true;
}
if (id && val && type) {
if (type && (type === 'checkbox' || type === 'radio')) {
$el.prop('checked', val);
} else {
$el.val(val);
}
}
$el.trigger(Events.RESTORE_FIELD);
});
// range fields
$('input[type="range"]').each((i, el) => {
setRangeValues(el);
});
$element.trigger(Events.RESTORE_FIELD);
$('input[type="range"]').on('change', (e) => {
setRangeValues(e.currentTarget);
});
// store form data into localStorage
$elements.on('change', (e) => {
const $el = $(e.currentTarget);
const id = $el.attr('id');
const type = $el.attr('type');
// skip some elements
if ($el.hasClass('no-storage')) {
return true;
}
let val = $el.val();
if (type && (type === 'checkbox' || type === 'radio')) {
val = !!$el.is(':checked');
}
if (id && type && type !== 'password') {
STORAGE.setItem(NAME + id, val);
}
});
$element.on('submit', () => {
$element.data(DATA_KEY).clear();
});
$element.find('button,[type="submit"],[type="clear"]').on('click', () => {
$element.data(DATA_KEY).clear();
});
$element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_STORAGE);
} }
// Public methods if (id && val && type) {
dispose() { if (type && (type === 'checkbox' || type === 'radio')) {
const $element = $(this._element); $el.prop('checked', val);
} else {
$element.removeClass(`${NAME}-active`); $el.val(val);
$.removeData(this._element, DATA_KEY); }
this._element = null;
} }
clear() { $el.trigger(Events.RESTORE_FIELD);
STORAGE.clear(); });
// range fields
$('input[type="range"]').each((i, el) => {
setRangeValues(el);
});
$element.trigger(Events.RESTORE_FIELD);
$('input[type="range"]').on('change', (e) => {
setRangeValues(e.currentTarget);
});
// store form data into localStorage
$elements.on('change', (e) => {
const $el = $(e.currentTarget);
const id = $el.attr('id');
const type = $el.attr('type');
// skip some elements
if ($el.hasClass('no-storage')) {
return true;
} }
static _jQueryInterface() { let val = $el.val();
if (typeof window.localStorage !== 'undefined') {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) { if (type && (type === 'checkbox' || type === 'radio')) {
data = new FormStorage(this); val = !!$el.is(':checked');
$element.data(DATA_KEY, data);
}
});
}
} }
if (id && type && type !== 'password') {
STORAGE.setItem(NAME + id, val);
}
});
$element.on('submit', () => {
$element.data(DATA_KEY).clear();
});
$element.find('button,[type="submit"],[type="clear"]').on('click', () => {
$element.data(DATA_KEY).clear();
});
$element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_STORAGE);
} }
// jQuery interface // Public methods
$.fn[NAME] = FormStorage._jQueryInterface; dispose() {
$.fn[NAME].Constructor = FormStorage; const $element = $(this._element);
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormStorage._jQueryInterface;
};
// auto-apply $element.removeClass(`${NAME}-active`);
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $.removeData(this._element, DATA_KEY);
$('form').each((i, el) => { this._element = null;
const $el = $(el); }
// skip some forms clear() {
if ($el.hasClass('no-storage')) { STORAGE.clear();
return true; }
}
$el.jsFormStorage(); static _jQueryInterface() {
if (typeof window.localStorage !== 'undefined') {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new FormStorage(this);
$element.data(DATA_KEY, data);
}
}); });
}); }
}
}
return FormStorage; // jQuery interface
$.fn[NAME] = FormStorage._jQueryInterface;
$.fn[NAME].Constructor = FormStorage;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormStorage._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('form').each((i, el) => {
const $el = $(el);
// skip some forms
if ($el.hasClass('no-storage')) {
return true;
}
$el.jsFormStorage();
});
});
return FormStorage;
})($); })($);
export default FormStorage; export default FormStorage;

View File

@ -2,141 +2,141 @@ import $ from 'jquery';
import Events from "../_events"; import Events from "../_events";
const FormValidateField = (($) => { const FormValidateField = (($) => {
// Constants // Constants
const NAME = 'jsFormValidateField'; const NAME = 'jsFormValidateField';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $('html, body');
class FormValidateField { class FormValidateField {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
ui._element = element; ui._element = element;
ui._actions = $element.parents('form').children('.btn-toolbar,.form-actions'); ui._actions = $element.parents('form').children('.btn-toolbar,.form-actions');
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
// prevent browsers checks (will do it using JS) // prevent browsers checks (will do it using JS)
$element.attr('novalidate', 'novalidate'); $element.attr('novalidate', 'novalidate');
$element.on('change', (e) => { $element.on('change', (e) => {
ui.validate(false); ui.validate(false);
}); });
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_VALIDATE_FIELD); $element.trigger(Events.FORM_INIT_VALIDATE_FIELD);
} }
// Public methods // Public methods
dispose() { dispose() {
const $element = $(this._element); const $element = $(this._element);
$element.removeClass(`${NAME}-active`); $element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY); $.removeData(this._element, DATA_KEY);
this._element = null; this._element = null;
} }
validate(scrollTo = true) { validate(scrollTo = true) {
const ui = this; const ui = this;
const $el = $(ui._element); const $el = $(ui._element);
const $field = $el.closest('.field'); const $field = $el.closest('.field');
const extraChecks = $el.data(`${NAME}-extra`); const extraChecks = $el.data(`${NAME}-extra`);
let valid = true; let valid = true;
let msg = null; let msg = null;
// browser checks + required // browser checks + required
if (!ui._element.checkValidity() || if (!ui._element.checkValidity() ||
($el.hasClass('required') && !$el.val().trim().length) ($el.hasClass('required') && !$el.val().trim().length)
) { ) {
valid = false; valid = false;
} }
// validate URL // validate URL
if ($el.hasClass('url') && $el.val().trim().length && !this.valideURL($el.val())) { if ($el.hasClass('url') && $el.val().trim().length && !this.valideURL($el.val())) {
valid = false; valid = false;
msg = 'URL must start with http:// or https://. For example: https://your-domain.com/'; msg = 'URL must start with http:// or https://. For example: https://your-domain.com/';
} }
// extra checks // extra checks
if (extraChecks) { if (extraChecks) {
extraChecks.forEach((check) => { extraChecks.forEach((check) => {
valid = valid && check(); valid = valid && check();
}); });
} }
this.removeError(); this.removeError();
if (valid) { if (valid) {
return true; return true;
} }
setTimeout(() => { setTimeout(() => {
this.setError(scrollTo, msg); this.setError(scrollTo, msg);
}, 500); }, 500);
return false; return false;
} }
valideURL(str) { valideURL(str) {
const pattern = new RegExp('^(https?:\\/\\/){1}' + // protocol const pattern = new RegExp('^(https?:\\/\\/){1}' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
return pattern.test(str); return pattern.test(str);
}
setError(scrollTo = true, msg = null) {
const ui = this;
const $field = $(ui._element).closest('.field');
const pos = $field.offset().top;
$field.addClass('error');
if (msg) {
$field.append('<div class="message alert alert-error alert-danger">' + msg + '</div>');
}
if (scrollTo) {
$field.focus();
$Html.scrollTop(pos - 100);
}
}
removeError() {
const ui = this;
const $field = $(ui._element).closest('.field');
$field.removeClass('error');
$field.removeClass('holder-error');
$field.removeClass('holder-validation');
$field.find('.message').remove();
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new FormValidateField(this);
$element.data(DATA_KEY, data);
}
});
}
} }
// jQuery interface setError(scrollTo = true, msg = null) {
$.fn[NAME] = FormValidateField._jQueryInterface; const ui = this;
$.fn[NAME].Constructor = FormValidateField; const $field = $(ui._element).closest('.field');
$.fn[NAME].noConflict = function() { const pos = $field.offset().top;
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormValidateField._jQueryInterface;
};
return FormValidateField; $field.addClass('error');
if (msg) {
$field.append(`<div class="message alert alert-error alert-danger">${ msg }</div>`);
}
if (scrollTo) {
$field.focus();
$Html.scrollTop(pos - 100);
}
}
removeError() {
const ui = this;
const $field = $(ui._element).closest('.field');
$field.removeClass('error');
$field.removeClass('holder-error');
$field.removeClass('holder-validation');
$field.find('.message').remove();
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new FormValidateField(this);
$element.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = FormValidateField._jQueryInterface;
$.fn[NAME].Constructor = FormValidateField;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormValidateField._jQueryInterface;
};
return FormValidateField;
})($); })($);
export default FormValidateField; export default FormValidateField;

View File

@ -4,128 +4,128 @@ import FormValidateField from "./_ui.form.validate.field";
import SpinnerUI from './_ui.spinner'; import SpinnerUI from './_ui.spinner';
const FormValidate = (($) => { const FormValidate = (($) => {
// Constants // Constants
const NAME = 'jsFormValidate'; const NAME = 'jsFormValidate';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $('html, body');
class FormValidate { class FormValidate {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
const $fields = $element.find('input,textarea,select'); const $fields = $element.find('input,textarea,select');
ui._element = element; ui._element = element;
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
ui._fields = $fields; ui._fields = $fields;
ui._stepped_form = $element.data('jsSteppedForm'); ui._stepped_form = $element.data('jsSteppedForm');
// prevent browsers checks (will do it using JS) // prevent browsers checks (will do it using JS)
$element.attr('novalidate', 'novalidate'); $element.attr('novalidate', 'novalidate');
$element.on(Events.FORM_INIT_STEPPED, () => { $element.on(Events.FORM_INIT_STEPPED, () => {
ui._stepped_form = $element.data('jsSteppedForm'); ui._stepped_form = $element.data('jsSteppedForm');
}); });
// init fields validation // init fields validation
$fields.each((i, el) => { $fields.each((i, el) => {
new FormValidateField(el); new FormValidateField(el);
}); });
// check form // check form
$element.on('submit', (e) => { $element.on('submit', (e) => {
ui.validate(true, () => { ui.validate(true, () => {
e.preventDefault(); e.preventDefault();
// switch to step // switch to step
if (ui._stepped_form) { if (ui._stepped_form) {
const $el = $element.find('.error').first(); const $el = $element.find('.error').first();
if ($el.length) { if ($el.length) {
ui._stepped_form.step($el.parents('.step')); ui._stepped_form.step($el.parents('.step'));
} }
} }
$element.trigger(Events.FORM_VALIDATION_FAILED); $element.trigger(Events.FORM_VALIDATION_FAILED);
}); });
}); });
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
$element.trigger(Events.FORM_INIT_VALIDATE); $element.trigger(Events.FORM_INIT_VALIDATE);
}
// Public methods
dispose() {
const $element = $(this._element);
$element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
}
validate(scrollTo = true, badCallback = false) {
console.log('Checking the form ...');
const ui = this;
let valid = true;
ui._fields.each(function(i, el) {
const $el = $(el);
const fieldUI = $el.data('jsFormValidateField');
if (fieldUI && !fieldUI.validate()) {
if (badCallback) {
badCallback();
}
console.log('Invalid form data');
SpinnerUI.hide();
valid = false;
return false;
}
});
return valid;
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new FormValidate(this);
$element.data(DATA_KEY, data);
}
});
}
} }
// jQuery interface // Public methods
$.fn[NAME] = FormValidate._jQueryInterface; dispose() {
$.fn[NAME].Constructor = FormValidate; const $element = $(this._element);
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormValidate._jQueryInterface;
};
// auto-apply $element.removeClass(`${NAME}-active`);
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $.removeData(this._element, DATA_KEY);
$('form').each((i, el) => { this._element = null;
const $el = $(el); }
// skip some forms validate(scrollTo = true, badCallback = false) {
if ($el.hasClass('no-validation')) { console.log('Checking the form ...');
return true; const ui = this;
} let valid = true;
$el.jsFormValidate(); ui._fields.each((i, el) => {
}); const $el = $(el);
const fieldUI = $el.data('jsFormValidateField');
if (fieldUI && !fieldUI.validate()) {
if (badCallback) {
badCallback();
}
console.log('Invalid form data');
SpinnerUI.hide();
valid = false;
return false;
}
});
return valid;
}
static _jQueryInterface() {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new FormValidate(this);
$element.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = FormValidate._jQueryInterface;
$.fn[NAME].Constructor = FormValidate;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return FormValidate._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('form').each((i, el) => {
const $el = $(el);
// skip some forms
if ($el.hasClass('no-validation')) {
return true;
}
$el.jsFormValidate();
}); });
});
return FormValidate; return FormValidate;
})($); })($);
export default FormValidate; export default FormValidate;

View File

@ -10,43 +10,43 @@ import "../../scss/_components/_ui.map.scss";
const W = window; const W = window;
const MapAPI = (($) => { const MapAPI = (($) => {
const STORAGE = W.localStorage; const STORAGE = W.localStorage;
// Constants // Constants
const NAME = 'jsMapAPI'; const NAME = 'jsMapAPI';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $BODY = $('body'); const $BODY = $('body');
let Map; let Map;
let currentStyle; let currentStyle;
class MapAPI { class MapAPI {
// Constructor // Constructor
constructor(element) { constructor(element) {
this._element = element; this._element = element;
const $element = $(this._element); const $element = $(this._element);
const geojson = $element.data('geojson'); const geojson = $element.data('geojson');
const center = [ const center = [
($element.data('lng') ? $element.data('lng') : $BODY.data('default-lng')), ($element.data('lng') ? $element.data('lng') : $BODY.data('default-lng')),
($element.data('lat') ? $element.data('lat') : $BODY.data('default-lat')), ($element.data('lat') ? $element.data('lat') : $BODY.data('default-lat')),
]; ];
const popup = new mapboxgl.Popup({ const popup = new mapboxgl.Popup({
closeOnClick: false, closeOnClick: false,
className: 'popup' className: 'popup',
}); });
currentStyle = this.getStyle(); currentStyle = this.getStyle();
mapBoxGL.accessToken = $element.data('key'); mapBoxGL.accessToken = $element.data('key');
Map = new mapBoxGL.Map({ Map = new mapBoxGL.Map({
'container': $element.find('.mapAPI-map')[0], 'container': $element.find('.mapAPI-map')[0],
'center': center, center,
//hash: true, //hash: true,
'style': currentStyle, 'style': currentStyle,
//localIdeographFontFamily: $BODY.css('font-family'), //localIdeographFontFamily: $BODY.css('font-family'),
'zoom': ($element.data('map-zoom') ? $element.data('map-zoom') : 10), 'zoom': ($element.data('map-zoom') ? $element.data('map-zoom') : 10),
'attributionControl': false 'attributionControl': false,
/*transformRequest: (url, resourceType)=> { /*transformRequest: (url, resourceType)=> {
if(resourceType === 'Source' && url.startsWith('http://myHost')) { if(resourceType === 'Source' && url.startsWith('http://myHost')) {
return { return {
url: url.replace('http', 'https'), url: url.replace('http', 'https'),
@ -55,49 +55,49 @@ const MapAPI = (($) => {
} }
} }
}*/ }*/
}) })
.addControl(new mapBoxGL.AttributionControl({ .addControl(new mapBoxGL.AttributionControl({
compact: true compact: true,
})) }))
.addControl(new mapBoxGL.NavigationControl(), 'top-right') .addControl(new mapBoxGL.NavigationControl(), 'top-right')
.addControl(new mapBoxGL.GeolocateControl({ .addControl(new mapBoxGL.GeolocateControl({
positionOptions: { positionOptions: {
enableHighAccuracy: true, enableHighAccuracy: true,
}, },
trackUserLocation: true, trackUserLocation: true,
}), 'bottom-right') }), 'bottom-right')
.addControl(new mapboxgl.ScaleControl({ .addControl(new mapboxgl.ScaleControl({
maxWidth: 80, maxWidth: 80,
unit: 'metric' unit: 'metric',
}), 'top-left'); }), 'top-left');
// event.target // event.target
Map.on('load', (e) => { Map.on('load', (e) => {
// add markers to map // add markers to map
geojson.features.forEach(function(marker) { geojson.features.forEach((marker) => {
// create a DOM element for the marker // create a DOM element for the marker
const $el = $('<div class="marker">' + marker.icon + '</div>'); const $el = $(`<div class="marker">${ marker.icon }</div>`);
$el.on('click', function() { $el.on('click', () => {
console.log('Marker click'); console.log('Marker click');
const coordinates = marker.geometry.coordinates; const coordinates = marker.geometry.coordinates;
const content = marker.properties.content; const content = marker.properties.content;
console.log(popup); console.log(popup);
popup.setLngLat(coordinates) popup.setLngLat(coordinates)
.setHTML(content) .setHTML(content)
.addTo(Map); .addTo(Map);
}); });
// add marker to map // add marker to map
new mapboxgl.Marker($el[0]) new mapboxgl.Marker($el[0])
.setLngLat(marker.geometry.coordinates) .setLngLat(marker.geometry.coordinates)
.addTo(Map); .addTo(Map);
}); });
console.log('Map is loaded'); console.log('Map is loaded');
}); });
/*Map.on('render',function(event){ /*Map.on('render',function(event){
console.log('map moved'); console.log('map moved');
console.log(event); console.log(event);
}); });
@ -114,75 +114,75 @@ const MapAPI = (($) => {
//console.log(event); //console.log(event);
});*/ });*/
// check time every 60 mins and change to night style // check time every 60 mins and change to night style
const api = this; const api = this;
setInterval(() => { setInterval(() => {
const newStyle = api.getStyle(); const newStyle = api.getStyle();
if (newStyle !== currentStyle) { if (newStyle !== currentStyle) {
Map.setStyle(api.getStyle()); Map.setStyle(api.getStyle());
}
}, 36000);
$element.addClass(`${NAME}-active`);
} }
}, 36000);
// Public methods
getMap() {
return Map;
}
getStyle() { $element.addClass(`${NAME}-active`);
return 'mapbox://styles/mapbox/streets-v9';
const hour = new Date().getHours();
if (hour < 6 || hour > 18) {
// night
//return 'mapbox://styles/mapbox/streets-v7';
return 'mapbox://styles/tony-air/cjeacwih92iu42rpd8tcmuyb2';
} else {
// day
return 'mapbox://styles/mapbox/streets-v9';
}
}
dispose() {
const $element = $(this._element);
$element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
}
static _jQueryInterface() {
if (typeof W.localStorage !== 'undefined') {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new MapAPI(this);
$element.data(DATA_KEY, data);
}
});
}
}
} }
// jQuery interface // Public methods
$.fn[NAME] = MapAPI._jQueryInterface; getMap() {
$.fn[NAME].Constructor = MapAPI; return Map;
$.fn[NAME].noConflict = function() { }
$.fn[NAME] = JQUERY_NO_CONFLICT;
return MapAPI._jQueryInterface;
};
// auto-apply getStyle() {
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => { return 'mapbox://styles/mapbox/streets-v9';
$('.mapAPI-map-container').jsMapAPI(); const hour = new Date().getHours();
}); if (hour < 6 || hour > 18) {
// night
//return 'mapbox://styles/mapbox/streets-v7';
return 'mapbox://styles/tony-air/cjeacwih92iu42rpd8tcmuyb2';
} else {
// day
return 'mapbox://styles/mapbox/streets-v9';
}
}
return MapAPI; dispose() {
const $element = $(this._element);
$element.removeClass(`${NAME}-active`);
$.removeData(this._element, DATA_KEY);
this._element = null;
}
static _jQueryInterface() {
if (typeof W.localStorage !== 'undefined') {
return this.each(function() {
// attach functionality to element
const $element = $(this);
let data = $element.data(DATA_KEY);
if (!data) {
data = new MapAPI(this);
$element.data(DATA_KEY, data);
}
});
}
}
}
// jQuery interface
$.fn[NAME] = MapAPI._jQueryInterface;
$.fn[NAME].Constructor = MapAPI;
$.fn[NAME].noConflict = function() {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return MapAPI._jQueryInterface;
};
// auto-apply
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('.mapAPI-map-container').jsMapAPI();
});
return MapAPI;
})($); })($);
export default MapAPI; export default MapAPI;

View File

@ -3,70 +3,70 @@ import Events from '../_events';
import Spinner from './_ui.spinner'; import Spinner from './_ui.spinner';
const NoCaptcha = (($) => { const NoCaptcha = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const $Body = $('body'); const $Body = $('body');
const NAME = 'NoCaptcha'; const NAME = 'NoCaptcha';
class NoCaptcha { class NoCaptcha {
static init() { static init() {
const ui = this; const ui = this;
ui.dispose(); ui.dispose();
console.log(`Initializing: ${NAME}`); console.log(`Initializing: ${NAME}`);
this.renderCaptcha(); this.renderCaptcha();
}
static dispose() {
console.log(`Destroying: ${NAME}`);
}
static renderCaptcha() {
console.log(`Rendering Captcha: ${NAME}`);
if (typeof grecaptcha === 'undefined') {
console.log('Captcha API isn\'t available yet');
}
const $_noCaptchaFields = $('.g-recaptcha');
const submitListener = (e) => {
e.preventDefault();
grecaptcha.execute();
};
$_noCaptchaFields.each((i, field) => {
const $field = $(field);
if ($field.data('widgetid')) {
return;
}
const $form = $field.data('form') ? $('#' + $field.data('form')) : $field.parents('form');
//For the invisible captcha we need to setup some callback listeners
if ($field.data('size') === 'invisible' && !$field.data('callback')) {
$form.on('submit', submitListener);
}
const widget_id = grecaptcha.render(field, $field.data());
$field.data('widgetid', widget_id);
});
}
} }
$(W).on(`${Events.AJAX}`, () => { static dispose() {
NoCaptcha.init(); console.log(`Destroying: ${NAME}`);
}); }
W.NoCaptcha = NoCaptcha; static renderCaptcha() {
W.noCaptchaFieldRender = NoCaptcha.renderCaptcha; console.log(`Rendering Captcha: ${NAME}`);
return NoCaptcha; if (typeof grecaptcha === 'undefined') {
console.log('Captcha API isn\'t available yet');
}
const $_noCaptchaFields = $('.g-recaptcha');
const submitListener = (e) => {
e.preventDefault();
grecaptcha.execute();
};
$_noCaptchaFields.each((i, field) => {
const $field = $(field);
if ($field.data('widgetid')) {
return;
}
const $form = $field.data('form') ? $(`#${ $field.data('form')}`) : $field.parents('form');
//For the invisible captcha we need to setup some callback listeners
if ($field.data('size') === 'invisible' && !$field.data('callback')) {
$form.on('submit', submitListener);
}
const widget_id = grecaptcha.render(field, $field.data());
$field.data('widgetid', widget_id);
});
}
}
$(W).on(`${Events.AJAX}`, () => {
NoCaptcha.init();
});
W.NoCaptcha = NoCaptcha;
W.noCaptchaFieldRender = NoCaptcha.renderCaptcha;
return NoCaptcha;
})($); })($);
export default NoCaptcha; export default NoCaptcha;

View File

@ -3,106 +3,106 @@ import $ from 'jquery';
import Events from '../_events'; import Events from '../_events';
const OpeningHoursUI = (($) => { const OpeningHoursUI = (($) => {
// Constants // Constants
const NAME = 'OpeningHoursUI'; const NAME = 'OpeningHoursUI';
class OpeningHoursUI { class OpeningHoursUI {
// Static methods // Static methods
static each(callback) { static each(callback) {
$('.js-opening-hours').each(function(i, e) { $('.js-opening-hours').each((i, e) => {
callback(i, $(e)); callback(i, $(e));
}); });
}
static init() {
this.dispose();
const hours = $.parseJSON($('.oppening-hours-json').html());
const date = new Date();
const dateYMD = this.Date_toYMD(date);
const weekday = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
];
const today = weekday[date.getDay()];
let html = '<b class="opening-hours-status opening-hours-status-closed">Closed today</b>';
if (
typeof hours['days'] !== 'undefined' &&
typeof hours['days'][today] !== 'undefined' &&
hours['days'][today].length
) {
html = 'Open today ';
$.each(hours['days'][today], (i, v) => {
if (v['DisplayStart'] || v['DisplayEnd']) {
if (
(
v['DisplayStart'] && v['DisplayStart'] <= dateYMD &&
v['DisplayEnd'] && v['DisplayEnd'] >= dateYMD
) ||
(v['DisplayStart'] && v['DisplayStart'] <= dateYMD && !v['DisplayEnd']) ||
(v['DisplayEnd'] && v['DisplayEnd'] >= dateYMD && !v['DisplayStart'])
) {
html = 'Open today from ' + v['From'] + ' to ' + v['Till'];
return false;
}
} else {
if (i > 0) {
html += ', <br/>';
}
html += 'from ' + v['From'] + ' to ' + v['Till'];
}
});
html += ' <b class="opening-hours-status"></b>';
}
if (
typeof hours['holidays'] !== 'undefined' &&
typeof hours['holidays'][dateYMD] !== 'undefined'
) {
html = '<b class="opening-hours-status opening-hours-status-closed">Closed today' +
(hours['holidays'][dateYMD] ? ' for ' + hours['holidays'][dateYMD] : '') +
'</b>';
}
this.each((i, e) => {
const $e = $(e);
$e.html(html);
});
}
static Date_toYMD(date) {
var year, month, day;
year = String(date.getFullYear());
month = String(date.getMonth() + 1);
if (month.length == 1) {
month = '0' + month;
}
day = String(date.getDate());
if (day.length == 1) {
day = '0' + day;
}
return year + '-' + month + '-' + day;
}
static dispose() {
this.each((i, e) => {
$(e).html('');
});
}
} }
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { static init() {
OpeningHoursUI.init(); this.dispose();
}); const hours = $.parseJSON($('.oppening-hours-json').html());
const date = new Date();
const dateYMD = this.Date_toYMD(date);
const weekday = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
];
const today = weekday[date.getDay()];
let html = '<b class="opening-hours-status opening-hours-status-closed">Closed today</b>';
return OpeningHoursUI; if (
typeof hours['days'] !== 'undefined' &&
typeof hours['days'][today] !== 'undefined' &&
hours['days'][today].length
) {
html = 'Open today ';
$.each(hours['days'][today], (i, v) => {
if (v['DisplayStart'] || v['DisplayEnd']) {
if (
(
v['DisplayStart'] && v['DisplayStart'] <= dateYMD &&
v['DisplayEnd'] && v['DisplayEnd'] >= dateYMD
) ||
(v['DisplayStart'] && v['DisplayStart'] <= dateYMD && !v['DisplayEnd']) ||
(v['DisplayEnd'] && v['DisplayEnd'] >= dateYMD && !v['DisplayStart'])
) {
html = `Open today from ${ v['From'] } to ${ v['Till']}`;
return false;
}
} else {
if (i > 0) {
html += ', <br/>';
}
html += `from ${ v['From'] } to ${ v['Till']}`;
}
});
html += ' <b class="opening-hours-status"></b>';
}
if (
typeof hours['holidays'] !== 'undefined' &&
typeof hours['holidays'][dateYMD] !== 'undefined'
) {
html = `<b class="opening-hours-status opening-hours-status-closed">Closed today${
hours['holidays'][dateYMD] ? ` for ${ hours['holidays'][dateYMD]}` : ''
}</b>`;
}
this.each((i, e) => {
const $e = $(e);
$e.html(html);
});
}
static Date_toYMD(date) {
var year, month, day;
year = String(date.getFullYear());
month = String(date.getMonth() + 1);
if (month.length == 1) {
month = `0${ month}`;
}
day = String(date.getDate());
if (day.length == 1) {
day = `0${ day}`;
}
return `${year }-${ month }-${ day}`;
}
static dispose() {
this.each((i, e) => {
$(e).html('');
});
}
}
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
OpeningHoursUI.init();
});
return OpeningHoursUI;
})($); })($);
export default OpeningHoursUI; export default OpeningHoursUI;

View File

@ -3,20 +3,20 @@
import $ from 'jquery'; import $ from 'jquery';
const ShrinkUI = (($) => { const ShrinkUI = (($) => {
// Constants // Constants
const G = window; const G = window;
const D = document; const D = document;
// shrink bar // shrink bar
$(G).scroll(function() { $(G).scroll(() => {
if ($(D).scrollTop() > 100) { if ($(D).scrollTop() > 100) {
$('body').addClass('shrink'); $('body').addClass('shrink');
} else { } else {
$('body').removeClass('shrink'); $('body').removeClass('shrink');
} }
}); });
return ShrinkUI; return ShrinkUI;
})($); })($);
export default ShrinkUI; export default ShrinkUI;

View File

@ -8,98 +8,98 @@ import SpinnerUI from './_ui.spinner';
const VideoPreviewUI = (($) => { const VideoPreviewUI = (($) => {
const NAME = 'jsVideoPreviewUI'; const NAME = 'jsVideoPreviewUI';
const DATA_KEY = NAME; const DATA_KEY = NAME;
const G = window; const G = window;
const D = document; const D = document;
class VideoPreviewUI { class VideoPreviewUI {
constructor(el) { constructor(el) {
console.log(`Initializing: ${NAME}`); console.log(`Initializing: ${NAME}`);
const ui = this; const ui = this;
ui.$_el = $(el); ui.$_el = $(el);
ui.innerHTML = ui.$_el[0].innerHTML; ui.innerHTML = ui.$_el[0].innerHTML;
ui.$_el.data(DATA_KEY, this); ui.$_el.data(DATA_KEY, this);
const href = ui.$_el.attr('href') || ui.$_el.data('href'); const href = ui.$_el.attr('href') || ui.$_el.data('href');
let video; let video;
if (video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/)) { if (video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/)) {
let video_id; let video_id;
if (video[1] === 'youtube' || video[1] === 'youtube-nocookie') { if (video[1] === 'youtube' || video[1] === 'youtube-nocookie') {
video_id = video[4]; video_id = video[4];
} }
if (video[1] === 'youtu') { if (video[1] === 'youtu') {
video_id = video[3]; video_id = video[3];
}
if (video[1] == 'vimeo') {
video_id = video[3];
ui.$_el.addClass('loading');
$.ajax({
type: 'GET',
url: 'https://vimeo.com/api/v2/video/' + video_id + '.json',
jsonp: 'callback',
dataType: 'jsonp',
success: function(data) {
const thumbnail_src = data[0].thumbnail_large;
ui.show(thumbnail_src);
ui.$_el.removeClass('loading');
}
});
return;
}
if (video_id) {
ui.show(`//i3.ytimg.com/vi/${video_id}/0.jpg`);
}
}
} }
show(src) { if (video[1] == 'vimeo') {
const ui = this; video_id = video[3];
ui.$_el[0].innerHTML = ''; ui.$_el.addClass('loading');
ui.$_el.append(`<img src="${src}" alt="Video" />`); $.ajax({
type: 'GET',
url: `https://vimeo.com/api/v2/video/${ video_id }.json`,
jsonp: 'callback',
dataType: 'jsonp',
success: function(data) {
const thumbnail_src = data[0].thumbnail_large;
ui.show(thumbnail_src);
ui.$_el.removeClass('loading');
},
});
return;
} }
static dispose() { if (video_id) {
console.log(`Destroying: ${NAME}`); ui.show(`//i3.ytimg.com/vi/${video_id}/0.jpg`);
ui.$_el[0].innerHTML = ui.innerHTML;
}
static _jQueryInterface() {
return this.each((i, el) => {
// attach functionality to element
const $el = $(el);
let data = $el.data(DATA_KEY);
if (!data) {
data = new VideoPreviewUI(el);
$el.data(DATA_KEY, data);
}
});
} }
}
} }
// jQuery interface show(src) {
$.fn[NAME] = VideoPreviewUI._jQueryInterface; const ui = this;
$.fn[NAME].Constructor = VideoPreviewUI; ui.$_el[0].innerHTML = '';
$.fn[NAME].noConflict = () => { ui.$_el.append(`<img src="${src}" alt="Video" />`);
$.fn[NAME] = JQUERY_NO_CONFLICT; }
return VideoPreviewUI._jQueryInterface;
};
// auto-apply static dispose() {
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { console.log(`Destroying: ${NAME}`);
$('[data-video-preview="true"]').jsVideoPreviewUI(); ui.$_el[0].innerHTML = ui.innerHTML;
}); }
return VideoPreviewUI; static _jQueryInterface() {
return this.each((i, el) => {
// attach functionality to element
const $el = $(el);
let data = $el.data(DATA_KEY);
if (!data) {
data = new VideoPreviewUI(el);
$el.data(DATA_KEY, data);
}
});
}
}
// jQuery interface
$.fn[NAME] = VideoPreviewUI._jQueryInterface;
$.fn[NAME].Constructor = VideoPreviewUI;
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return VideoPreviewUI._jQueryInterface;
};
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('[data-video-preview="true"]').jsVideoPreviewUI();
});
return VideoPreviewUI;
})($); })($);
export default VideoPreviewUI; export default VideoPreviewUI;