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

216 lines
5.2 KiB
JavaScript
Raw Normal View History

2022-05-03 20:50:57 +02:00
'use strict'
2020-12-24 23:42:33 +01:00
2022-05-03 20:50:57 +02:00
import $ from 'jquery'
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
2022-05-03 20:50:57 +02:00
const NAME = 'jsFormValidateField'
const DATA_KEY = NAME
const $Body = $('body')
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
const FieldUI = 'jsFormFieldUI'
2020-07-24 20:13:25 +02:00
class FormValidateField {
2022-05-03 20:50:57 +02:00
constructor (el) {
const ui = this
const $el = $(el)
2022-05-03 20:50:57 +02:00
ui.$el = $el
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +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)
2022-05-03 20:50:57 +02:00
$el.attr('novalidate', 'novalidate')
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
$el.on('change focusout', (e) => {
ui.validate(false)
})
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
$el.addClass(`${NAME}-active`)
$el.trigger(Events.FORM_INIT_VALIDATE_FIELD)
2020-07-24 20:13:25 +02:00
}
2020-07-24 20:13:25 +02:00
// Public methods
2022-05-03 20:50:57 +02:00
dispose () {
const $el = ui.$el
2020-07-24 20:13:25 +02:00
2022-05-03 20:50:57 +02:00
$el.removeClass(`${NAME}-active`)
$.removeData(ui.$el[0], DATA_KEY)
ui.$el = null
2020-07-24 20:13:25 +02:00
}
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
validate (scrollTo = true) {
const ui = this
const $el = ui.$el
2019-07-10 20:59:57 +02:00
2022-05-03 20:50:57 +02:00
const $field = $el.closest('.field')
const extraChecks = $el.data(`${NAME}-extra`)
let valid = true
let msg = null
2020-07-24 20:13:25 +02:00
2022-05-03 20:50:57 +02:00
const val = $el.val()
2020-07-24 20:13:25 +02:00
2020-09-02 00:12:38 +02:00
// browser checks
if (!ui.$el[0].checkValidity()) {
2022-05-03 20:50:57 +02:00
valid = false
2020-11-05 08:57:23 +01:00
console.warn(
2022-05-03 20:50:57 +02:00
`${NAME}: Browser check validity is failed #${$el.attr('id')}`
)
2020-09-02 00:12:38 +02:00
}
2022-05-03 20:50:57 +02:00
let unmaskedVal = val
if (typeof $el.inputmask === 'function') {
unmaskedVal = $el.inputmask('unmaskedvalue')
2020-10-12 16:40:17 +02:00
}
2020-09-02 00:12:38 +02:00
// required
2020-07-24 20:13:25 +02:00
if (
2022-05-03 20:50:57 +02:00
$el.hasClass('required') &&
2020-10-12 16:40:17 +02:00
(!unmaskedVal.length ||
!unmaskedVal.trim().length ||
(ui.isHtml(val) && !$(unmaskedVal).text().length))
2020-07-24 20:13:25 +02:00
) {
2022-05-03 20:50:57 +02:00
valid = false
console.warn(`${NAME}: Required field is missing #${$el.attr('id')}`)
2020-07-24 20:13:25 +02:00
}
2019-06-08 17:20:51 +02:00
2020-07-24 20:13:25 +02:00
// validate URL
2020-11-17 01:26:30 +01:00
if (
2022-05-03 20:50:57 +02:00
$el.hasClass('url') &&
2020-11-17 01:26:30 +01:00
unmaskedVal.length &&
!ui.valideURL(unmaskedVal)
) {
2022-05-03 20:50:57 +02:00
valid = false
2020-10-11 18:09:12 +02:00
2020-07-24 20:13:25 +02:00
msg =
2022-05-03 20:50:57 +02:00
'Invalid URL: URL must start with http:// or https://. For example: https://your-domain.com/bla-bla/?p1=b&p2=a#tag'
console.warn(`${NAME}: Wrong URL #${$el.attr('id')}`)
2020-07-24 20:13:25 +02:00
}
2019-06-08 17:20:51 +02:00
2020-10-11 18:09:12 +02:00
// maxlength
2022-05-03 20:50:57 +02:00
const maxLength = $el.attr('maxlength')
2020-11-05 08:57:23 +01:00
if (unmaskedVal.length && maxLength && maxLength.length) {
if (unmaskedVal.length > maxLength) {
2022-05-03 20:50:57 +02:00
valid = false
2020-10-11 18:09:12 +02:00
2022-05-03 20:50:57 +02:00
msg = `The value is limited to ${maxLength} chars`
console.warn(`${NAME}: Too long value #${$el.attr('id')}`)
2020-10-11 18:09:12 +02:00
}
}
// minlength
2022-05-03 20:50:57 +02:00
const minLength = $el.attr('minlength')
2020-11-05 08:57:23 +01:00
if (unmaskedVal.length && minLength && minLength.length) {
if (unmaskedVal.length < minLength) {
2022-05-03 20:50:57 +02:00
valid = false
2020-10-11 18:09:12 +02:00
2022-05-03 20:50:57 +02:00
msg = `The value should contain more than ${minLength} chars`
console.warn(`${NAME}: Too short value #${$el.attr('id')}`)
2020-10-11 18:09:12 +02:00
}
}
2022-05-03 20:50:57 +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) => {
2022-05-03 20:50:57 +02:00
const result = check($el)
valid = valid && result
2020-09-02 00:12:38 +02:00
if (!result) {
2022-05-03 20:50:57 +02:00
console.log(check)
console.warn(`${NAME}: Extra check is failed #${$el.attr('id')}`)
2020-09-02 00:12:38 +02:00
}
2022-05-03 20:50:57 +02:00
})
2020-07-24 20:13:25 +02:00
}
if (valid) {
2022-05-03 20:50:57 +02:00
return true
2020-07-24 20:13:25 +02:00
}
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
this.setError(scrollTo, msg)
2020-07-24 20:13:25 +02:00
2022-05-03 20:50:57 +02:00
return false
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
isHtml (str) {
const doc = new DOMParser().parseFromString(str, 'text/html')
2020-07-24 20:13:25 +02:00
return Array.from(doc.body.childNodes).some(
2021-08-18 20:51:15 +02:00
(node) => node.nodeType === 1
2022-05-03 20:50:57 +02:00
)
2020-07-24 20:13:25 +02:00
}
2019-07-10 20:59:57 +02:00
2022-05-03 20:50:57 +02:00
valideURL (str) {
let url
2020-11-17 01:26:30 +01:00
try {
2022-05-03 20:50:57 +02:00
url = new URL(str)
2020-11-17 01:26:30 +01:00
} catch (_) {
2022-05-03 20:50:57 +02:00
return false
2020-11-17 01:26:30 +01:00
}
2022-05-03 20:50:57 +02:00
return url.protocol === 'http:' || url.protocol === 'https:'
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
setError (scrollTo = true, msg = null) {
const ui = this
const fieldUI = ui.$el.data(FieldUI)
2022-05-03 20:50:57 +02:00
const $field = ui.$el.closest('.field')
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
const bodyScroll = $Body.scrollTop()
const pos = $field[0].getBoundingClientRect().top // $field.offset().top;
2020-09-02 00:12:38 +02:00
2022-05-03 20:50:57 +02:00
const rowCorrection = parseInt($field.css('font-size')) * 4
ui.removeError()
2022-05-03 20:50:57 +02:00
$field.addClass('error')
2020-07-24 20:13:25 +02:00
if (msg) {
2022-05-03 20:50:57 +02:00
fieldUI.addMessage(msg, 'alert-error alert-danger', scrollTo)
2020-09-02 00:12:38 +02:00
} else if (pos && scrollTo) {
2022-05-03 20:50:57 +02:00
$field.focus()
$Body.scrollTop(bodyScroll + pos - rowCorrection)
2020-07-24 20:13:25 +02:00
}
}
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
removeError () {
const ui = this
const fieldUI = ui.$el.data(FieldUI)
2022-05-03 20:50:57 +02:00
const $field = ui.$el.closest('.field')
2020-07-24 20:13:25 +02:00
2022-05-03 20:50:57 +02:00
$field.removeClass('error')
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
$field.removeClass('holder-error')
$field.removeClass('holder-validation')
$field.find('.alert-error').remove()
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
static _jQueryInterface () {
2020-07-24 20:13:25 +02:00
return this.each(function () {
// attach functionality to el
2022-05-03 20:50:57 +02:00
const $el = $(this)
let data = $el.data(DATA_KEY)
2019-06-08 17:20:51 +02:00
if (!data) {
2022-05-03 20:50:57 +02:00
data = new FormValidateField(this)
$el.data(DATA_KEY, data)
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
})
2019-06-08 17:20:51 +02:00
}
}
// jQuery interface
2022-05-03 20:50:57 +02:00
$.fn[NAME] = FormValidateField._jQueryInterface
$.fn[NAME].Constructor = FormValidateField
2020-07-24 20:13:25 +02:00
$.fn[NAME].noConflict = function () {
2022-05-03 20:50:57 +02:00
$.fn[NAME] = JQUERY_NO_CONFLICT
return FormValidateField._jQueryInterface
}
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
return FormValidateField
})($)
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
export default FormValidateField