webpack-bootstrap-ui-kit/src/js/_components/_ui.form.validate.field.js

166 lines
3.9 KiB
JavaScript
Raw Normal View History

2019-06-08 17:20:51 +02:00
import $ from 'jquery';
2020-05-13 18:05:34 +02:00
import Events from '../_events';
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
const FormValidateField = (($) => {
2019-06-08 17:20:51 +02:00
// Constants
2020-07-24 20:13:25 +02:00
const NAME = 'jsFormValidateField';
2019-06-08 17:20:51 +02:00
const DATA_KEY = NAME;
const $Html = $('html, body');
2020-07-24 20:13:25 +02:00
const FieldUI = 'jsFormFieldUI';
class FormValidateField {
constructor(el) {
2019-06-08 17:20:51 +02:00
const ui = this;
2020-07-24 20:13:25 +02:00
const $el = $(el);
2020-07-24 20:13:25 +02:00
ui.$el = $el;
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
ui._actions = $el.parents('form').children('.btn-toolbar,.form-actions');
$el.data(DATA_KEY, this);
2019-06-08 17:20:51 +02:00
// prevent browsers checks (will do it using JS)
2020-07-24 20:13:25 +02:00
$el.attr('novalidate', 'novalidate');
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
$el.on('change focusout', (e) => {
ui.validate(false);
2019-06-08 17:20:51 +02:00
});
2020-07-24 20:13:25 +02:00
$el.addClass(`${NAME}-active`);
$el.trigger(Events.FORM_INIT_VALIDATE_FIELD);
}
2020-07-24 20:13:25 +02:00
// Public methods
dispose() {
const $el = ui.$el;
$el.removeClass(`${NAME}-active`);
$.removeData(ui.$el[0], DATA_KEY);
ui.$el = null;
}
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
validate(scrollTo = true) {
const ui = this;
const $el = ui.$el;
2019-07-10 20:59:57 +02:00
2020-07-24 20:13:25 +02:00
const $field = $el.closest('.field');
const extraChecks = $el.data(`${NAME}-extra`);
let valid = true;
let msg = null;
const val = $el.val();
// browser checks + required
if (
!ui.$el[0].checkValidity() ||
($el.hasClass('required') &&
(!val.length ||
!val.trim().length ||
(ui.isHtml(val) && !$(val).text().length)))
) {
valid = false;
}
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
// validate URL
if ($el.hasClass('url') && val.length && !this.valideURL(val)) {
valid = false;
msg =
'URL must start with http:// or https://. For example: https://your-domain.com/';
}
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
this.removeError();
2019-07-10 20:59:57 +02:00
2020-07-24 20:13:25 +02:00
// extra checks
if (extraChecks) {
extraChecks.forEach((check) => {
valid = valid && check();
2019-06-08 17:20:51 +02:00
});
2020-07-24 20:13:25 +02:00
}
if (valid) {
return true;
}
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
this.setError(scrollTo, msg);
return false;
2019-06-08 17:20:51 +02:00
}
2020-07-24 20:13:25 +02:00
isHtml(str) {
const doc = new DOMParser().parseFromString(str, 'text/html');
return Array.from(doc.body.childNodes).some(
(node) => node.nodeType === 1,
);
}
2019-07-10 20:59:57 +02:00
2020-07-24 20:13:25 +02:00
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);
2019-06-08 17:20:51 +02:00
}
2020-07-24 20:13:25 +02:00
setError(scrollTo = true, msg = null) {
2019-06-08 17:20:51 +02:00
const ui = this;
2020-07-24 20:13:25 +02:00
const fieldUI = ui.$el.data(FieldUI);
2020-07-24 20:13:25 +02:00
const $field = ui.$el.closest('.field');
const pos = $field.offset().top;
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
ui.removeError();
2020-07-24 20:13:25 +02:00
$field.addClass('error');
if (msg) {
fieldUI.addMessage(msg, 'alert-error alert-danger', scrollTo);
} else if (scrollTo) {
$field.focus();
$Html.scrollTop(pos - 100);
}
}
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
removeError() {
const ui = this;
const fieldUI = ui.$el.data(FieldUI);
2020-07-24 20:13:25 +02:00
const $field = ui.$el.closest('.field');
$field.removeClass('error');
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
$field.removeClass('holder-error');
$field.removeClass('holder-validation');
$field.find('.alert-error').remove();
2019-06-08 17:20:51 +02:00
}
static _jQueryInterface() {
2020-07-24 20:13:25 +02:00
return this.each(function () {
// attach functionality to el
const $el = $(this);
let data = $el.data(DATA_KEY);
2019-06-08 17:20:51 +02:00
if (!data) {
2020-07-24 20:13:25 +02:00
data = new FormValidateField(this);
$el.data(DATA_KEY, data);
2019-06-08 17:20:51 +02:00
}
});
}
}
// jQuery interface
2020-07-24 20:13:25 +02:00
$.fn[NAME] = FormValidateField._jQueryInterface;
$.fn[NAME].Constructor = FormValidateField;
$.fn[NAME].noConflict = function () {
2019-06-08 17:20:51 +02:00
$.fn[NAME] = JQUERY_NO_CONFLICT;
2020-07-24 20:13:25 +02:00
return FormValidateField._jQueryInterface;
2019-06-08 17:20:51 +02:00
};
2020-07-24 20:13:25 +02:00
return FormValidateField;
2019-06-08 17:20:51 +02:00
})($);
2020-07-24 20:13:25 +02:00
export default FormValidateField;