Minor updates
This commit is contained in:
parent
e6ee53b668
commit
caadf7d6af
|
@ -286,7 +286,7 @@ const AjaxUI = (($) => {
|
||||||
for (const url in $.xhrPool.requests) {
|
for (const url in $.xhrPool.requests) {
|
||||||
const jqXHR = $.xhrPool.requests[url];
|
const jqXHR = $.xhrPool.requests[url];
|
||||||
$.ajax(jqXHR.opts);
|
$.ajax(jqXHR.opts);
|
||||||
console.log(`AJAX request is restored (${jqXHR.opts.url})`);
|
//console.log(`AJAX request is restored (${jqXHR.opts.url})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.xhrPool.paused = false;
|
$.xhrPool.paused = false;
|
||||||
|
@ -297,7 +297,7 @@ const AjaxUI = (($) => {
|
||||||
beforeSend: (jqXHR) => {}, // and connection to list
|
beforeSend: (jqXHR) => {}, // and connection to list
|
||||||
complete: (jqXHR) => {
|
complete: (jqXHR) => {
|
||||||
if (!$.xhrPool.paused) {
|
if (!$.xhrPool.paused) {
|
||||||
console.log(`AJAX request is done (${jqXHR.opts.url})`);
|
//console.log(`AJAX request is done (${jqXHR.opts.url})`);
|
||||||
delete $.xhrPool.requests[jqXHR.opts.url];
|
delete $.xhrPool.requests[jqXHR.opts.url];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import 'croppie/croppie.js';
|
||||||
import 'exif-js/exif.js';
|
import 'exif-js/exif.js';
|
||||||
|
|
||||||
const CroppieUI = (($) => {
|
const CroppieUI = (($) => {
|
||||||
|
|
||||||
const NAME = 'jsCroppieUI';
|
const NAME = 'jsCroppieUI';
|
||||||
const DATA_KEY = NAME;
|
const DATA_KEY = NAME;
|
||||||
|
|
||||||
|
@ -28,11 +27,12 @@ const CroppieUI = (($) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
class CroppieUI {
|
class CroppieUI {
|
||||||
|
|
||||||
constructor(element) {
|
constructor(element) {
|
||||||
const ui = this;
|
const ui = this;
|
||||||
const $el = $(element);
|
const $el = $(element);
|
||||||
|
|
||||||
|
console.log(`${NAME}: init ...`);
|
||||||
|
|
||||||
ui.$el = $el;
|
ui.$el = $el;
|
||||||
$el.data(DATA_KEY, this);
|
$el.data(DATA_KEY, this);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ const CroppieUI = (($) => {
|
||||||
|
|
||||||
$el.append(
|
$el.append(
|
||||||
'<div class="cropper-wrap"><div class="cropper-container"></div>' +
|
'<div class="cropper-wrap"><div class="cropper-container"></div>' +
|
||||||
'<a href="#" class="btn-remove" style="display:none"><i class="fas fa-times"></i> Remove</a></div>'
|
'<a href="#" class="btn-remove" style="display:none"><i class="fas fa-times"></i> Remove</a></div>',
|
||||||
);
|
);
|
||||||
//$el.append(ui.inputData);
|
//$el.append(ui.inputData);
|
||||||
|
|
||||||
|
@ -102,103 +102,127 @@ const CroppieUI = (($) => {
|
||||||
ui.uploadCrop.show();
|
ui.uploadCrop.show();
|
||||||
ui.uploadCropWrap.show();
|
ui.uploadCropWrap.show();
|
||||||
ui.$btnRemove.show();
|
ui.$btnRemove.show();
|
||||||
}
|
};
|
||||||
|
|
||||||
reader.readAsDataURL(input.files[0]);
|
reader.readAsDataURL(input.files[0]);
|
||||||
|
|
||||||
|
$form.off('submit');
|
||||||
$form.on('submit', (e) => {
|
$form.on('submit', (e) => {
|
||||||
//$(input).val('');
|
console.log(`${NAME}: Processing submission ...`);
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if ($form.data('locked')) {
|
||||||
|
console.warn(`${NAME}: Form#${$form.attr('id')} is locked.`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$form.data('locked', true);
|
||||||
|
|
||||||
SpinnerUI.show();
|
SpinnerUI.show();
|
||||||
|
|
||||||
if (!ui.uploadCrop.hasClass('ready')) {
|
if (!ui.uploadCrop.hasClass('ready')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.uploadCrop.croppie('result', {
|
ui.uploadCrop
|
||||||
type: 'blob',
|
.croppie('result', {
|
||||||
size: {
|
type: 'blob',
|
||||||
width: ui.width,
|
size: {
|
||||||
height: ui.height,
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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['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);
|
|
||||||
},
|
},
|
||||||
|
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) {
|
||||||
|
$form.data('locked', false);
|
||||||
|
|
||||||
|
let IS_JSON = false;
|
||||||
|
let json = {};
|
||||||
|
try {
|
||||||
|
IS_JSON = true;
|
||||||
|
json = $.parseJSON(data);
|
||||||
|
} catch (e) {
|
||||||
|
IS_JSON = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_JSON) {
|
||||||
|
if (typeof json['status'] !== 'undefined') {
|
||||||
|
if (json['status'] === 'success') {
|
||||||
|
MainUI.alert(json['message'], json['status']);
|
||||||
|
|
||||||
|
if (typeof json['link'] !== 'undefined') {
|
||||||
|
console.log(
|
||||||
|
`${NAME}: Finished submission > JSON ... Redirecting to ${json['link']}.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
G.location = json['link'];
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`${NAME}: Finished submission > JSON no redirect link.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (json['status'] === 'error') {
|
||||||
|
MainUI.alert(json['message'], json['status']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof json['form'] !== 'undefined') {
|
||||||
|
console.log(
|
||||||
|
`${NAME}: Finished submission > JSON. Got new form response.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
$(form).replaceWith(json['form']);
|
||||||
|
$(G).trigger(Events.AJAX);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
`${NAME}: Finished submission > DATA response.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
$(form).replaceWith(data);
|
||||||
|
$(G).trigger(Events.AJAX);
|
||||||
|
//G.location.reload(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinnerUI.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//ui.inputData.val(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
//ui.inputData.val(data);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log('Sorry - your browser doesn\'t support the FileReader API');
|
console.log(
|
||||||
|
`${NAME}: Sorry - your browser doesn't support the FileReader API.`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static dispose() {
|
static dispose() {
|
||||||
console.log(`Destroying: ${NAME}`);
|
console.log(`${NAME}: destroying.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _jQueryInterface() {
|
static _jQueryInterface() {
|
||||||
|
|
|
@ -5,7 +5,7 @@ const FormValidateField = (($) => {
|
||||||
// Constants
|
// Constants
|
||||||
const NAME = 'jsFormValidateField';
|
const NAME = 'jsFormValidateField';
|
||||||
const DATA_KEY = NAME;
|
const DATA_KEY = NAME;
|
||||||
const $Html = $('html, body');
|
const $Body = $('body');
|
||||||
|
|
||||||
const FieldUI = 'jsFormFieldUI';
|
const FieldUI = 'jsFormFieldUI';
|
||||||
|
|
||||||
|
@ -50,15 +50,21 @@ const FormValidateField = (($) => {
|
||||||
|
|
||||||
const val = $el.val();
|
const val = $el.val();
|
||||||
|
|
||||||
// browser checks + required
|
// browser checks
|
||||||
|
if (!ui.$el[0].checkValidity()) {
|
||||||
|
valid = false;
|
||||||
|
console.warn(`Browser check validity is failed #${$el.attr('id')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// required
|
||||||
if (
|
if (
|
||||||
!ui.$el[0].checkValidity() ||
|
$el.hasClass('required') &&
|
||||||
($el.hasClass('required') &&
|
(!val.length ||
|
||||||
(!val.length ||
|
!val.trim().length ||
|
||||||
!val.trim().length ||
|
(ui.isHtml(val) && !$(val).text().length))
|
||||||
(ui.isHtml(val) && !$(val).text().length)))
|
|
||||||
) {
|
) {
|
||||||
valid = false;
|
valid = false;
|
||||||
|
console.warn(`Required field is missing #${$el.attr('id')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate URL
|
// validate URL
|
||||||
|
@ -66,6 +72,7 @@ const FormValidateField = (($) => {
|
||||||
valid = false;
|
valid = false;
|
||||||
msg =
|
msg =
|
||||||
'URL must start with http:// or https://. For example: https://your-domain.com/';
|
'URL must start with http:// or https://. For example: https://your-domain.com/';
|
||||||
|
console.warn(`Wrong URL #${$el.attr('id')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeError();
|
this.removeError();
|
||||||
|
@ -73,7 +80,12 @@ const FormValidateField = (($) => {
|
||||||
// extra checks
|
// extra checks
|
||||||
if (extraChecks) {
|
if (extraChecks) {
|
||||||
extraChecks.forEach((check) => {
|
extraChecks.forEach((check) => {
|
||||||
valid = valid && check();
|
const result = check();
|
||||||
|
valid = valid && result;
|
||||||
|
if (!result) {
|
||||||
|
console.log(check);
|
||||||
|
console.warn(`Extra check is failed #${$el.attr('id')}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,16 +123,19 @@ const FormValidateField = (($) => {
|
||||||
const fieldUI = ui.$el.data(FieldUI);
|
const fieldUI = ui.$el.data(FieldUI);
|
||||||
|
|
||||||
const $field = ui.$el.closest('.field');
|
const $field = ui.$el.closest('.field');
|
||||||
const pos = $field.offset().top;
|
|
||||||
|
|
||||||
|
const bodyScroll = $Body.scrollTop();
|
||||||
|
const pos = $field[0].getBoundingClientRect().top; //$field.offset().top;
|
||||||
|
|
||||||
|
const rowCorrection = parseInt($field.css('font-size')) * 4;
|
||||||
ui.removeError();
|
ui.removeError();
|
||||||
|
|
||||||
$field.addClass('error');
|
$field.addClass('error');
|
||||||
if (msg) {
|
if (msg) {
|
||||||
fieldUI.addMessage(msg, 'alert-error alert-danger', scrollTo);
|
fieldUI.addMessage(msg, 'alert-error alert-danger', scrollTo);
|
||||||
} else if (scrollTo) {
|
} else if (pos && scrollTo) {
|
||||||
$field.focus();
|
$field.focus();
|
||||||
$Html.scrollTop(pos - 100);
|
$Body.scrollTop(bodyScroll + pos - rowCorrection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,6 @@ const FormValidate = (($) => {
|
||||||
SpinnerUI.hide();
|
SpinnerUI.hide();
|
||||||
|
|
||||||
ui.$element.addClass('error');
|
ui.$element.addClass('error');
|
||||||
console.log('Invalid form data:');
|
|
||||||
console.log($el);
|
|
||||||
|
|
||||||
if (badCallback) {
|
if (badCallback) {
|
||||||
badCallback();
|
badCallback();
|
||||||
|
@ -101,7 +99,7 @@ const FormValidate = (($) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
static _jQueryInterface() {
|
static _jQueryInterface() {
|
||||||
return this.each(function() {
|
return this.each(function () {
|
||||||
// attach functionality to element
|
// attach functionality to element
|
||||||
const $element = $(this);
|
const $element = $(this);
|
||||||
let data = $element.data(DATA_KEY);
|
let data = $element.data(DATA_KEY);
|
||||||
|
@ -117,7 +115,7 @@ const FormValidate = (($) => {
|
||||||
// jQuery interface
|
// jQuery interface
|
||||||
$.fn[NAME] = FormValidate._jQueryInterface;
|
$.fn[NAME] = FormValidate._jQueryInterface;
|
||||||
$.fn[NAME].Constructor = FormValidate;
|
$.fn[NAME].Constructor = FormValidate;
|
||||||
$.fn[NAME].noConflict = function() {
|
$.fn[NAME].noConflict = function () {
|
||||||
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
||||||
return FormValidate._jQueryInterface;
|
return FormValidate._jQueryInterface;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AJAX: 'ajax-load',
|
AJAX: 'ajax-load',
|
||||||
|
AJAXMAIN: 'ajax-main-load',
|
||||||
|
MAININIT: 'main-init',
|
||||||
TABHIDDEN: 'tab-hidden',
|
TABHIDDEN: 'tab-hidden',
|
||||||
TABFOCUSED: 'tab-focused',
|
TABFOCUSED: 'tab-focused',
|
||||||
OFFLINE: 'offline',
|
OFFLINE: 'offline',
|
||||||
|
|
|
@ -327,6 +327,7 @@ const MainUI = (($) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
$Body.data(NAME, this);
|
$Body.data(NAME, this);
|
||||||
|
$(W).removeClass('lock-main-init');
|
||||||
}
|
}
|
||||||
|
|
||||||
static detectBootstrapScreenSize() {
|
static detectBootstrapScreenSize() {
|
||||||
|
@ -467,6 +468,24 @@ const MainUI = (($) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// replace img src
|
||||||
|
$Body
|
||||||
|
.find('[data-src-replace]')
|
||||||
|
.not('.loaded')
|
||||||
|
.each((i, el) => {
|
||||||
|
const $el = $(el);
|
||||||
|
const lazySrc = $el.data('src-replace');
|
||||||
|
|
||||||
|
if ($el.hasClass('loaded')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lazySrc && lazySrc.length) {
|
||||||
|
$el.addClass('loaded');
|
||||||
|
$el.attr('src', lazySrc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load defined images
|
// load defined images
|
||||||
AjaxUI.preload($imgUrls).then(() => {
|
AjaxUI.preload($imgUrls).then(() => {
|
||||||
$(W).trigger('images-loaded');
|
$(W).trigger('images-loaded');
|
||||||
|
@ -487,9 +506,20 @@ const MainUI = (($) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => {
|
$(W).on(
|
||||||
MainUI.init();
|
`${Events.MAININIT} ${Events.AJAX} ${Events.AJAXMAIN} ${Events.LOADED}`,
|
||||||
});
|
() => {
|
||||||
|
const $w = $(W);
|
||||||
|
|
||||||
|
if ($w.hasClass('lock-main-init')) {
|
||||||
|
console.warn('MainUI is locked');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$w.addClass('lock-main-init');
|
||||||
|
MainUI.init();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
$(W).on(`${Events.RESIZE}`, () => {
|
$(W).on(`${Events.RESIZE}`, () => {
|
||||||
MainUI.detectBootstrapScreenSize();
|
MainUI.detectBootstrapScreenSize();
|
||||||
|
|
|
@ -17,6 +17,7 @@ $carousel-controls-font-size: 3rem;
|
||||||
$carousel-controls-zindex: 11 !default;
|
$carousel-controls-zindex: 11 !default;
|
||||||
$carousel-controls-shadow: 1px 1px $black !default;
|
$carousel-controls-shadow: 1px 1px $black !default;
|
||||||
$carousel-controls-hover-bg: transparentize($black, 0.4) !default;
|
$carousel-controls-hover-bg: transparentize($black, 0.4) !default;
|
||||||
|
$carousel-slide-img-loading-max-height: 25vh !default;
|
||||||
|
|
||||||
.carousel-slide {
|
.carousel-slide {
|
||||||
min-height: $carousel-slide-min-height;
|
min-height: $carousel-slide-min-height;
|
||||||
|
@ -37,6 +38,10 @@ $carousel-controls-hover-bg: transparentize($black, 0.4) !default;
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.loading {
|
||||||
|
max-height: $carousel-slide-img-loading-max-height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-control-prev,
|
.carousel-control-prev,
|
||||||
|
|
|
@ -178,25 +178,15 @@ textarea,
|
||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@media (min-width: map-get($grid-breakpoints, 'sm')) {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.typography {
|
.typography {
|
||||||
flex: 1 1;
|
flex: 1 1;
|
||||||
}
|
}
|
||||||
.btn-close {
|
.btn-close {
|
||||||
position: absolute;
|
margin-left: 1rem;
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
@media (min-width: map-get($grid-breakpoints, 'sm')) {
|
|
||||||
position: static;
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue