enum FieldStatusEvents { Pending = "field-status-pending", Success = "field-status-success", Error = "field-status-error", Invalid = "field-status-invalid", }; class LocalizedStatusStrings { private _locale: 'ru' | 'en' = 'ru' private _strings = { statusLocale: { 'ru': ' locale-ru ', 'en': ' locale-en ' } } constructor() { this._locale = $('.page-wrapper').data('lang') || 'ru' } public get getLocaleClass(): string { return this._strings.statusLocale[this._locale] } } /** * Выводит иконку возле инпута либо формы - статус сохранения. */ class FieldStatusShower { static baseClass = "field-status "; static successClass = " field-status field-success "; static errorClass = " field-status field-error "; static pendingClass = " field-status field-pending "; static invalidClass = " field-status field-invalid"; static right35 = "status-r-35"; static hideOnInputChange = true; static localizedStatusStrings /** * Подписывается на реагирование на все типы событий от троттлера и кастомной части */ public static subscribeAll() { this.localizedStatusStrings = new LocalizedStatusStrings() this.subscribeFieldsEvents(); this.subscribePatchThrottler(); if (this.hideOnInputChange) { this.enableHideOnInputChange(); } } /** * Скрывать старые статусы, при изменении инпута и клике! */ public static enableHideOnInputChange() { $(document).on('change', 'input, textarea, select', (e) => { $(`.${this.baseClass}`) .not($(e.currentTarget).parents(`.${this.baseClass}`)) .not(e.currentTarget) .removeClass( this.errorClass + this.pendingClass + this.successClass ); }); } /** * Подписка на ивенты, которые присылает троттлер */ public static subscribePatchThrottler() { document.addEventListener(JsonPatchSaveStatuses.Pending, (event: CustomEvent) => { this.showStatus(this.getLabelFromJsonPatcher(event.detail as any), this.pendingClass); }); document.addEventListener(JsonPatchSaveStatuses.Success, (event: CustomEvent) => { this.showStatus(this.getLabelFromJsonPatcher(event.detail as any), this.successClass + this.localizedStatusStrings.getLocaleClass); }); document.addEventListener(JsonPatchSaveStatuses.Error, (event: CustomEvent) => { this.showStatus(this.getLabelFromJsonPatcher(event.detail as any), this.errorClass + this.localizedStatusStrings.getLocaleClass); }); document.addEventListener(JsonPatchSaveStatuses.Invalid, (event: CustomEvent) => { this.showStatus(this.getLabelFromJsonPatcher(event.detail as any), this.invalidClass + this.localizedStatusStrings.getLocaleClass); }); } /** * Подписка на ивенты, которые сами себе же и отправляем=) */ public static subscribeFieldsEvents() { document.addEventListener(FieldStatusEvents.Pending, (event: CustomEvent) => { this.showStatus(this.getLabelFromCustomPart(event.detail as any), this.pendingClass); }); document.addEventListener(FieldStatusEvents.Success, (event: CustomEvent) => { this.showStatus(this.getLabelFromCustomPart(event.detail as any), this.successClass + this.localizedStatusStrings.getLocaleClass); }); document.addEventListener(FieldStatusEvents.Error, (event: CustomEvent) => { this.showStatus(this.getLabelFromCustomPart(event.detail as any), this.errorClass + this.localizedStatusStrings.getLocaleClass); }); document.addEventListener(FieldStatusEvents.Invalid, (event: CustomEvent) => { this.showStatus(this.getLabelFromCustomPart(event.detail as any), this.invalidClass + this.localizedStatusStrings.getLocaleClass); }); } /** * Поиск нужного элемента(лэйбла) которому навесим иконку справа для патчера */ public static getLabelFromJsonPatcher(rawInput: HTMLElement): JQuery { var input = $(rawInput); var label = input.parents(".custom-input-wrapper"); return label; } /** * Поиск нужного элемента(лэйбла) которому навесим иконку справа для кастомной части на заявке */ public static getLabelFromCustomPart(rawInput: HTMLElement): JQuery { var input = $(rawInput); var label = input.closest(".custom-input-wrapper"); if (!label || label.length <= 0) { label = input.parents("form"); } return label; } /** * Отправить ивент себе же=) */ public static sendEvent(rawInput: HTMLElement) { document.dispatchEvent(new CustomEvent(FieldStatusEvents.Error, { detail: rawInput } as any)); } /** * Отобразить непосредственно иконку на лейбле */ private static showStatus(label: JQuery, className: string) { if (label && label.length > 0) { label.removeClass( this.errorClass + this.pendingClass + this.successClass + this.invalidClass ); label.addClass(className); if (className == this.pendingClass) { this.addEditIconToElement(label); } else { this.removeEditIconFromElement(label); } } else { console.error("Не смогли найти лэйбл для элемента : " + label); } } private static addEditIconToElement(input: JQuery) { let isIcon = 0; if ($(input).hasClass("inputbox")) { isIcon = $(input).next("span.edit-icon-status").length; } else { isIcon = $(input).closest(".inputbox").find("span.edit-icon-status").length; } if (!isIcon) { let icon = this.createPendingIcon(input); $(input).append(icon); } } private static removeEditIconFromElement(input: JQuery) { $(input).find("span.edit-icon-status").remove(); } private static createPendingIcon(input: JQuery): HTMLSpanElement { let img = document.createElement("img"); let span = document.createElement("span"); span.className = "edit-icon-status"; span.appendChild(img); return span; } }