Skip to content

Instantly share code, notes, and snippets.

@Dexdot
Created July 7, 2020 08:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dexdot/12f70b4a26b52014e1c33c77e5c75580 to your computer and use it in GitHub Desktop.
Save Dexdot/12f70b4a26b52014e1c33c77e5c75580 to your computer and use it in GitHub Desktop.
import IMask from 'imask';
export default class Input {
constructor(el) {
this.el = el;
this.input = $.qs('.input__field', this.el);
this.isDate = this.input.type === 'date';
this.isPhone = this.input.type === 'tel';
this.isMaskDate = this.input.classList.contains('js-mask-date');
this.isRuble = this.input.classList.contains('js-mask-ruble');
this.setup();
}
setup() {
this.mask();
this.keyup();
this.focus();
this.checkValid();
}
keyup() {
if (this.isDate) return false;
const check = () => {
if (this.input.value.length > 0) {
this.el.classList.add('input--filled');
} else {
this.el.classList.remove('input--filled');
}
};
this.checkLength();
this.input.addEventListener('keyup', this.checkLength.bind(this));
}
checkLength() {
if (this.input.value.length > 0) {
this.el.classList.add('input--filled');
} else {
this.el.classList.remove('input--filled');
}
}
focus() {
if (this.isDate) {
this.el.classList.add('input--focused');
return false;
}
this.input.addEventListener('focus', this.onFocus.bind(this));
this.input.addEventListener('focusout', this.onFocusout.bind(this));
}
onFocus() {
this.el.classList.add('input--focused');
}
onFocusout() {
this.el.classList.remove('input--focused');
}
removeInvalidClass() {
const condition = this.isPhone
? this.im.unmaskedValue.length < 11
: !this.input.validity.valid;
if (!condition) this.el.classList.remove('input--invalid');
}
onSubmit() {
const fieldset = this.el.closest('fieldset');
if (fieldset && fieldset.disabled) return false;
const condition = this.isPhone
? this.im.unmaskedValue.length < 11
: !this.input.validity.valid;
if (condition) {
this.el.classList.add('input--invalid');
} else {
this.el.classList.remove('input--invalid');
}
}
checkValid() {
if (this.isDate) return false;
const closestForm = this.input.closest('form');
if (!closestForm || (closestForm && !closestForm.noValidate)) return false;
this.closestForm = closestForm;
['focusout', 'keyup'].forEach(ev => {
this.input.addEventListener(ev, this.removeInvalidClass.bind(this));
});
this.closestForm.addEventListener('submit', this.onSubmit.bind(this));
}
mask() {
if (this.isPhone) {
this.im = IMask(this.input, { mask: '+0{(}000{)}000{-}00{-}00' });
}
if (this.isMaskDate) {
this.im = IMask(this.input, { mask: '00{.}00{.}0000' });
}
if (this.isRuble) {
this.im = IMask(this.input, {
mask: '₽ num',
blocks: {
num: {
mask: Number,
thousandsSeparator: ' '
}
}
});
}
}
destroy() {
this.input.removeEventListener('keyup', this.checkLength);
this.input.addEventListener('focus', this.onFocus);
this.input.addEventListener('focusout', this.onFocusout);
['focusout', 'keyup'].forEach(ev => {
this.input.removeEventListener(ev, this.removeInvalidClass);
});
if (this.closestForm)
this.closestForm.removeEventListener('submit', this.onSubmit);
if (this.im) this.im.destroy();
}
}
+input('Дата', 'input--date')(required name="date" type="date")
+svg('calendar').input__icon
.input--date
.input__field
z-index: 1
position: relative
&::-webkit-inner-spin-button,
&::-webkit-calendar-picker-indicator
-webkit-appearance: none
opacity: 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment