projects/i-components/src/lib/utils/validation-helper.ts
Provides a mechanism to display error messages linked to a specific DOM element.
Properties |
|
Methods |
|
constructor(elementRef: ElementRef
|
|||||||||
Creates an instance of ValidationHelper.
Parameters :
|
Private focusInListener |
Type : function
|
Default value : null
|
Listener of the focus-in on the owner element to show the validation message. |
Private focusOutListener |
Type : function
|
Default value : null
|
Listener of the focus-out on the owner element to hide the validation message. |
Public isRounded |
Default value : false
|
Used to determine if validation should be displayed rounded or not. |
Private messageToShow |
Type : string
|
Default value : null
|
Current message to show on mouse over or on focus. |
Private mouseLeaveListener |
Type : function
|
Default value : null
|
Listener of the mouse leave on the corner div to hide the validation message. |
Private mouseOverListener |
Type : function
|
Default value : null
|
Listener of the mouse over the corner div to show the validation message. |
Private ownerTarget |
Type : HTMLElement
|
Default value : null
|
Reference to the owner being targeted to show the validation messages. |
Private renderer2 |
Type : Renderer2
|
Angular's Renderer2. |
Private validationMessageInstance |
Type : any
|
Default value : null
|
Reference to the current validation message instance being shown. |
Protected createCornerDiv | ||||||
createCornerDiv(size: string)
|
||||||
Creates the corner div that will work as a visual clue to see validations message.
Parameters :
Returns :
HTMLDivElement
{HTMLDivElement} |
Protected hideValidationMessage |
hideValidationMessage()
|
Hides the current validation message.
Returns :
void
|
Public registerValidationMsgService | ||||||||||||||||||||
registerValidationMsgService(message: string, size: string, applyTo?: string, initiallyHide)
|
||||||||||||||||||||
Register the validation message service with the owner target to provide the popup and other visual cues of the error.
Parameters :
Returns :
void
{void} |
Protected showValidationMessage |
showValidationMessage()
|
Shows the current validation message.
Returns :
void
|
Public unregisterValidationMsgService |
unregisterValidationMsgService()
|
Unregister the validation message service and executes a clean up of other elements.
Returns :
void
|
Public updateValidationMsgService |
updateValidationMsgService(message: string, size: string, applyTo: string)
|
It updates the informationg used by the validation directive given a registration already exists.
Returns :
void
|
import {
ApplicationRef,
ComponentFactoryResolver,
ElementRef,
Injector,
Renderer2,
ViewContainerRef,
} from '@angular/core';
import { ValidationMessageServiceComponent } from '../components/validation-message-service/validation-message-service.component';
/**
* Provides a mechanism to display error messages linked to a specific DOM element.
*
* @export
* @class ValidationHelper
*/
export class ValidationHelper {
/**
* Current message to show on mouse over or on focus.
*
* @private
* @type {string}
* @memberof ValidationHelper
*/
private messageToShow: string = null;
/**
* Reference to the current validation message instance being shown.
*
* @private
* @type {*}
* @memberof ValidationHelper
*/
private validationMessageInstance: any = null;
/**
* Reference to the owner being targeted to show the validation messages.
*
* @private
* @type {HTMLElement}
* @memberof ValidationHelper
*/
private ownerTarget: HTMLElement = null;
/**
* Angular's Renderer2.
*
* @private
* @type {Renderer2}
* @memberof ValidationHelper
*/
private renderer2: Renderer2;
/**
* Used to determine if validation should be displayed rounded or not.
*
* @public
* @type {boolean}
* @memberof ValidationHelper
*/
public isRounded = false;
/**
* Listener of the mouse over the corner div to show the validation message.
*
* @private
* @memberof ValidationHelper
*/
private mouseOverListener: () => void = null;
/**
* Listener of the mouse leave on the corner div to hide the validation message.
*
* @private
* @memberof ValidationHelper
*/
private mouseLeaveListener: () => void = null;
/**
* Listener of the focus-in on the owner element to show the validation message.
*
* @private
* @memberof ValidationHelper
*/
private focusInListener: () => void = null;
/**
* Listener of the focus-out on the owner element to hide the validation message.
*
* @private
* @memberof ValidationHelper
*/
private focusOutListener: () => void = null;
/**
* Creates an instance of ValidationHelper.
*
* @param {ElementRef<HTMLElement>} elementRef
* @param {Injector} injectorBase
* @memberof ValidationHelper
*/
constructor(
private elementRef: ElementRef<HTMLElement>,
private injectorBase: Injector
) {
this.renderer2 = injectorBase.get(Renderer2);
}
/**
* Register the validation message service with the owner target
* to provide the popup and other visual cues of the error.
*
* @param {string} message
* @param {string} [size='7px']
* @param {string} [applyTo]
* @param {boolean} [initiallyHide=false]
* @return {*} {void}
* @memberof ValidationHelper
*/
public registerValidationMsgService(
message: string,
size = '7px',
applyTo?: string,
initiallyHide = false
): void {
/* istanbul ignore else */
if (this.ownerTarget != null) {
this.updateValidationMsgService(message, size, applyTo);
return;
}
this.unregisterValidationMsgService();
this.ownerTarget =
applyTo != null
? this.elementRef.nativeElement.querySelector(applyTo)
: this.elementRef.nativeElement;
/* istanbul ignore else */
if (!!this.ownerTarget) {
// Add border to indicate an error.
this.isRounded
? this.ownerTarget.classList.add('validationBorderErrorRounded')
: this.ownerTarget.classList.add('validationBorderError');
// Add corner cue.
const cornerDiv = this.createCornerDiv(size);
this.ownerTarget.appendChild(cornerDiv);
this.messageToShow = message;
this.mouseOverListener = this.renderer2.listen(
cornerDiv,
'mouseover',
this.showValidationMessage.bind(this)
);
this.focusInListener = this.renderer2.listen(
this.ownerTarget,
'focusin',
this.showValidationMessage.bind(this)
);
this.mouseLeaveListener = this.renderer2.listen(
cornerDiv,
'mouseleave',
this.hideValidationMessage.bind(this)
);
this.focusOutListener = this.renderer2.listen(
this.ownerTarget,
'focusout',
this.hideValidationMessage.bind(this)
);
/* istanbul ignore else */
if (!initiallyHide && this.ownerTarget.contains(document.activeElement)) {
// Currently the element has the focus.
this.showValidationMessage();
}
}
}
/**
* It updates the informationg used by the validation directive
* given a registration already exists.
*
* @param {string} message
* @param {string} size
* @param {string} applyTo
* @memberof ValidationHelper
*/
public updateValidationMsgService(
message: string,
size: string,
applyTo: string
): void {
this.messageToShow = message;
/* istanbul ignore else */
if (this.validationMessageInstance != null) {
this.validationMessageInstance.instance.message = this.messageToShow;
this.validationMessageInstance.changeDetectorRef.detectChanges();
}
}
/**
* Unregister the validation message service and executes
* a clean up of other elements.
*
* @memberof ValidationHelper
*/
public unregisterValidationMsgService(): void {
let validationBorderError = 'validationBorderError';
let validationCornerError = '.validationCornerError';
if (this.isRounded) {
validationBorderError = 'validationBorderErrorRounded';
validationCornerError = '.validationCornerErrorRounded';
}
this.ownerTarget?.classList.remove(validationBorderError);
const cornerDiv = this.ownerTarget?.querySelector(validationCornerError);
cornerDiv?.remove();
this.ownerTarget = null;
this.messageToShow = null;
this.mouseOverListener?.();
this.mouseOverListener = null;
this.mouseLeaveListener?.();
this.mouseLeaveListener = null;
this.focusInListener?.();
this.focusInListener = null;
this.focusOutListener?.();
this.focusOutListener = null;
this.hideValidationMessage();
}
/**
* Shows the current validation message.
*
* @protected
* @return {*}
* @memberof ValidationHelper
*/
protected showValidationMessage() {
/* istanbul ignore else */
if (this.validationMessageInstance) {
return;
}
const appRef = this.injectorBase.get(ApplicationRef);
const factoryResolver = this.injectorBase.get(ComponentFactoryResolver);
const root = appRef.components[0];
const appRootViewContainer = root.injector.get(ViewContainerRef);
const popupHostFactory = factoryResolver.resolveComponentFactory(
ValidationMessageServiceComponent
);
const popupHostComponentRef = popupHostFactory.create(root.injector);
appRootViewContainer.insert(popupHostComponentRef.hostView);
this.validationMessageInstance = popupHostComponentRef;
this.validationMessageInstance.instance.ownerTargetRect =
this.ownerTarget.getBoundingClientRect();
this.validationMessageInstance.instance.message = this.messageToShow;
this.validationMessageInstance.changeDetectorRef.detectChanges();
}
/**
* Hides the current validation message.
*
* @protected
* @memberof ValidationHelper
*/
protected hideValidationMessage() {
this.validationMessageInstance?.destroy?.();
this.validationMessageInstance?.changeDetectorRef?.detectChanges();
this.validationMessageInstance = null;
}
/**
* Creates the corner div that will work as a
* visual clue to see validations message.
*
* @protected
* @param {string} size
* @return {*} {HTMLDivElement}
* @memberof ValidationHelper
*/
protected createCornerDiv(size: string): HTMLDivElement {
const div = document.createElement('div');
this.isRounded
? div.classList.add('validationCornerErrorRounded')
: div.classList.add('validationCornerError');
div.style.width = size;
div.style.height = size;
return div;
}
}