import { ChangeDetectorRef, EventEmitter } from '@angular/core'; import { InputCommandsAction, InputCommandsType, InputConfigNameStringEnum, InputStringEnum, } from '../enums'; import { ThousandSeparatorPipe } from '../../../pipes/thousand-separator.pipe'; import moment from 'moment'; import { InputConstants } from '../utils/constants'; import { InputChangeValue, InputSvgRoutes } from '../utils'; import { CaInputValidationService } from '../services'; import { CaInputBaseHelpersComponent } from '../base-classes/ca-input-base-helpres'; import { EventInputManager } from './ca-input-event-manager'; import { CommandsEvent } from '../models'; import { ICaInput } from '../config'; export abstract class CaInputBaseComponent extends CaInputBaseHelpersComponent { abstract focusInputEvent: EventEmitter; abstract handleToggleDropdownOptions: EventEmitter; // #region abstract variables abstract isFocusInput: boolean; abstract isTouchedInput: boolean; // Input Commands abstract isVisibleCommands: boolean; // Edit Input abstract isEditInput: boolean; abstract isDropdownToggler: boolean; abstract isCapsLockOn: boolean; // #endregion // #region abstract events abstract setCommandEvent: EventInputManager; abstract setClearInputEvent: EventInputManager; abstract setIncorrectInput: EventInputManager; abstract setBlurInput: EventInputManager; abstract setChangeInput: EventInputManager; abstract setShowHideDropdown: EventInputManager; abstract setDropDownKeyNavigation: EventInputManager<{ keyCode: number; data: ICaInput | null; }>; // #endregion public inputSelection: boolean = false; public cursorInputPosition!: number; public hasDecimalIndex: number = -1; public originPriceSeparatorLimit!: number | undefined; public timeoutCleaner!: ReturnType | number; public lastCursorSpacePosition: number = 0; private preventBlur!: boolean; public passwordTimeout!: ReturnType | number; public isDotDeleted!: boolean; abstract incorrectValue: boolean; // Dropdown public showDateInput: boolean = false; public dateTimeInputDate: Date = new Date(); // Number of spaces public numberOfConsecutivelySpaces: number = 0; abstract caInputValidationService: CaInputValidationService; constructor( public cdRef: ChangeDetectorRef, public thousandSeparatorPipe: ThousandSeparatorPipe ) { super(); } public transformText(value: string, isPaste?: boolean): void { this.cursorInputPosition = this.input.nativeElement.selectionStart; // Handle paste operation if (isPaste) { this.handlePaste(value); } else if (value) { this.superControl.control?.patchValue(value, { emitEvent: false }); } this.applyTextTransformation(); // Apply thousand and price separators if configured this.applyThousandSeparator(); this.applyPriceSeparator(); this.customValidation(value); this.sanitizeConsecutiveSpaces(); this.removeLeadingZero(); } private handlePaste(value: string): void { let mainValue = this.superControl.control?.value; if (!this.inputSelection) { mainValue += value; this.limitInputLength(); } else { mainValue = value; this.inputSelection = false; } // Delete spaces on begin and end mainValue = mainValue.trim(); this.superControl.control?.patchValue(mainValue, { emitEvent: false, }); } private limitInputLength(): void { if ( this.superControl.control?.value.length > this._inputConfig.maxLength! ) { this.superControl.control?.patchValue( this.superControl.control?.value.substring( 0, this._inputConfig.maxLength ), { emitEvent: false, } ); } } private applyTextTransformation(): void { let { value } = this.input.nativeElement; switch (this._inputConfig.textTransform) { case InputStringEnum.CAPITALIZE: value = value.charAt(0).toUpperCase() + value.substring(1).toLowerCase(); break; case InputStringEnum.UPPERCASE: value = value.toLocaleUpperCase('en-US'); break; case InputStringEnum.CAPITALIZED_CASE: const capitalizedCaseWords = value.replace( /(^\w{1})|(\s+\w{1})/g, (letter: string) => letter.toUpperCase() ); value = capitalizedCaseWords; break; default: break; } this.superControl.control?.patchValue(value, { emitEvent: false, }); } private applyThousandSeparator(): void { const controlValue = this.superControl.control?.value; if (this._inputConfig.thousandSeparator && controlValue) { if (this.isAllZeros(controlValue)) { this.superControl.control?.patchValue('0', { emitEvent: false, }); return; } if (this.superControl.control?.value.toString()) { this.superControl.control?.patchValue( this.thousandSeparatorPipe.transform(controlValue), { emitEvent: false, } ); } } } private applyPriceSeparator(): void { const controlValue = this.superControl.control?.value; if (this._inputConfig.priceSeparator && controlValue) { // 0. Don't allow 0 as first character if (this.isAllZeros(controlValue)) { this.superControl.control?.patchValue('0', { emitEvent: false, }); return; } // 4. If user set dot if (controlValue.includes('.')) { this.formatWithDecimal(); } else { // 5. If user doesn't set dot this.formatWithoutDecimal(); } this.setInputCursorPosition(); } } private setInputCursorPosition(): void { if (this.superControl.control?.value) { this.timeoutCleaner = setTimeout(() => { this.input.nativeElement.setSelectionRange( this.cursorInputPosition + (this.superControl.control?.value.indexOf('.') === -1 ? 1 : 0), this.cursorInputPosition + (this.superControl.control?.value.indexOf('.') === -1 ? 1 : 0) ); }, 0); } else { // if we have ${n}00000 and we delete N then we got undefined instead of dot this.superControl.control?.patchValue(0, { emitEvent: false, }); } } private formatWithDecimal(): void { const controlValue = this.superControl.control?.value; // 4.1. Check for Dot position this.hasDecimalIndex = controlValue.indexOf('.'); this.originPriceSeparatorLimit = this._inputConfig.priceSeparatorLimitation! + 3; // 4.2. Divide number into decimal and integer parts let integerPart = this.thousandSeparatorPipe.transform( controlValue .slice(0, this.hasDecimalIndex) .slice(0, this._inputConfig.priceSeparatorLimitation) ); let decimalPart = controlValue.slice(this.hasDecimalIndex + 1); if (!integerPart) { integerPart = '0'; } // 4.4. Get only two numbers of the decimal part decimalPart = decimalPart.slice(0, 2); if (decimalPart) { // 4.5. Set formatted number this.superControl.control?.patchValue( `${integerPart}.${decimalPart}`, { emitEvent: false, } ); this.hasDecimalIndex = this.superControl.control?.value.indexOf('.'); } } private customValidation(value: string): void { const configName = this._inputConfig.name.toLowerCase(); if ( configName === InputStringEnum.YEAR && parseInt(value) > parseInt(moment().add(1, 'year').format('YYYY')) ) { this.superControl.control?.setErrors({ invalid: true }); } if (configName === InputStringEnum.MONTHS) { if (parseInt(value) < 1 || parseInt(value) > 12) { this.superControl.control?.setErrors({ invalid: true }); } else { this.superControl.control?.setErrors(null); } } if (configName === InputStringEnum.AXLES) { if (parseInt(value) < 1 || parseInt(value) > 17) { if (parseInt(value) < 1) { this.superControl.control?.setErrors({ min: 1 }); } else if (parseInt(value) > 17) { this.superControl.control?.setErrors({ max: 17 }); } } else { this.superControl.control?.setErrors(null); } } if ( configName === InputStringEnum.FULL_NAME && this.superControl.control?.value ) { this.capitalizeWords(); } } private formatWithoutDecimal(): void { const controlValue = this.superControl.control?.value; this.hasDecimalIndex = -1; if (controlValue.indexOf('.') === -1) { // Transform value with thousand separator this.superControl.control?.patchValue( this.thousandSeparatorPipe.transform(controlValue), { emitEvent: false, } ); // Limit validation this.originPriceSeparatorLimit = this._inputConfig.priceSeparatorLimitation; // Cut value if (controlValue) { this.superControl.control?.patchValue( controlValue.slice( 0, this._inputConfig.priceSeparatorLimitation ), { emitEvent: false, } ); } // Transform value again after cutting this.superControl.control?.patchValue( this.thousandSeparatorPipe.transform(controlValue), { emitEvent: false, } ); } } private sanitizeConsecutiveSpaces(): void { const configNames = InputConstants.textTransformConfigNames; if (configNames.includes(this._inputConfig.name.toLowerCase())) { const sanitizedInput = this.input.nativeElement.value.replace( /\s{2,}/g, ' ' ); if (sanitizedInput !== this.input.nativeElement.value) { this.superControl.control?.patchValue(sanitizedInput, { emitEvent: false, }); this.setCursorForSanitizedInput(); } } } private setCursorForSanitizedInput(): void { this.timeoutCleaner = setTimeout(() => { this.input.nativeElement.setSelectionRange( this.lastCursorSpacePosition - 1, this.lastCursorSpacePosition - 1 ); }); } private removeLeadingZero(): void { if (this._inputConfig.removeLeadingZero) { const currentValue = this.superControl.control?.value; if (!currentValue) { this.superControl.control?.patchValue('', { emitEvent: false, }); this.superControl.control?.setErrors(null); return; } if (this._inputConfig.negativeLeadingZero) { const isNegative = currentValue.startsWith('-'); if (isNegative) { // Get the part after the negative sign const numberPart = currentValue.slice(1); // Remove leading zeros const transformedNumber = numberPart.replace( /^0+(?=\d)/, '' ); this.superControl.control?.patchValue( `-${transformedNumber}`, { emitEvent: false, } ); } else { this.superControl.control?.patchValue( currentValue.replace(/^0+(?=\d)/, ''), { emitEvent: false, } ); } } else { this.superControl.control?.patchValue( currentValue.replace(/^0+(?!$)/, ''), { emitEvent: false, } ); } } } public writeValueBase(obj: InputChangeValue): void { this.setChangeInput.next(obj); if (!this._inputConfig.priceSeparator) { this.input.nativeElement.value = obj; } } private capitalizeWords(): void { const words = this.superControl.control?.value.split(' '); const capitalized = words.map((word: string) => { return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }); this.superControl.control?.patchValue(capitalized.join(' '), { emitEvent: false, }); } private isAllZeros(value: string): boolean { return value.split('').every((char) => char === '0'); } public onBlurBase(event?: FocusEvent): void { // DropDown Label if (this._inputConfig.dropdownLabel && !this.isEditInput) this._inputConfig.placeholderIcon = InputSvgRoutes.dynamicLabelSvg; // Edit Input if (this.isEditInput) { this.superControl.control?.setErrors({ invalid: true }); return; } // Datepicker; if (this.preventBlur) { this.preventBlur = false; return; } // Bank if ( this._inputConfig.name === InputConfigNameStringEnum.INPUT_DROPDOWN_BANK_NAME ) this._inputConfig.blackInput = false; // Price Separator - remove dot on focus out if ( this._inputConfig.priceSeparator && this.superControl.control?.value && this.superControl.control?.value?.toString().indexOf('.') >= 0 ) { // 4.1. Check for Dot position this.hasDecimalIndex = this.superControl.control?.value .toString() .indexOf('.'); let integerPart = this.thousandSeparatorPipe.transform( this.superControl.control?.value .slice(0, this.hasDecimalIndex) .slice(0, this._inputConfig.priceSeparatorLimitation) ); let decimalPart = this.superControl.control?.value.slice( this.hasDecimalIndex + 1 ); // 4.4. Get only two numbers of decimal part decimalPart = decimalPart.slice(0, 2); if (!decimalPart) { this.hasDecimalIndex = -1; this.superControl.control?.patchValue(integerPart); this.numberOfPoints = 0; } } // Dropdown if (this._inputConfig.isDropdown || this._inputConfig.dropdownLabel) { this.blurOnDropDownArrow(); } // Normal, without dropdown else { let selection = window.getSelection(); selection?.removeAllRanges(); // Input Commands if (this._inputConfig.commands) this.blurOnCommands(); // Password if (this._inputConfig.type === 'password') this.blurOnPassword(); // Normal focus out else this.isFocusInput = false; } this.setBlurInput.next(true); this.isTouchedInput = true; } private blurOnDropDownArrow(): void { this.timeoutCleaner = setTimeout(() => { this.isDropdownToggler = false; this.isFocusInput = false; this.isDropdownToggler = false; this.isFocusInput = false; this.setShowHideDropdown.next(this.isDropdownToggler); }, 150); } public blurOnPassword() { this.passwordTimeout = setTimeout(() => { this.isFocusInput = false; this.input.nativeElement.blur(); this.cdRef.detectChanges(); }, 150); } public checkRegexPattern( charCode: string, name: string ): boolean | undefined { return this.caInputValidationService .getInputRegexPattern(name) ?.test(charCode); } // FOCUS INPUT FUNCTION public onKeypress(event: KeyboardEvent): boolean | void { const lowerCaseName = this._inputConfig.name.toLowerCase(); const charCode = String.fromCharCode(event.charCode); // Disable first character to be space if (!this.input.nativeElement.value && /^\s*$/.test(charCode)) { event.preventDefault(); return false; } if (this._inputConfig.priceSeparator) { if ( this.checkRegexPattern( charCode, InputStringEnum.PRICE_SEPARATOR ) ) { if ( this.superControl.control?.value?.length === this.originPriceSeparatorLimit && event.keyCode !== 46 ) { event.preventDefault(); return; } // Disable multiple dots this.disableMultiplePoints(event); // Find index of dot const valueToString = String(this.superControl.control?.value); this.hasDecimalIndex = valueToString?.indexOf('.'); if (this.hasDecimalIndex >= 0) { // 1. Divide number on decimal and integer part let integerPart = this.superControl.control?.value.slice( 0, this.hasDecimalIndex ); if (!integerPart) integerPart = '0'; let decimalPart = this.superControl.control?.value.slice( this.hasDecimalIndex + 1 ); // 2. Disable more than two decimals if (decimalPart.length > 2) { event.preventDefault(); return; } // 3. Get only two numbers of decimal part decimalPart = decimalPart.slice(0, 2); const currentPosition = this.input.nativeElement.selectionStart; // 4. Set formatted number this.superControl.control?.patchValue( integerPart + '.' + decimalPart ); this.timeoutCleaner = setTimeout(() => { if (event.keyCode === 51) { this.cursorInputPosition = this.input.nativeElement.selectionStart; this.input.nativeElement.setSelectionRange( currentPosition, currentPosition ); } else { this.input.nativeElement.setSelectionRange( currentPosition, currentPosition ); } }, 0); } return true; } event.preventDefault(); return false; } if ( this.checkNameArray( InputConstants.businessNamesArray, lowerCaseName ) ) { if ( this.checkRegexPattern(charCode, InputStringEnum.BUSINESS_NAME) ) { this.disableMultiplePoints(event); this.disableConsecutivelySpaces(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray(InputConstants.qtyArray, lowerCaseName)) { // Only numbers if (this.checkRegexPattern(charCode, InputStringEnum.QTY)) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.EMAIL], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.EMAIL)) { this.disableConsecutivelyPoints(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.INVOICE], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.INVOICE)) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.ADDRESS], lowerCaseName)) { if (/^[A-Za-z0-9\s.&/,_-]*$/?.test(charCode)) { this.disableConsecutivelySpaces(event); return true; } else { event.preventDefault(); return false; } } if ( this.checkNameArray(InputConstants.addressUnitArray, lowerCaseName) ) { if (this.checkRegexPattern(charCode, InputStringEnum.ADDRESS_UNIT)) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.FIRST_NAME], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.FIRST_NAME)) { this.disableMultiplePoints(event); this.enableOneSpaceOnly(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.LAST_NAME], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.LAST_NAME)) { this.enableOneSpaceOnly(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.BANK_NAME], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.BANK_NAME)) { this.disableMultiplePoints(event); this.enableOneSpaceOnly(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray(InputConstants.vinNumberArray, lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.VIN_NUMBER)) return !/^[IiOQ]*$/?.test(charCode); event.preventDefault(); return false; } if ( this.checkNameArray( [InputStringEnum.TRUCK_TRAILER_MODEL], lowerCaseName ) ) { if ( this.checkRegexPattern( charCode, InputStringEnum.TRUCK_TRAILER_MODEL ) ) { this.enableOneSpaceOnly(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.YEAR], lowerCaseName)) { if (/^0*$/.test(charCode) && !this.input.nativeElement.value) { event.preventDefault(); return false; } if (this.checkRegexPattern(charCode, InputStringEnum.YEAR)) return true; event.preventDefault(); return false; } if ( this.checkNameArray([InputStringEnum.LICENSE_PLATE], lowerCaseName) ) { if ( this.checkRegexPattern(charCode, InputStringEnum.LICENSE_PLATE) ) { this.enableOneSpaceOnly(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.DESCRIPTION], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.DESCRIPTION)) { this.disableConsecutivelySpaces(event); return true; } event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.ALLOW_ALL], lowerCaseName)) { if (/.*/?.test(charCode)) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.DBA_NAME], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.DBA_NAME)) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.PER_MILE], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.PER_MILE)) { this.disableMultiplePoints(event); // Check for max length if (this.superControl.control?.value?.toString().includes('.')) this._inputConfig.maxLength = 4; else this._inputConfig.maxLength = 2; // Check for range if ( this.superControl.control?.value > this._inputConfig.max! || this.superControl.control?.value < this._inputConfig.min! ) { this.superControl.control?.setErrors({ invalid: true }); } return true; } else { event.preventDefault(); return false; } } if (this.checkNameArray(InputConstants.perStopArray, lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.PER_STOP)) { this.timeoutCleaner = setTimeout(() => { if (this.superControl.control?.value) { let perStopValue = this.superControl.control?.value.replace(/,/g, ''); if ( perStopValue > this._inputConfig.max! || perStopValue < this._inputConfig.min! ) { this.superControl.control?.setErrors({ invalid: true, }); return false; } return true; } return; }, 0); } else { event.preventDefault(); return false; } } if ( this.checkNameArray( InputConstants.emergencyNameArray, lowerCaseName ) ) { if ( this.checkRegexPattern(charCode, InputStringEnum.EMERGENCY_NAME) ) return true; event.preventDefault(); return false; } if ( this.checkNameArray([InputStringEnum.EMERGENCY_NAME], lowerCaseName) ) { if ( this.checkRegexPattern(charCode, InputStringEnum.EMERGENCY_NAME) ) { this.disableConsecutivelySpaces(event); this.enableOneSpaceOnly(event); return true; } event.preventDefault(); return false; } if ( this.checkNameArray( [InputStringEnum.FULL_CONTACT_NAME], lowerCaseName ) ) { if ( this.checkRegexPattern( charCode, InputStringEnum.FULL_CONTACT_NAME ) ) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.FUEL_STORE], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.FUEL_STORE)) return true; event.preventDefault(); return false; } if (this.checkNameArray([InputStringEnum.HOS], lowerCaseName)) { if ( !this.inputSelection && this.checkRegexPattern(charCode, InputStringEnum.HOS) ) { return ( this.superControl.control?.value * 10 + event.charCode - 48 <= this._inputConfig.max! ); } else { if (this.inputSelection) { this.superControl.control?.patchValue(charCode); this.inputSelection = false; } event.preventDefault(); return false; } } if ( this.checkNameArray(InputConstants.parkingSlotArray, lowerCaseName) ) { if ( this.checkRegexPattern( charCode, InputStringEnum.FULL_PARKING_SLOT ) ) return true; else { event.preventDefault(); return false; } } if (this.checkNameArray([InputStringEnum.CDL_NUMBER], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.CDL_NUMBER)) { this.enableOneSpaceOnly(event); this.disableConsecutivelySpaces(event); return true; } else { event.preventDefault(); return false; } } // All Simbols if (this.checkNameArray(InputConstants.usernameArray, lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.USERNAME)) return true; else { event.preventDefault(); return false; } } if (this.checkNameArray([InputStringEnum.FULL_NAME], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.FULL_NAME)) { this.enableOneSpaceOnly(event); this.disableMultiplePoints(event); this.disableConsecutivelySpaces(event); return true; } else { event.preventDefault(); return false; } } if ( this.checkNameArray( [InputStringEnum.TOLL_VALIDATION], lowerCaseName ) ) { if ( this.checkRegexPattern( charCode, InputStringEnum.TOLL_VALIDATION ) ) return true; else { event.preventDefault(); return false; } } // Just characters and numbers if (this.checkNameArray(InputConstants.prefixArray, lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.PREFIX)) return true; else { event.preventDefault(); return false; } } if (this.checkNameArray([InputStringEnum.FULL_NAME], lowerCaseName)) { if (this.checkRegexPattern(charCode, InputStringEnum.FULL_NAME)) { event.preventDefault(); return false; } else { this.disableConsecutivelySpaces(event); return true; } } if ( this.checkNameArray(InputConstants.producerNameArray, lowerCaseName) ) { if ( this.checkRegexPattern(charCode, InputStringEnum.PRODUCER_NAME) ) { this.disableMultiplePoints(event); return true; } else { event.preventDefault(); return false; } } if ( this.checkNameArray( [InputStringEnum.INPUT_DROPDOWN_LABEL], lowerCaseName ) ) { this.disableConsecutivelySpaces(event); this.disableConsecutivelyPoints(event); } this.input.nativeElement.value.trim(); } // #region onFocus public onFocus(event?: FocusEvent) { this.focusInputEvent.emit(event); // DropDown Label if (this._inputConfig.dropdownLabel) { this._inputConfig.placeholderIcon = InputSvgRoutes.dynamicFocusLabelSvg; } // Dropdown if (this._inputConfig.isDropdown) { this.isDropdownToggler = true; this.setShowHideDropdown.next(this.isDropdownToggler); } // Commands if (this._inputConfig.commands && !this._inputConfig.isDisabled) { if (this._inputConfig.commands.type === InputCommandsType.MONTHS) { if (!this._inputConfig.blueInput) this._inputConfig.blackInput = true; this._inputConfig.commands.active = true; this.isVisibleCommands = true; } if ( this._inputConfig.commands.type === InputCommandsType.PM_INCREMENT_DECREMENT || this._inputConfig.commands.type === InputCommandsType.INCREMENT_DECREMENT ) { this._inputConfig.blackInput = false; this._inputConfig.commands.active = true; this.isVisibleCommands = true; } } this.isFocusInput = true; } // #endregion // #region onKeyDown public onKeydown(event: KeyboardEvent) { if (event) this.isCapsLockOn = event?.getModifierState?.('CapsLock'); if (this._inputConfig.priceSeparator) { const valueToString = String(this.superControl.control?.value); this.isDotDeleted = valueToString?.includes('.'); } // Disable for phone field first character to be 0 if (this._inputConfig.name.toLowerCase() === InputStringEnum.PHONE) { if ( (event.target as HTMLInputElement).selectionStart === 0 && event.key === '0' ) { event.preventDefault(); } } if (event.keyCode === 9) { this.setDropDownKeyNavigation.next({ keyCode: event.keyCode, data: null, }); } } // #endregion // #region onKeyUp public onKeyup(event: KeyboardEvent): void { if (event) { this.isCapsLockOn = event?.getModifierState?.('CapsLock'); } // Reset function property for disabling multiple dots const valueToString = String(this.superControl.control?.value); if (this.isDotDeleted && !valueToString?.includes('.')) this.numberOfPoints = 0; if ( event.keyCode == 8 && !(this._inputConfig.isDropdown || this._inputConfig.dropdownLabel) ) { // Reset Multiple Consecutively Spaces this.numberOfConsecutivelySpaces = 0; // Reset One Space Only if ( this.superControl.control?.value && !this.superControl.control?.value?.includes(' ') ) { this.oneSpaceOnlyCounter = 0; } } if ( this._inputConfig.isDropdown || this._inputConfig.dropdownLabel || this._inputConfig.name === InputConfigNameStringEnum.ADDRESS ) { if (event.keyCode === 40 || event.keyCode === 38) { this.setDropDownKeyNavigation.next({ keyCode: event.keyCode, data: null, }); } if (event.keyCode === 13) { this.setDropDownKeyNavigation.next({ keyCode: event.keyCode, data: this._inputConfig, }); if ( this._inputConfig.name === InputConfigNameStringEnum.ADDRESS ) { this.input.nativeElement.blur(); } } if (event.keyCode === 27) { this.isVisibleCommands = false; this.onBlurBase(); this.blurOnDropDownArrow(); this.input.nativeElement.blur(); this.setDropDownKeyNavigation.next({ keyCode: event.keyCode, data: null, }); } if (event.keyCode === 9) { this.onFocus(); this.input.nativeElement.focus(); this.setDropDownKeyNavigation.next({ keyCode: event.keyCode, data: null, }); } } } private handleConfirmCancel(action: string): void { switch (action) { case InputCommandsAction.CONFIRM: this.confirmCommand(); break; case InputCommandsAction.CANCEL: this.cancelCommand(); break; default: break; } this.superControl.control?.setErrors(null); this._inputConfig.dropdownLabelNew = false; this._inputConfig.commands!.active = false; this._inputConfig.blackInput = false; this.isEditInput = false; this.isVisibleCommands = false; this.isFocusInput = false; } private cancelCommand(): void { this.setCommandEvent.next({ action: InputCommandsAction.CANCEL }); } private confirmCommand(): void { this.setCommandEvent.next({ data: this.superControl.control?.value, action: InputCommandsAction.CONFIRM, mode: !this._inputConfig.dropdownLabelNew && this._inputConfig.name !== 'Input Dropdown Bank Name' ? 'edit' : 'new', }); } // #endregion // #region ClearInput public clearInput(event: Event): void { event.preventDefault(); event.stopPropagation(); // Clear whole input if (this._inputConfig.removeInput) { this.setClearInputEvent.next(true); return; } // Incorrect Input if (this._inputConfig.incorrectInput) { this.incorrectValue = !this.incorrectValue; this.setIncorrectInput.next(this.incorrectValue); } // Native clear else { this.input.nativeElement.value = null; this.superControl.control?.setValue(null, { emitEvent: false, }); this.numberOfConsecutivelySpaces = 0; this.numberOfConsecutivelyPoints = 0; this.numberOfPoints = 0; this.oneSpaceOnlyCounter = 0; this._inputConfig.dropdownImageInput = undefined; this.isTouchedInput = true; this.isFocusInput = false; this.setClearInputEvent.next(true); } } // #endregion // #region OnCommands public onCommands(e: any): void { const { event, type, action } = e; event.stopPropagation(); event.preventDefault(); switch (type) { case InputCommandsType.PM_INCREMENT_DECREMENT: this.handlePmIncrementDecrement(action); break; case InputCommandsType.INCREMENT_DECREMENT: this.handleIncrementDecrement(action); break; case InputCommandsType.CONFIRM_CANCEL: this.handleConfirmCancel(action); break; case InputCommandsType.MONTHS: this.handleMonths(action); break; default: break; } } // #endregion // #region onEditInput public onEditInput(event: Event): void { event.preventDefault(); event.stopPropagation(); this.isEditInput = true; this._inputConfig.dropdownLabelNew = false; if (!this._inputConfig.blueInput) this._inputConfig.blackInput = true; this._inputConfig.commands!.active = true; this.isVisibleCommands = true; this.isFocusInput = true; this.setInputCursorAtTheEnd(this.input.nativeElement); this.superControl.control?.setErrors({ required: true }); this.setCommandEvent.next({ data: this.superControl.control?.value, action: 'Edit Input', }); } // #endregion // #region ToggleDropdownOptions public toggleDropdownOptions(): void { this.handleToggleDropdownOptions.emit(); if (this._inputConfig.isDisabled) { return; } this.isDropdownToggler = !this.isDropdownToggler; this.setShowHideDropdown.next(this.isDropdownToggler); if (this.isDropdownToggler) { this.input.nativeElement.focus(); this.isFocusInput = true; } } // #endregion // #region onPlaceholderIconevent public onPlaceholderIconEvent(event: Event): void { event.preventDefault(); event.stopPropagation(); if (this.isEditInput) { this.setCommandEvent.next({ data: this.superControl.control?.value, action: 'Toggle Dropdown', }); } else { this.setCommandEvent.next({ data: this.superControl.control?.value, action: 'Placeholder Icon Event', }); } } // #endregion // #region SelectionChange public selectionChange(event: Event): void { if (event) this.inputSelection = true; } // #endregion setSelection // #region AutoFocusFirstInput public autoFocusFirstInput(): void { if (this._inputConfig.autoFocus && !this.superControl.control?.value) { this.timeoutCleaner = setTimeout(() => { this.input.nativeElement.focus(); this.isFocusInput = true; this._inputConfig.autoFocus = false; }, 30); } } // #endregion public onPopoverShown(): void { if (!this._inputConfig.dropdownLabel) { this.isFocusInput = true; } } public onPopoverHidden(): void { if (!this._inputConfig.dropdownLabel) { this.isFocusInput = false; } } public onInputConfigChange(): void { // Price Separator if (this._inputConfig.priceSeparator) { this.originPriceSeparatorLimit = this._inputConfig.priceSeparatorLimitation; } // Custom Range if (this._inputConfig.isUsingCustomPeriodRange) { if (this._inputConfig.isDisplayingCustomPeriodRange) this.isFocusInput = true; else this.isFocusInput = false; } // When add mode in dropdown if ( this._inputConfig.commands?.active && !this._inputConfig.isDisabled ) { if (this._inputConfig.commands.type === 'confirm-cancel') { if (!this._inputConfig.blueInput) this._inputConfig.blackInput = true; this.isVisibleCommands = true; this.isFocusInput = true; this.input.nativeElement.focus(); } } } }