mirror of
https://github.com/a2nt/silverstripe-webpack.git
synced 2024-10-22 17:05:31 +02:00
Linting
This commit is contained in:
parent
4fa466157f
commit
5358afd5ec
@ -5,258 +5,258 @@ import Events from '../_events';
|
||||
import Spinner from './_ui.spinner';
|
||||
|
||||
const AjaxUI = (($) => {
|
||||
// Constants
|
||||
const G = window;
|
||||
const D = document;
|
||||
const $Html = $('html');
|
||||
const $Body = $('body');
|
||||
// Constants
|
||||
const G = window;
|
||||
const D = document;
|
||||
const $Html = $('html');
|
||||
const $Body = $('body');
|
||||
|
||||
const NAME = 'jsAjaxUI';
|
||||
const DATA_KEY = NAME;
|
||||
const NAME = 'jsAjaxUI';
|
||||
const DATA_KEY = NAME;
|
||||
|
||||
class AjaxUI {
|
||||
// Constructor
|
||||
constructor(element) {
|
||||
this._element = element;
|
||||
const $element = $(this._element);
|
||||
$element.addClass(`${NAME}-active`);
|
||||
class AjaxUI {
|
||||
// Constructor
|
||||
constructor(element) {
|
||||
this._element = element;
|
||||
const $element = $(this._element);
|
||||
$element.addClass(`${NAME}-active`);
|
||||
|
||||
$element.bind('click', function(e) {
|
||||
e.preventDefault();
|
||||
$element.bind('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const $this = $(this);
|
||||
const $this = $(this);
|
||||
|
||||
$('.ajax').each(function() {
|
||||
const $this = $(this);
|
||||
$this.removeClass('active');
|
||||
$this.parents('.nav-item').removeClass('active');
|
||||
});
|
||||
$('.ajax').each(function() {
|
||||
const $this = $(this);
|
||||
$this.removeClass('active');
|
||||
$this.parents('.nav-item').removeClass('active');
|
||||
});
|
||||
|
||||
$this.addClass('loading');
|
||||
$this.addClass('loading');
|
||||
|
||||
AjaxUI.load($this.attr('href'), () => {
|
||||
$this.removeClass('loading');
|
||||
$this.parents('.nav-item').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);
|
||||
}
|
||||
});
|
||||
}
|
||||
AjaxUI.load($this.attr('href'), () => {
|
||||
$this.removeClass('loading');
|
||||
$this.parents('.nav-item').addClass('active');
|
||||
$this.addClass('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = AjaxUI._jQueryInterface;
|
||||
$.fn[NAME].Constructor = AjaxUI;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return AjaxUI._jQueryInterface;
|
||||
};
|
||||
// Public methods
|
||||
static load(url, callback) {
|
||||
// show spinner
|
||||
Spinner.show(() => {
|
||||
$Body.removeClass('loaded');
|
||||
});
|
||||
|
||||
// auto-apply
|
||||
$('.ajax').ready(() => {
|
||||
$('.ajax').jsAjaxUI();
|
||||
});
|
||||
// update document location
|
||||
G.MainUI.updateLocation(url);
|
||||
|
||||
// AJAX update browser title
|
||||
$(D).on('layoutRefresh', (e, data) => {
|
||||
D.title = data.Title;
|
||||
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);
|
||||
}
|
||||
|
||||
$Html.attr('class', '');
|
||||
if (data.ClassName) {
|
||||
$Html.addClass(data.ClassName);
|
||||
$.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);
|
||||
}
|
||||
}
|
||||
//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;
|
||||
// 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();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
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;
|
||||
|
@ -3,88 +3,88 @@ import $ from 'jquery';
|
||||
import Events from '../_events';
|
||||
|
||||
const CarouselUI = (($) => {
|
||||
// Constants
|
||||
const NAME = 'CarouselUI';
|
||||
// Constants
|
||||
const NAME = 'CarouselUI';
|
||||
|
||||
class CarouselUI {
|
||||
// Static methods
|
||||
class CarouselUI {
|
||||
// Static methods
|
||||
|
||||
static each(callback) {
|
||||
$('.js-carousel').each(function(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');
|
||||
});
|
||||
}
|
||||
static each(callback) {
|
||||
$('.js-carousel').each((i, e) => {
|
||||
callback(i, $(e));
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
CarouselUI.init();
|
||||
});
|
||||
static 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;
|
@ -5,175 +5,175 @@ import Events from "../_events";
|
||||
import SpinnerUI from './_ui.spinner';
|
||||
|
||||
const FormBasics = (($) => {
|
||||
// Constants
|
||||
const NAME = 'jsFormBasics';
|
||||
const DATA_KEY = NAME;
|
||||
const $Html = $('html, body');
|
||||
// Constants
|
||||
const NAME = 'jsFormBasics';
|
||||
const DATA_KEY = NAME;
|
||||
const $Html = $('html, body');
|
||||
|
||||
class FormBasics {
|
||||
class FormBasics {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
|
||||
const $fields = $element.find('input,textarea,select');
|
||||
const $selectFields = $element.find('select:not([readonly])');
|
||||
const $radioOptions = $element.find('input[type="radio"]');
|
||||
const separator = ', ';
|
||||
const $fields = $element.find('input,textarea,select');
|
||||
const $selectFields = $element.find('select:not([readonly])');
|
||||
const $radioOptions = $element.find('input[type="radio"]');
|
||||
const separator = ', ';
|
||||
|
||||
$selectFields.each((i, el) => {
|
||||
const $el = $(el);
|
||||
const maxOptions = $el.data('max-options') || false;
|
||||
$selectFields.each((i, el) => {
|
||||
const $el = $(el);
|
||||
const maxOptions = $el.data('max-options') || false;
|
||||
|
||||
$el.selectpicker($.extend({
|
||||
iconBase: 'fas',
|
||||
tickIcon: 'fa-check',
|
||||
virtualScroll: false,
|
||||
dropupAuto: false,
|
||||
size: 10,
|
||||
maxOptions: maxOptions,
|
||||
}, $el.data(), {
|
||||
multipleSeparator: separator,
|
||||
}));
|
||||
$el.selectpicker($.extend({
|
||||
iconBase: 'fas',
|
||||
tickIcon: 'fa-check',
|
||||
virtualScroll: false,
|
||||
dropupAuto: false,
|
||||
size: 10,
|
||||
maxOptions,
|
||||
}, $el.data(), {
|
||||
multipleSeparator: separator,
|
||||
}));
|
||||
|
||||
// wrap options
|
||||
$el.on('rendered.bs.select', () => {
|
||||
if (!$el.val().length) {
|
||||
return true;
|
||||
}
|
||||
// wrap options
|
||||
$el.on('rendered.bs.select', () => {
|
||||
if (!$el.val().length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const $container = $el.parent().find('.filter-option-inner-inner');
|
||||
const val = $container.text();
|
||||
const vals = val.split(separator);
|
||||
let html = '';
|
||||
const $container = $el.parent().find('.filter-option-inner-inner');
|
||||
const val = $container.text();
|
||||
const vals = val.split(separator);
|
||||
let html = '';
|
||||
|
||||
vals.forEach((opt) => {
|
||||
const $opt = $el.find('option').filter((i, e) => {
|
||||
return $(e).text() === opt;
|
||||
});
|
||||
vals.forEach((opt) => {
|
||||
const $opt = $el.find('option').filter((i, e) => {
|
||||
return $(e).text() === opt;
|
||||
});
|
||||
|
||||
html += '<span class="option" data-val=' + $opt.attr('value') + '>' + opt +
|
||||
' <i class="fas fa-times btn-remove"></i></span>';
|
||||
});
|
||||
html += `<span class="option" data-val=${ $opt.attr('value') }>${ opt
|
||||
} <i class="fas fa-times btn-remove"></i></span>`;
|
||||
});
|
||||
|
||||
$container.html(html);
|
||||
$container.html(html);
|
||||
|
||||
// remove value
|
||||
$container.find('.option').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
// remove value
|
||||
$container.find('.option').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const $opt = $(e.currentTarget);
|
||||
const val = $opt.data('val').toString();
|
||||
//$opt.remove();
|
||||
const $opt = $(e.currentTarget);
|
||||
const val = $opt.data('val').toString();
|
||||
//$opt.remove();
|
||||
|
||||
let vals = $el.selectpicker('val');
|
||||
const i = vals.indexOf(val);
|
||||
if (i > -1) {
|
||||
vals.splice(i, 1);
|
||||
$el.selectpicker('val', vals);
|
||||
}
|
||||
});
|
||||
});
|
||||
const vals = $el.selectpicker('val');
|
||||
const i = vals.indexOf(val);
|
||||
if (i > -1) {
|
||||
vals.splice(i, 1);
|
||||
$el.selectpicker('val', vals);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// FIX: hidden picker
|
||||
$el.selectpicker('render');
|
||||
$el.selectpicker('refresh');
|
||||
$el.selectpicker('toggle');
|
||||
document.activeElement.blur();
|
||||
// FIX: hidden picker
|
||||
$el.selectpicker('render');
|
||||
$el.selectpicker('refresh');
|
||||
$el.selectpicker('toggle');
|
||||
document.activeElement.blur();
|
||||
|
||||
//$el.selectpicker('show');
|
||||
//$el.selectpicker('hide');
|
||||
//$el.selectpicker('show');
|
||||
//$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').blur();*/
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$fields.each((e, el) => {
|
||||
const $el = $(el);
|
||||
$fields.each((e, el) => {
|
||||
const $el = $(el);
|
||||
|
||||
if ($el.hasClass('required') || $el.attr('aria-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);
|
||||
if ($el.hasClass('required') || $el.attr('aria-required')) {
|
||||
$el.closest('.field').addClass('required');
|
||||
}
|
||||
});
|
||||
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
$radioOptions.each((e, el) => {
|
||||
const $el = $(el);
|
||||
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
if ($el.is(':checked')) {
|
||||
$el.parents('.radio').addClass('checked');
|
||||
}
|
||||
});
|
||||
|
||||
static _jQueryInterface() {
|
||||
return this.each(function() {
|
||||
// attach functionality to element
|
||||
const $element = $(this);
|
||||
let data = $element.data(DATA_KEY);
|
||||
$radioOptions.on('change', (e) => {
|
||||
const $el = $(e.currentTarget);
|
||||
const $parent = $el.parents('.radio');
|
||||
|
||||
if (!data) {
|
||||
data = new FormBasics(this);
|
||||
$element.data(DATA_KEY, data);
|
||||
}
|
||||
});
|
||||
$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);
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = FormBasics._jQueryInterface;
|
||||
$.fn[NAME].Constructor = FormBasics;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return FormBasics._jQueryInterface;
|
||||
};
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('form').each((i, el) => {
|
||||
const $el = $(el);
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
}
|
||||
|
||||
// skip some forms
|
||||
if ($el.hasClass('no-validation')) {
|
||||
return true;
|
||||
}
|
||||
static _jQueryInterface() {
|
||||
return this.each(function() {
|
||||
// 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;
|
||||
|
@ -11,219 +11,219 @@ import 'exif-js/exif.js';
|
||||
|
||||
const CroppieUI = (($) => {
|
||||
|
||||
const NAME = 'jsCroppieUI';
|
||||
const DATA_KEY = NAME;
|
||||
const NAME = 'jsCroppieUI';
|
||||
const DATA_KEY = NAME;
|
||||
|
||||
const G = window;
|
||||
const D = document;
|
||||
const G = window;
|
||||
const D = document;
|
||||
|
||||
const jqteOptions = {
|
||||
color: false,
|
||||
fsize: false,
|
||||
funit: 'em',
|
||||
format: false,
|
||||
rule: false,
|
||||
source: false,
|
||||
sub: false,
|
||||
sup: false,
|
||||
};
|
||||
const jqteOptions = {
|
||||
color: false,
|
||||
fsize: false,
|
||||
funit: 'em',
|
||||
format: false,
|
||||
rule: false,
|
||||
source: false,
|
||||
sub: false,
|
||||
sup: false,
|
||||
};
|
||||
|
||||
class CroppieUI {
|
||||
class CroppieUI {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $el = $(element);
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $el = $(element);
|
||||
|
||||
ui.$el = $el;
|
||||
$el.data(DATA_KEY, this);
|
||||
ui.$el = $el;
|
||||
$el.data(DATA_KEY, this);
|
||||
|
||||
ui.input = $el.find('input[type="file"]');
|
||||
//ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />');
|
||||
ui.input = $el.find('input[type="file"]');
|
||||
//ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />');
|
||||
|
||||
ui.width = ui.input.data('width');
|
||||
ui.height = ui.input.data('height');
|
||||
ui.width = ui.input.data('width');
|
||||
ui.height = ui.input.data('height');
|
||||
|
||||
$el.append(
|
||||
'<div class="cropper-wrap"><div class="cropper-container"></div>' +
|
||||
$el.append(
|
||||
'<div class="cropper-wrap"><div class="cropper-container"></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.uploadCrop = ui.uploadCropWrap.find('.cropper-container');
|
||||
ui.uploadCropWrap = $el.find('.cropper-wrap');
|
||||
ui.uploadCrop = ui.uploadCropWrap.find('.cropper-container');
|
||||
|
||||
const ratio = ui.width / (ui.uploadCrop.width() - 32);
|
||||
ui.uploadCrop.croppie({
|
||||
enableExif: true,
|
||||
enforceBoundary: false,
|
||||
viewport: {
|
||||
width: ui.width / ratio,
|
||||
height: ui.height / ratio,
|
||||
}
|
||||
});
|
||||
const ratio = ui.width / (ui.uploadCrop.width() - 32);
|
||||
ui.uploadCrop.croppie({
|
||||
enableExif: true,
|
||||
enforceBoundary: false,
|
||||
viewport: {
|
||||
width: ui.width / ratio,
|
||||
height: ui.height / ratio,
|
||||
},
|
||||
});
|
||||
|
||||
ui.uploadCrop.hide();
|
||||
ui.uploadCrop.hide();
|
||||
|
||||
ui.input.on('change', (e) => {
|
||||
this.readFile(e.currentTarget);
|
||||
});
|
||||
ui.input.on('change', (e) => {
|
||||
this.readFile(e.currentTarget);
|
||||
});
|
||||
|
||||
$el.find('.btn-remove').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
$el.find('.btn-remove').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
ui.uploadCrop.removeClass('ready');
|
||||
$el.find('.croppie-image').remove();
|
||||
ui.uploadCrop.removeClass('ready');
|
||||
$el.find('.croppie-image').remove();
|
||||
|
||||
ui.$el.find('input[type="file"]').val('');
|
||||
ui.$el.find('input[type="file"]').change();
|
||||
ui.$el.find('input[type="file"]').val('');
|
||||
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) {
|
||||
const ui = this;
|
||||
const $el = ui.$el;
|
||||
const $form = $el.closest('form');
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
|
||||
if (input.files && input.files[0]) {
|
||||
const reader = new FileReader();
|
||||
$form.on('submit', (e) => {
|
||||
//$(input).val('');
|
||||
SpinnerUI.show();
|
||||
|
||||
reader.onload = (e) => {
|
||||
ui.uploadCrop.addClass('ready');
|
||||
ui.uploadCrop.croppie('bind', {
|
||||
url: e.target.result
|
||||
});
|
||||
if (!ui.uploadCrop.hasClass('ready')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ui.uploadCrop.show();
|
||||
ui.uploadCropWrap.show();
|
||||
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,
|
||||
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]);
|
||||
|
||||
$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) {
|
||||
if (IS_JSON) {
|
||||
/*for (let k in json) {
|
||||
$form.find('select[name="' + k + '"],input[name="' + k + '"],textarea[name="' + k + '"]').setError(true, json[k]);
|
||||
}*/
|
||||
|
||||
if (typeof json['status'] !== 'undefined') {
|
||||
if (json['status'] === 'success') {
|
||||
MainUI.alert(json['message'], json['status']);
|
||||
if (typeof json['status'] !== 'undefined') {
|
||||
if (json['status'] === 'success') {
|
||||
MainUI.alert(json['message'], json['status']);
|
||||
|
||||
if (typeof json['link'] !== 'undefined') {
|
||||
setTimeout(() => {
|
||||
G.location = json['link'];
|
||||
}, 2000);
|
||||
} else {
|
||||
//G.location.reload(false);
|
||||
}
|
||||
} else if (json['status'] === 'error') {
|
||||
MainUI.alert(json['message'], json['status']);
|
||||
}
|
||||
}
|
||||
if (typeof json['link'] !== 'undefined') {
|
||||
setTimeout(() => {
|
||||
G.location = json['link'];
|
||||
}, 2000);
|
||||
} else {
|
||||
//G.location.reload(false);
|
||||
}
|
||||
} else if (json['status'] === 'error') {
|
||||
MainUI.alert(json['message'], json['status']);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof json['form'] !== 'undefined') {
|
||||
$(form).replaceWith(json['form']);
|
||||
}
|
||||
} else {
|
||||
$(form).replaceWith(data);
|
||||
//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);
|
||||
if (typeof json['form'] !== 'undefined') {
|
||||
$(form).replaceWith(json['form']);
|
||||
}
|
||||
} else {
|
||||
$(form).replaceWith(data);
|
||||
//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');
|
||||
}
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = CroppieUI._jQueryInterface;
|
||||
$.fn[NAME].Constructor = CroppieUI;
|
||||
$.fn[NAME].noConflict = () => {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return CroppieUI._jQueryInterface;
|
||||
};
|
||||
static dispose() {
|
||||
console.log(`Destroying: ${NAME}`);
|
||||
}
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('.field.croppie').jsCroppieUI();
|
||||
});
|
||||
static _jQueryInterface() {
|
||||
return this.each((i, el) => {
|
||||
// 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;
|
||||
|
@ -6,87 +6,87 @@ import 'bootstrap-datepicker/dist/js/bootstrap-datepicker.js';
|
||||
import 'bootstrap-timepicker/js/bootstrap-timepicker.js';
|
||||
|
||||
const DatetimeUI = (($) => {
|
||||
// Constants
|
||||
const W = window;
|
||||
const D = document;
|
||||
const $Body = $('body');
|
||||
// Constants
|
||||
const W = window;
|
||||
const D = document;
|
||||
const $Body = $('body');
|
||||
|
||||
const NAME = 'jsDatetimeUI';
|
||||
const DATA_KEY = NAME;
|
||||
const NAME = 'jsDatetimeUI';
|
||||
const DATA_KEY = NAME;
|
||||
|
||||
const datepickerOptions = {
|
||||
autoclose: true,
|
||||
startDate: 0,
|
||||
//todayBtn: true,
|
||||
todayHighlight: true,
|
||||
clearBtn: true,
|
||||
};
|
||||
const datepickerOptions = {
|
||||
autoclose: true,
|
||||
startDate: 0,
|
||||
//todayBtn: true,
|
||||
todayHighlight: true,
|
||||
clearBtn: true,
|
||||
};
|
||||
|
||||
class DatetimeUI {
|
||||
constructor(el) {
|
||||
const ui = this;
|
||||
const $el = $(el);
|
||||
class DatetimeUI {
|
||||
constructor(el) {
|
||||
const ui = this;
|
||||
const $el = $(el);
|
||||
|
||||
ui._el = el;
|
||||
ui._el = el;
|
||||
|
||||
// datepicker
|
||||
if ($el.hasClass('date') || $el.attr('type') === 'date') {
|
||||
const defaultDate = ($el.attr('name').toLowerCase().indexOf('end') !== -1) ?
|
||||
'+4d' :
|
||||
'+3d';
|
||||
// datepicker
|
||||
if ($el.hasClass('date') || $el.attr('type') === 'date') {
|
||||
const defaultDate = ($el.attr('name').toLowerCase().indexOf('end') !== -1) ?
|
||||
'+4d' :
|
||||
'+3d';
|
||||
|
||||
$el.attr('readonly', 'true');
|
||||
$el.datepicker($.extend(datepickerOptions, {
|
||||
defaultViewDate: defaultDate,
|
||||
multidate: $el.data('multidate'),
|
||||
}));
|
||||
} else
|
||||
$el.attr('readonly', 'true');
|
||||
$el.datepicker($.extend(datepickerOptions, {
|
||||
defaultViewDate: defaultDate,
|
||||
multidate: $el.data('multidate'),
|
||||
}));
|
||||
} else
|
||||
|
||||
// timepicker
|
||||
if ($el.hasClass('time') || $el.attr('type') === 'time') {
|
||||
$el.attr('readonly', 'true');
|
||||
$el.timepicker({
|
||||
defaultTime: $el.data('default-time'),
|
||||
icons: {
|
||||
up: 'fas fa-chevron-up',
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
// timepicker
|
||||
if ($el.hasClass('time') || $el.attr('type') === 'time') {
|
||||
$el.attr('readonly', 'true');
|
||||
$el.timepicker({
|
||||
defaultTime: $el.data('default-time'),
|
||||
icons: {
|
||||
up: 'fas fa-chevron-up',
|
||||
down: 'fas fa-chevron-down',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = DatetimeUI._jQueryInterface;
|
||||
$.fn[NAME].Constructor = DatetimeUI;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return DatetimeUI._jQueryInterface;
|
||||
};
|
||||
static dispose() {
|
||||
console.log(`Destroying: ${NAME}`);
|
||||
}
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('input.date, input.time,input[type="date"], input[type="time"]').jsDatetimeUI();
|
||||
});
|
||||
static _jQueryInterface() {
|
||||
return this.each(function() {
|
||||
// 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;
|
||||
|
@ -10,71 +10,71 @@ import '../../thirdparty/jquery-te/jquery-te.js';
|
||||
|
||||
const JqteUI = (($) => {
|
||||
|
||||
const NAME = 'jsJqteUI';
|
||||
const DATA_KEY = NAME;
|
||||
const NAME = 'jsJqteUI';
|
||||
const DATA_KEY = NAME;
|
||||
|
||||
const jqteOptions = {
|
||||
color: false,
|
||||
fsize: false,
|
||||
funit: 'em',
|
||||
format: false,
|
||||
rule: false,
|
||||
source: false,
|
||||
sub: false,
|
||||
sup: false,
|
||||
};
|
||||
const jqteOptions = {
|
||||
color: false,
|
||||
fsize: false,
|
||||
funit: 'em',
|
||||
format: false,
|
||||
rule: false,
|
||||
source: false,
|
||||
sub: false,
|
||||
sup: false,
|
||||
};
|
||||
|
||||
class JqteUI {
|
||||
class JqteUI {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
const validationUI = $element.data('jsFormValidateField');
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
const validationUI = $element.data('jsFormValidateField');
|
||||
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
$element.jqte(jqteOptions);
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
$element.jqte(jqteOptions);
|
||||
|
||||
// dynamic error control
|
||||
if (validationUI) {
|
||||
$element.parents('.jqte').find('.jqte_editor').on('change', (e) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
// dynamic error control
|
||||
if (validationUI) {
|
||||
$element.parents('.jqte').find('.jqte_editor').on('change', (e) => {
|
||||
validationUI.validate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = JqteUI._jQueryInterface;
|
||||
$.fn[NAME].Constructor = JqteUI;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return JqteUI._jQueryInterface;
|
||||
};
|
||||
static dispose() {
|
||||
console.log(`Destroying: ${NAME}`);
|
||||
}
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('textarea.jqte-field').jsJqteUI();
|
||||
});
|
||||
static _jQueryInterface() {
|
||||
return this.each(function() {
|
||||
// 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;
|
||||
|
@ -4,200 +4,200 @@ import LANG from '../lang/_en';
|
||||
import FormValidateField from "./_ui.form.validate.field";
|
||||
|
||||
const SteppedForm = (($) => {
|
||||
// Constants
|
||||
const NAME = 'jsSteppedForm';
|
||||
const DATA_KEY = NAME;
|
||||
// Constants
|
||||
const NAME = 'jsSteppedForm';
|
||||
const DATA_KEY = NAME;
|
||||
|
||||
class SteppedForm {
|
||||
class SteppedForm {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
|
||||
$element.data(DATA_KEY, this);
|
||||
$element.data(DATA_KEY, this);
|
||||
|
||||
if (!$element.find('.steps-counter').length) {
|
||||
$element.prepend(LANG['en'][NAME]['STEPCOUNTER']);
|
||||
}
|
||||
if (!$element.find('.steps-counter').length) {
|
||||
$element.prepend(LANG['en'][NAME]['STEPCOUNTER']);
|
||||
}
|
||||
|
||||
if (!$element.find('.steps-buttons').length) {
|
||||
$element.append(LANG['en'][NAME]['STEPBUTTONS']);
|
||||
}
|
||||
if (!$element.find('.steps-buttons').length) {
|
||||
$element.append(LANG['en'][NAME]['STEPBUTTONS']);
|
||||
}
|
||||
|
||||
ui._currentStepCounter = $element.find('.steps-counter .current-step');
|
||||
ui._totalStepsCounter = $element.find('.steps-counter .total-steps');
|
||||
ui._currentStepCounter = $element.find('.steps-counter .current-step');
|
||||
ui._totalStepsCounter = $element.find('.steps-counter .total-steps');
|
||||
|
||||
ui._steps = $element.find('.step');
|
||||
ui._stepNext = $element.find('.step-next');
|
||||
ui._steps = $element.find('.step');
|
||||
ui._stepNext = $element.find('.step-next');
|
||||
|
||||
ui._stepPrev = $element.find('.step-prev');
|
||||
ui._actions = $element.children('.btn-toolbar,.form-actions');
|
||||
ui._stepPrev = $element.find('.step-prev');
|
||||
ui._actions = $element.children('.btn-toolbar,.form-actions');
|
||||
|
||||
ui._element = element;
|
||||
ui._currentStep = 1;
|
||||
ui._totalSteps = ui._steps.last().data('step') || ui._steps.length;
|
||||
ui._stepsOrder = [];
|
||||
ui._element = element;
|
||||
ui._currentStep = 1;
|
||||
ui._totalSteps = ui._steps.last().data('step') || ui._steps.length;
|
||||
ui._stepsOrder = [];
|
||||
|
||||
ui._totalStepsCounter.text(ui._totalSteps);
|
||||
ui._totalStepsCounter.text(ui._totalSteps);
|
||||
|
||||
// check if one of the steps already has an error
|
||||
const $hasError = ui._steps
|
||||
.find('.field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good')
|
||||
.first();
|
||||
if ($hasError.length) {
|
||||
const $modal = $element.parents('.modal');
|
||||
// check if one of the steps already has an error
|
||||
const $hasError = ui._steps
|
||||
.find('.field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good')
|
||||
.first();
|
||||
if ($hasError.length) {
|
||||
const $modal = $element.parents('.modal');
|
||||
|
||||
// show modal
|
||||
if ($modal.length && typeof $modal.modal !== 'undefined') {
|
||||
$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);
|
||||
// show modal
|
||||
if ($modal.length && typeof $modal.modal !== 'undefined') {
|
||||
$modal.modal('show');
|
||||
}
|
||||
|
||||
// Public methods
|
||||
dispose() {
|
||||
const ui = this;
|
||||
const $element = $(ui._element);
|
||||
ui._currentStep = $hasError.parents('.step').data('step') || ui._currentStep;
|
||||
}
|
||||
//
|
||||
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(ui._element, DATA_KEY);
|
||||
ui._element = null;
|
||||
}
|
||||
ui.step(`.step[data-step="${ ui._currentStep }"]`);
|
||||
|
||||
next() {
|
||||
const ui = this;
|
||||
ui._stepNext.on('click', (e) => {
|
||||
e.preventDefault();
|
||||
ui.next();
|
||||
});
|
||||
|
||||
if (ui._currentStep >= ui._totalSteps) {
|
||||
return;
|
||||
}
|
||||
ui._stepPrev.on('click', (e) => {
|
||||
e.preventDefault();
|
||||
ui.prev();
|
||||
});
|
||||
|
||||
ui.step('.step[data-step="' + (ui._currentStep + 1) + '"]');
|
||||
}
|
||||
$element.find('.step-toggle').on('click', (e) => {
|
||||
const $el = $(e.currentTarget);
|
||||
|
||||
prev() {
|
||||
const ui = this;
|
||||
e.preventDefault();
|
||||
ui.step($el.data('target'));
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
$element.addClass(`${NAME}-active`);
|
||||
$element.trigger(Events.FORM_INIT_STEPPED);
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = SteppedForm._jQueryInterface;
|
||||
$.fn[NAME].Constructor = SteppedForm;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return SteppedForm._jQueryInterface;
|
||||
};
|
||||
// Public methods
|
||||
dispose() {
|
||||
const ui = this;
|
||||
const $element = $(ui._element);
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('.form-stepped').jsSteppedForm();
|
||||
});
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(ui._element, DATA_KEY);
|
||||
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;
|
||||
|
@ -2,147 +2,147 @@ import $ from 'jquery';
|
||||
import Events from "../_events";
|
||||
|
||||
const FormStorage = (($) => {
|
||||
// Constants
|
||||
const NAME = 'jsFormStorage';
|
||||
const DATA_KEY = NAME;
|
||||
const STORAGE = window.localStorage;
|
||||
// Constants
|
||||
const NAME = 'jsFormStorage';
|
||||
const DATA_KEY = NAME;
|
||||
const STORAGE = window.localStorage;
|
||||
|
||||
class FormStorage {
|
||||
class FormStorage {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
const $elements = $element.find('input, textarea, select');
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
const $elements = $element.find('input, textarea, select');
|
||||
|
||||
const setRangeValues = function(el) {
|
||||
let $el = $(el);
|
||||
$el.siblings('.value').text($el.val());
|
||||
};
|
||||
const setRangeValues = function(el) {
|
||||
const $el = $(el);
|
||||
$el.siblings('.value').text($el.val());
|
||||
};
|
||||
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
|
||||
$element.addClass(`${NAME}-active`);
|
||||
$element.addClass(`${NAME}-active`);
|
||||
|
||||
// restore form data from localStorage
|
||||
$elements.each((i, el) => {
|
||||
const $el = $(el);
|
||||
const id = $el.attr('id');
|
||||
const type = $el.attr('type');
|
||||
const val = STORAGE.getItem(NAME + id);
|
||||
// restore form data from localStorage
|
||||
$elements.each((i, el) => {
|
||||
const $el = $(el);
|
||||
const id = $el.attr('id');
|
||||
const type = $el.attr('type');
|
||||
const val = STORAGE.getItem(NAME + id);
|
||||
|
||||
if (type === 'file') {
|
||||
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);
|
||||
if (type === 'file') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
if (id && val && type) {
|
||||
if (type && (type === 'checkbox' || type === 'radio')) {
|
||||
$el.prop('checked', val);
|
||||
} else {
|
||||
$el.val(val);
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
STORAGE.clear();
|
||||
$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;
|
||||
}
|
||||
|
||||
static _jQueryInterface() {
|
||||
if (typeof window.localStorage !== 'undefined') {
|
||||
return this.each(function() {
|
||||
// attach functionality to element
|
||||
const $element = $(this);
|
||||
let data = $element.data(DATA_KEY);
|
||||
let val = $el.val();
|
||||
|
||||
if (!data) {
|
||||
data = new FormStorage(this);
|
||||
$element.data(DATA_KEY, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = FormStorage._jQueryInterface;
|
||||
$.fn[NAME].Constructor = FormStorage;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return FormStorage._jQueryInterface;
|
||||
};
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('form').each((i, el) => {
|
||||
const $el = $(el);
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
}
|
||||
|
||||
// skip some forms
|
||||
if ($el.hasClass('no-storage')) {
|
||||
return true;
|
||||
}
|
||||
clear() {
|
||||
STORAGE.clear();
|
||||
}
|
||||
|
||||
$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;
|
||||
|
@ -2,141 +2,141 @@ import $ from 'jquery';
|
||||
import Events from "../_events";
|
||||
|
||||
const FormValidateField = (($) => {
|
||||
// Constants
|
||||
const NAME = 'jsFormValidateField';
|
||||
const DATA_KEY = NAME;
|
||||
const $Html = $('html, body');
|
||||
// Constants
|
||||
const NAME = 'jsFormValidateField';
|
||||
const DATA_KEY = NAME;
|
||||
const $Html = $('html, body');
|
||||
|
||||
class FormValidateField {
|
||||
class FormValidateField {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
|
||||
ui._element = element;
|
||||
ui._actions = $element.parents('form').children('.btn-toolbar,.form-actions');
|
||||
$element.data(DATA_KEY, this);
|
||||
ui._element = element;
|
||||
ui._actions = $element.parents('form').children('.btn-toolbar,.form-actions');
|
||||
$element.data(DATA_KEY, this);
|
||||
|
||||
// prevent browsers checks (will do it using JS)
|
||||
$element.attr('novalidate', 'novalidate');
|
||||
// prevent browsers checks (will do it using JS)
|
||||
$element.attr('novalidate', 'novalidate');
|
||||
|
||||
$element.on('change', (e) => {
|
||||
ui.validate(false);
|
||||
});
|
||||
$element.on('change', (e) => {
|
||||
ui.validate(false);
|
||||
});
|
||||
|
||||
$element.addClass(`${NAME}-active`);
|
||||
$element.trigger(Events.FORM_INIT_VALIDATE_FIELD);
|
||||
}
|
||||
$element.addClass(`${NAME}-active`);
|
||||
$element.trigger(Events.FORM_INIT_VALIDATE_FIELD);
|
||||
}
|
||||
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
}
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
}
|
||||
|
||||
validate(scrollTo = true) {
|
||||
const ui = this;
|
||||
const $el = $(ui._element);
|
||||
const $field = $el.closest('.field');
|
||||
const extraChecks = $el.data(`${NAME}-extra`);
|
||||
let valid = true;
|
||||
let msg = null;
|
||||
validate(scrollTo = true) {
|
||||
const ui = this;
|
||||
const $el = $(ui._element);
|
||||
const $field = $el.closest('.field');
|
||||
const extraChecks = $el.data(`${NAME}-extra`);
|
||||
let valid = true;
|
||||
let msg = null;
|
||||
|
||||
// browser checks + required
|
||||
if (!ui._element.checkValidity() ||
|
||||
// browser checks + required
|
||||
if (!ui._element.checkValidity() ||
|
||||
($el.hasClass('required') && !$el.val().trim().length)
|
||||
) {
|
||||
valid = false;
|
||||
}
|
||||
) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// validate URL
|
||||
if ($el.hasClass('url') && $el.val().trim().length && !this.valideURL($el.val())) {
|
||||
valid = false;
|
||||
msg = 'URL must start with http:// or https://. For example: https://your-domain.com/';
|
||||
}
|
||||
// validate URL
|
||||
if ($el.hasClass('url') && $el.val().trim().length && !this.valideURL($el.val())) {
|
||||
valid = false;
|
||||
msg = 'URL must start with http:// or https://. For example: https://your-domain.com/';
|
||||
}
|
||||
|
||||
// extra checks
|
||||
if (extraChecks) {
|
||||
extraChecks.forEach((check) => {
|
||||
valid = valid && check();
|
||||
});
|
||||
}
|
||||
// extra checks
|
||||
if (extraChecks) {
|
||||
extraChecks.forEach((check) => {
|
||||
valid = valid && check();
|
||||
});
|
||||
}
|
||||
|
||||
this.removeError();
|
||||
if (valid) {
|
||||
return true;
|
||||
}
|
||||
this.removeError();
|
||||
if (valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.setError(scrollTo, msg);
|
||||
}, 500);
|
||||
setTimeout(() => {
|
||||
this.setError(scrollTo, msg);
|
||||
}, 500);
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
valideURL(str) {
|
||||
const pattern = new RegExp('^(https?:\\/\\/){1}' + // protocol
|
||||
valideURL(str) {
|
||||
const pattern = new RegExp('^(https?:\\/\\/){1}' + // protocol
|
||||
'((([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+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
|
||||
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
return pattern.test(str);
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = FormValidateField._jQueryInterface;
|
||||
$.fn[NAME].Constructor = FormValidateField;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return FormValidateField._jQueryInterface;
|
||||
};
|
||||
setError(scrollTo = true, msg = null) {
|
||||
const ui = this;
|
||||
const $field = $(ui._element).closest('.field');
|
||||
const pos = $field.offset().top;
|
||||
|
||||
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;
|
||||
|
@ -4,128 +4,128 @@ import FormValidateField from "./_ui.form.validate.field";
|
||||
import SpinnerUI from './_ui.spinner';
|
||||
|
||||
const FormValidate = (($) => {
|
||||
// Constants
|
||||
const NAME = 'jsFormValidate';
|
||||
const DATA_KEY = NAME;
|
||||
const $Html = $('html, body');
|
||||
// Constants
|
||||
const NAME = 'jsFormValidate';
|
||||
const DATA_KEY = NAME;
|
||||
const $Html = $('html, body');
|
||||
|
||||
class FormValidate {
|
||||
class FormValidate {
|
||||
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
const $fields = $element.find('input,textarea,select');
|
||||
constructor(element) {
|
||||
const ui = this;
|
||||
const $element = $(element);
|
||||
const $fields = $element.find('input,textarea,select');
|
||||
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
ui._element = element;
|
||||
$element.data(DATA_KEY, this);
|
||||
|
||||
ui._fields = $fields;
|
||||
ui._stepped_form = $element.data('jsSteppedForm');
|
||||
ui._fields = $fields;
|
||||
ui._stepped_form = $element.data('jsSteppedForm');
|
||||
|
||||
// prevent browsers checks (will do it using JS)
|
||||
$element.attr('novalidate', 'novalidate');
|
||||
// prevent browsers checks (will do it using JS)
|
||||
$element.attr('novalidate', 'novalidate');
|
||||
|
||||
$element.on(Events.FORM_INIT_STEPPED, () => {
|
||||
ui._stepped_form = $element.data('jsSteppedForm');
|
||||
});
|
||||
$element.on(Events.FORM_INIT_STEPPED, () => {
|
||||
ui._stepped_form = $element.data('jsSteppedForm');
|
||||
});
|
||||
|
||||
// init fields validation
|
||||
$fields.each((i, el) => {
|
||||
new FormValidateField(el);
|
||||
});
|
||||
// init fields validation
|
||||
$fields.each((i, el) => {
|
||||
new FormValidateField(el);
|
||||
});
|
||||
|
||||
// check form
|
||||
$element.on('submit', (e) => {
|
||||
ui.validate(true, () => {
|
||||
e.preventDefault();
|
||||
// check form
|
||||
$element.on('submit', (e) => {
|
||||
ui.validate(true, () => {
|
||||
e.preventDefault();
|
||||
|
||||
// switch to step
|
||||
if (ui._stepped_form) {
|
||||
const $el = $element.find('.error').first();
|
||||
// switch to step
|
||||
if (ui._stepped_form) {
|
||||
const $el = $element.find('.error').first();
|
||||
|
||||
if ($el.length) {
|
||||
ui._stepped_form.step($el.parents('.step'));
|
||||
}
|
||||
}
|
||||
if ($el.length) {
|
||||
ui._stepped_form.step($el.parents('.step'));
|
||||
}
|
||||
}
|
||||
|
||||
$element.trigger(Events.FORM_VALIDATION_FAILED);
|
||||
});
|
||||
});
|
||||
$element.trigger(Events.FORM_VALIDATION_FAILED);
|
||||
});
|
||||
});
|
||||
|
||||
$element.addClass(`${NAME}-active`);
|
||||
$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);
|
||||
}
|
||||
});
|
||||
}
|
||||
$element.addClass(`${NAME}-active`);
|
||||
$element.trigger(Events.FORM_INIT_VALIDATE);
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = FormValidate._jQueryInterface;
|
||||
$.fn[NAME].Constructor = FormValidate;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return FormValidate._jQueryInterface;
|
||||
};
|
||||
// Public methods
|
||||
dispose() {
|
||||
const $element = $(this._element);
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('form').each((i, el) => {
|
||||
const $el = $(el);
|
||||
$element.removeClass(`${NAME}-active`);
|
||||
$.removeData(this._element, DATA_KEY);
|
||||
this._element = null;
|
||||
}
|
||||
|
||||
// skip some forms
|
||||
if ($el.hasClass('no-validation')) {
|
||||
return true;
|
||||
}
|
||||
validate(scrollTo = true, badCallback = false) {
|
||||
console.log('Checking the form ...');
|
||||
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;
|
||||
|
@ -10,43 +10,43 @@ import "../../scss/_components/_ui.map.scss";
|
||||
const W = window;
|
||||
|
||||
const MapAPI = (($) => {
|
||||
const STORAGE = W.localStorage;
|
||||
const STORAGE = W.localStorage;
|
||||
|
||||
// Constants
|
||||
const NAME = 'jsMapAPI';
|
||||
const DATA_KEY = NAME;
|
||||
const $BODY = $('body');
|
||||
let Map;
|
||||
let currentStyle;
|
||||
// Constants
|
||||
const NAME = 'jsMapAPI';
|
||||
const DATA_KEY = NAME;
|
||||
const $BODY = $('body');
|
||||
let Map;
|
||||
let currentStyle;
|
||||
|
||||
class MapAPI {
|
||||
// Constructor
|
||||
constructor(element) {
|
||||
this._element = element;
|
||||
const $element = $(this._element);
|
||||
const geojson = $element.data('geojson');
|
||||
class MapAPI {
|
||||
// Constructor
|
||||
constructor(element) {
|
||||
this._element = element;
|
||||
const $element = $(this._element);
|
||||
const geojson = $element.data('geojson');
|
||||
|
||||
const center = [
|
||||
($element.data('lng') ? $element.data('lng') : $BODY.data('default-lng')),
|
||||
($element.data('lat') ? $element.data('lat') : $BODY.data('default-lat')),
|
||||
];
|
||||
const popup = new mapboxgl.Popup({
|
||||
closeOnClick: false,
|
||||
className: 'popup'
|
||||
});
|
||||
const center = [
|
||||
($element.data('lng') ? $element.data('lng') : $BODY.data('default-lng')),
|
||||
($element.data('lat') ? $element.data('lat') : $BODY.data('default-lat')),
|
||||
];
|
||||
const popup = new mapboxgl.Popup({
|
||||
closeOnClick: false,
|
||||
className: 'popup',
|
||||
});
|
||||
|
||||
currentStyle = this.getStyle();
|
||||
mapBoxGL.accessToken = $element.data('key');
|
||||
currentStyle = this.getStyle();
|
||||
mapBoxGL.accessToken = $element.data('key');
|
||||
|
||||
Map = new mapBoxGL.Map({
|
||||
'container': $element.find('.mapAPI-map')[0],
|
||||
'center': center,
|
||||
//hash: true,
|
||||
'style': currentStyle,
|
||||
//localIdeographFontFamily: $BODY.css('font-family'),
|
||||
'zoom': ($element.data('map-zoom') ? $element.data('map-zoom') : 10),
|
||||
'attributionControl': false
|
||||
/*transformRequest: (url, resourceType)=> {
|
||||
Map = new mapBoxGL.Map({
|
||||
'container': $element.find('.mapAPI-map')[0],
|
||||
center,
|
||||
//hash: true,
|
||||
'style': currentStyle,
|
||||
//localIdeographFontFamily: $BODY.css('font-family'),
|
||||
'zoom': ($element.data('map-zoom') ? $element.data('map-zoom') : 10),
|
||||
'attributionControl': false,
|
||||
/*transformRequest: (url, resourceType)=> {
|
||||
if(resourceType === 'Source' && url.startsWith('http://myHost')) {
|
||||
return {
|
||||
url: url.replace('http', 'https'),
|
||||
@ -55,49 +55,49 @@ const MapAPI = (($) => {
|
||||
}
|
||||
}
|
||||
}*/
|
||||
})
|
||||
.addControl(new mapBoxGL.AttributionControl({
|
||||
compact: true
|
||||
}))
|
||||
.addControl(new mapBoxGL.NavigationControl(), 'top-right')
|
||||
.addControl(new mapBoxGL.GeolocateControl({
|
||||
positionOptions: {
|
||||
enableHighAccuracy: true,
|
||||
},
|
||||
trackUserLocation: true,
|
||||
}), 'bottom-right')
|
||||
.addControl(new mapboxgl.ScaleControl({
|
||||
maxWidth: 80,
|
||||
unit: 'metric'
|
||||
}), 'top-left');
|
||||
})
|
||||
.addControl(new mapBoxGL.AttributionControl({
|
||||
compact: true,
|
||||
}))
|
||||
.addControl(new mapBoxGL.NavigationControl(), 'top-right')
|
||||
.addControl(new mapBoxGL.GeolocateControl({
|
||||
positionOptions: {
|
||||
enableHighAccuracy: true,
|
||||
},
|
||||
trackUserLocation: true,
|
||||
}), 'bottom-right')
|
||||
.addControl(new mapboxgl.ScaleControl({
|
||||
maxWidth: 80,
|
||||
unit: 'metric',
|
||||
}), 'top-left');
|
||||
|
||||
// event.target
|
||||
Map.on('load', (e) => {
|
||||
// add markers to map
|
||||
geojson.features.forEach(function(marker) {
|
||||
// create a DOM element for the marker
|
||||
const $el = $('<div class="marker">' + marker.icon + '</div>');
|
||||
// event.target
|
||||
Map.on('load', (e) => {
|
||||
// add markers to map
|
||||
geojson.features.forEach((marker) => {
|
||||
// create a DOM element for the marker
|
||||
const $el = $(`<div class="marker">${ marker.icon }</div>`);
|
||||
|
||||
$el.on('click', function() {
|
||||
console.log('Marker click');
|
||||
const coordinates = marker.geometry.coordinates;
|
||||
const content = marker.properties.content;
|
||||
console.log(popup);
|
||||
popup.setLngLat(coordinates)
|
||||
.setHTML(content)
|
||||
.addTo(Map);
|
||||
});
|
||||
$el.on('click', () => {
|
||||
console.log('Marker click');
|
||||
const coordinates = marker.geometry.coordinates;
|
||||
const content = marker.properties.content;
|
||||
console.log(popup);
|
||||
popup.setLngLat(coordinates)
|
||||
.setHTML(content)
|
||||
.addTo(Map);
|
||||
});
|
||||
|
||||
// add marker to map
|
||||
new mapboxgl.Marker($el[0])
|
||||
.setLngLat(marker.geometry.coordinates)
|
||||
.addTo(Map);
|
||||
});
|
||||
// add marker to map
|
||||
new mapboxgl.Marker($el[0])
|
||||
.setLngLat(marker.geometry.coordinates)
|
||||
.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(event);
|
||||
});
|
||||
@ -114,75 +114,75 @@ const MapAPI = (($) => {
|
||||
//console.log(event);
|
||||
});*/
|
||||
|
||||
// check time every 60 mins and change to night style
|
||||
const api = this;
|
||||
setInterval(() => {
|
||||
const newStyle = api.getStyle();
|
||||
if (newStyle !== currentStyle) {
|
||||
Map.setStyle(api.getStyle());
|
||||
}
|
||||
}, 36000);
|
||||
|
||||
|
||||
$element.addClass(`${NAME}-active`);
|
||||
// check time every 60 mins and change to night style
|
||||
const api = this;
|
||||
setInterval(() => {
|
||||
const newStyle = api.getStyle();
|
||||
if (newStyle !== currentStyle) {
|
||||
Map.setStyle(api.getStyle());
|
||||
}
|
||||
}, 36000);
|
||||
|
||||
// Public methods
|
||||
getMap() {
|
||||
return Map;
|
||||
}
|
||||
|
||||
getStyle() {
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
$element.addClass(`${NAME}-active`);
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = MapAPI._jQueryInterface;
|
||||
$.fn[NAME].Constructor = MapAPI;
|
||||
$.fn[NAME].noConflict = function() {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return MapAPI._jQueryInterface;
|
||||
};
|
||||
// Public methods
|
||||
getMap() {
|
||||
return Map;
|
||||
}
|
||||
|
||||
// auto-apply
|
||||
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('.mapAPI-map-container').jsMapAPI();
|
||||
});
|
||||
getStyle() {
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -3,70 +3,70 @@ import Events from '../_events';
|
||||
import Spinner from './_ui.spinner';
|
||||
|
||||
const NoCaptcha = (($) => {
|
||||
// Constants
|
||||
const W = window;
|
||||
const D = document;
|
||||
const $Body = $('body');
|
||||
// Constants
|
||||
const W = window;
|
||||
const D = document;
|
||||
const $Body = $('body');
|
||||
|
||||
const NAME = 'NoCaptcha';
|
||||
const NAME = 'NoCaptcha';
|
||||
|
||||
class NoCaptcha {
|
||||
static init() {
|
||||
const ui = this;
|
||||
ui.dispose();
|
||||
class NoCaptcha {
|
||||
static init() {
|
||||
const ui = this;
|
||||
ui.dispose();
|
||||
|
||||
console.log(`Initializing: ${NAME}`);
|
||||
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);
|
||||
});
|
||||
|
||||
}
|
||||
console.log(`Initializing: ${NAME}`);
|
||||
this.renderCaptcha();
|
||||
}
|
||||
|
||||
$(W).on(`${Events.AJAX}`, () => {
|
||||
NoCaptcha.init();
|
||||
});
|
||||
static dispose() {
|
||||
console.log(`Destroying: ${NAME}`);
|
||||
}
|
||||
|
||||
W.NoCaptcha = NoCaptcha;
|
||||
W.noCaptchaFieldRender = NoCaptcha.renderCaptcha;
|
||||
static 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;
|
||||
|
@ -3,106 +3,106 @@ import $ from 'jquery';
|
||||
import Events from '../_events';
|
||||
|
||||
const OpeningHoursUI = (($) => {
|
||||
// Constants
|
||||
const NAME = 'OpeningHoursUI';
|
||||
// Constants
|
||||
const NAME = 'OpeningHoursUI';
|
||||
|
||||
class OpeningHoursUI {
|
||||
// Static methods
|
||||
class OpeningHoursUI {
|
||||
// Static methods
|
||||
|
||||
static each(callback) {
|
||||
$('.js-opening-hours').each(function(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('');
|
||||
});
|
||||
}
|
||||
static each(callback) {
|
||||
$('.js-opening-hours').each((i, e) => {
|
||||
callback(i, $(e));
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
OpeningHoursUI.init();
|
||||
});
|
||||
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>';
|
||||
|
||||
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;
|
||||
|
@ -3,20 +3,20 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
const ShrinkUI = (($) => {
|
||||
// Constants
|
||||
const G = window;
|
||||
const D = document;
|
||||
// Constants
|
||||
const G = window;
|
||||
const D = document;
|
||||
|
||||
// shrink bar
|
||||
$(G).scroll(function() {
|
||||
if ($(D).scrollTop() > 100) {
|
||||
$('body').addClass('shrink');
|
||||
} else {
|
||||
$('body').removeClass('shrink');
|
||||
}
|
||||
});
|
||||
// shrink bar
|
||||
$(G).scroll(() => {
|
||||
if ($(D).scrollTop() > 100) {
|
||||
$('body').addClass('shrink');
|
||||
} else {
|
||||
$('body').removeClass('shrink');
|
||||
}
|
||||
});
|
||||
|
||||
return ShrinkUI;
|
||||
return ShrinkUI;
|
||||
})($);
|
||||
|
||||
export default ShrinkUI;
|
||||
|
@ -8,98 +8,98 @@ import SpinnerUI from './_ui.spinner';
|
||||
|
||||
const VideoPreviewUI = (($) => {
|
||||
|
||||
const NAME = 'jsVideoPreviewUI';
|
||||
const DATA_KEY = NAME;
|
||||
const NAME = 'jsVideoPreviewUI';
|
||||
const DATA_KEY = NAME;
|
||||
|
||||
const G = window;
|
||||
const D = document;
|
||||
const G = window;
|
||||
const D = document;
|
||||
|
||||
class VideoPreviewUI {
|
||||
class VideoPreviewUI {
|
||||
|
||||
constructor(el) {
|
||||
console.log(`Initializing: ${NAME}`);
|
||||
constructor(el) {
|
||||
console.log(`Initializing: ${NAME}`);
|
||||
|
||||
const ui = this;
|
||||
ui.$_el = $(el);
|
||||
ui.innerHTML = ui.$_el[0].innerHTML;
|
||||
const ui = this;
|
||||
ui.$_el = $(el);
|
||||
ui.innerHTML = ui.$_el[0].innerHTML;
|
||||
|
||||
ui.$_el.data(DATA_KEY, this);
|
||||
const href = ui.$_el.attr('href') || ui.$_el.data('href');
|
||||
let video;
|
||||
ui.$_el.data(DATA_KEY, this);
|
||||
const href = ui.$_el.attr('href') || ui.$_el.data('href');
|
||||
let video;
|
||||
|
||||
if (video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/)) {
|
||||
let video_id;
|
||||
if (video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/)) {
|
||||
let video_id;
|
||||
|
||||
if (video[1] === 'youtube' || video[1] === 'youtube-nocookie') {
|
||||
video_id = video[4];
|
||||
}
|
||||
if (video[1] === 'youtu') {
|
||||
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`);
|
||||
}
|
||||
}
|
||||
if (video[1] === 'youtube' || video[1] === 'youtube-nocookie') {
|
||||
video_id = video[4];
|
||||
}
|
||||
if (video[1] === 'youtu') {
|
||||
video_id = video[3];
|
||||
}
|
||||
|
||||
show(src) {
|
||||
const ui = this;
|
||||
ui.$_el[0].innerHTML = '';
|
||||
ui.$_el.append(`<img src="${src}" alt="Video" />`);
|
||||
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;
|
||||
}
|
||||
|
||||
static dispose() {
|
||||
console.log(`Destroying: ${NAME}`);
|
||||
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);
|
||||
}
|
||||
});
|
||||
if (video_id) {
|
||||
ui.show(`//i3.ytimg.com/vi/${video_id}/0.jpg`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// jQuery interface
|
||||
$.fn[NAME] = VideoPreviewUI._jQueryInterface;
|
||||
$.fn[NAME].Constructor = VideoPreviewUI;
|
||||
$.fn[NAME].noConflict = () => {
|
||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||
return VideoPreviewUI._jQueryInterface;
|
||||
};
|
||||
show(src) {
|
||||
const ui = this;
|
||||
ui.$_el[0].innerHTML = '';
|
||||
ui.$_el.append(`<img src="${src}" alt="Video" />`);
|
||||
}
|
||||
|
||||
// auto-apply
|
||||
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
||||
$('[data-video-preview="true"]').jsVideoPreviewUI();
|
||||
});
|
||||
static dispose() {
|
||||
console.log(`Destroying: ${NAME}`);
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user