UNPKG

@pepperi/components

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.1.

424 lines (360 loc) 14.7 kB
import { Component, OnInit, OnChanges, OnDestroy, Input, Output, EventEmitter, ViewChild, ElementRef, ChangeDetectorRef, ChangeDetectionStrategy, Renderer2, AfterViewChecked, } from '@angular/core'; import { FormGroup } from '@angular/forms'; // import {Observable} from 'rxjs'; import { trigger, state, style, animate, transition } from '@angular/animations'; import { SessionService, LAYOUT_TYPE, STYLE_TYPE, CustomizationService } from '@pepperi/lib'; @Component({ selector: 'pepperi-quantity-selector', templateUrl: './quantity-selector.component.html', styleUrls: ['./quantity-selector.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, animations: [ trigger('showHide', [ state( 'show', style({ opacity: 1, transform: 'scale(1)', }) ), state( 'hide', style({ opacity: 0, transform: 'scale(0)', }) ), transition('show => hide', animate('250ms ease-out')), transition('hide => show', animate('250ms ease-in')), ]), ], }) export class PepperiQuantitySelectorComponent implements OnChanges, OnInit, AfterViewChecked, OnDestroy { public static ENTER_CHILDREN = '[EnterChildren]'; public static ENTER_PACKAGE = '[EnterPackage]'; @Input() key: string = ''; @Input() value: string = ''; @Input() formattedValue: string = ''; @Input() label: string = ''; @Input() type: string = 'qs'; @Input() required: boolean = false; @Input() disabled: boolean = false; @Input() readonly: boolean = false; @Input() textColor: string = ''; @Input() xAlignment: string = '0'; @Input() rowSpan: number = 1; @Input() lastFocusField: any; @Input() alowDecimal: boolean = false; @Input() additionalValue: string = ''; @Input() notificationInfo: any; controlType = 'qs'; @Input() form: FormGroup = null; @Input() showTitle: boolean = true; @Input() layoutType: LAYOUT_TYPE = LAYOUT_TYPE.PepperiForm; @Input() isActive: boolean = false; @Input() showQSButtons = true; @Output() valueChanged: EventEmitter<any> = new EventEmitter<any>(); @Output() elementClicked: EventEmitter<any> = new EventEmitter<any>(); @ViewChild('QSCont') QSCont: ElementRef; @ViewChild('QSInput') QSInput: ElementRef; LAYOUT_TYPE = LAYOUT_TYPE; standAlone = false; isFocus: boolean = false; isMatrixFocus: boolean = false; isCaution = false; messages: Array<any> = null; showQsBtn = false; resize: any; sameElementInTheWantedRow = null; STYLE_TYPE = STYLE_TYPE; styleClass = STYLE_TYPE.Strong; isEmptyKey = false; constructor( private cd: ChangeDetectorRef, private customizationService: CustomizationService, public sessionService: SessionService, private renderer: Renderer2, public _eref: ElementRef ) { } ngOnInit() { if (this.form === null) { if (this.key === '') { this.isEmptyKey = true; } this.standAlone = true; this.form = this.customizationService.getDefaultFromGroup(this.key, this.value, this.required, this.readonly, this.disabled); this.formattedValue = this.formattedValue || this.value; this.renderer.addClass(this._eref.nativeElement, CustomizationService.STAND_ALONE_FIELD_CLASS_NAME); } const self = this; this.setQsView(); // TODO: // this.resize = Observable.fromEvent(window, 'resize') // .debounceTime(100) // .subscribe((event) => { // self.setQsView(); // }); } ngAfterViewChecked() { setTimeout(() => { this.setQsView(); }, 125); } ngOnChanges(changes: any) { // Bug fix for addons when the key is '' in the ngOnInit for some reson if (this.isEmptyKey && this.key !== '') { this.form = this.customizationService.getDefaultFromGroup(this.key, this.value, this.required, this.readonly, this.disabled); } // If isActive changes don't update. // if (changes && changes.isActive && !changes.isActive.firstChange) { // return; // } if (changes && changes.showQSButtons && changes.showQSButtons.currentValue) { this.showQSButtons = changes.showQSButtons.currentValue; } // this.fieldValue = this.value; // this.fieldFormattedValue = this.formattedValue; this.isCaution = this.textColor === '#FF0000'; // For having the on hide animation. // if (this.additionalValue && this.additionalValue.length > 0) { // this.fieldAdditionalValue = this.additionalValue; // } this.messages = this.notificationInfo && this.notificationInfo.length > 0 ? JSON.parse(this.notificationInfo).Messages : ''; // this.messages = ["error test"]; // For error check if (this.messages && this.messages.length > 0) { const fieldControl = this.form.controls[this.key]; fieldControl.setErrors({ serverError: 'Error', }); setTimeout(() => { if (this.QSInput && this.QSInput.nativeElement) { this.QSInput.nativeElement.focus(); } }, 150); } else { const self = this; setTimeout(() => { if (self.lastFocusField) { self.lastFocusField.focus(); self.lastFocusField = null; } else { self.focusToTheSameElementInTheWantedRow(); } }, 100); } } ngOnDestroy() { if (this.resize) { this.resize.unsubscribe(); } if (this.valueChanged) { this.valueChanged.unsubscribe(); } if (this.elementClicked) { this.elementClicked.unsubscribe(); } } get getAdditionalValue() { return this.additionalValue.length > 0 ? 'show' : 'hide'; } getSameElementInTheWantedRowByClassName(event: any, isNext = true) { // TODO: return null; // const eventTarget = event.target || event.srcElement; // let sameElementInTheWantedRowByClassName; // let parentSelector; // if (this.layoutType === LAYOUT_TYPE.PepperiTable) { // parentSelector = sameElementInTheWantedRowByClassName = $(eventTarget).parents('.table-row'); // } else if (this.layoutType === LAYOUT_TYPE.PepperiCard) { // parentSelector = sameElementInTheWantedRowByClassName = $(eventTarget).parents('.card-view'); // if (parentSelector.length === 0) { // parentSelector = sameElementInTheWantedRowByClassName = $(eventTarget).parents('.line-view'); // } // } // if (isNext) { // if (parentSelector.is(':last-child')) { // sameElementInTheWantedRowByClassName = parentSelector // .parent() // .children() // .first() // .find('[name=' + this.key + ']'); // } else { // sameElementInTheWantedRowByClassName = parentSelector.next().find('[name=' + this.key + ']'); // } // } else { // if (parentSelector.is(':first-child')) { // sameElementInTheWantedRowByClassName = parentSelector // .parent() // .children() // .last() // .find('[name=' + this.key + ']'); // } else { // sameElementInTheWantedRowByClassName = parentSelector.prev().find('[name=' + this.key + ']'); // } // } // return sameElementInTheWantedRowByClassName; } setSameElementInTheWantedRow(event: any, isNext = true) { // Navigate to the QS in the next row. const target = event.target || event.srcElement; this.sameElementInTheWantedRow = this.getSameElementInTheWantedRowByClassName(event, isNext); this.QSInput.nativeElement.blur(); } focusToTheSameElementInTheWantedRow() { if (this.sameElementInTheWantedRow) { // If this is regular item (qs and not button) . if (this.sameElementInTheWantedRow.is('input')) { this.sameElementInTheWantedRow.click().select(); } else { this.sameElementInTheWantedRow.parent().click(); this.sameElementInTheWantedRow.focus(); } this.sameElementInTheWantedRow = null; } } cleanError() { const fieldControl = this.form.controls[this.key]; // Clean the error message if (this.messages && this.messages.length > 0) { this.messages = this.notificationInfo = null; fieldControl.setErrors(null); } } onMatrixMouseEnter(event: any) { this.isMatrixFocus = true; } onMatrixMouseleave(event: any) { this.isMatrixFocus = false; } onMatrixClick(event: any) { this.isFocus = true; if (this.QSInput && this.QSInput.nativeElement) { this.QSInput.nativeElement.focus(); } } onMatrixBlur(event: any) { if (!event.relatedTarget || event.relatedTarget.className.indexOf('qs') < 0) { this.isMatrixFocus = false; } this.onBlur(event); } onFocus(event: any) { this.isFocus = true; } onBlur(event: any) { this.isFocus = false; this.cleanError(); const value = event.target ? event.target.value : event; if (parseFloat(this.value) !== parseFloat(value)) { this.value = value; this.formattedValue = value; this.customizationService.updateFormFieldValue(this.form, this.key, value); // this.propagateChange(this.value, event.relatedTarget); this.changeValue(this.value, event.relatedTarget); } else { this.focusToTheSameElementInTheWantedRow(); } } changeValue(value: any, lastFocusedField: any = null) { this.valueChanged.emit({ apiName: this.key, value: value, controlType: this.controlType, lastFocusedField: lastFocusedField }); } increment(event) { if (this.standAlone) { let tmp = parseFloat(this.value); this.value = this.formattedValue = (++tmp).toString(); this.customizationService.updateFormFieldValue(this.form, this.key, this.value); } // this.propagateChange('+'); this.changeValue('+', null); event.stopPropagation(); } decrement(event) { if (this.standAlone) { let tmp = parseFloat(this.value); this.value = this.formattedValue = (--tmp).toString(); this.customizationService.updateFormFieldValue(this.form, this.key, this.value); } // this.propagateChange('-'); this.changeValue('-', null); event.stopPropagation(); } enterChildren(event) { this.elementClicked.emit({ apiName: PepperiQuantitySelectorComponent.ENTER_CHILDREN, eventWhich: event.which }); } enterPackage(event) { this.elementClicked.emit({ apiName: PepperiQuantitySelectorComponent.ENTER_PACKAGE, eventWhich: event.which, otherData: this.notificationInfo }); } setQsView() { if (!this.showQSButtons) { this.showQsBtn = false; } else { if (this.QSCont && this.QSCont.nativeElement) { this.showQsBtn = this.QSCont.nativeElement.clientWidth > 140; } } // Get state class from theme. // this.styleClass = this.customizationService.getThemeVariable(CustomizationService.STYLE_QS_KEY); this.styleClass = document.documentElement.style.getPropertyValue(CustomizationService.STYLE_QS_KEY) as STYLE_TYPE; if (!this.cd['destroyed']) { this.cd.detectChanges(); } } onKeyPress(event) { let inputChar = String.fromCharCode(event.charCode); const keyboardEvent = <KeyboardEvent>event; if (keyboardEvent.keyCode === 13) { this.setSameElementInTheWantedRow(keyboardEvent, !keyboardEvent.shiftKey); return true; } // TODO: Make it one function like in PepperiTextboxComponent if ( /*[8, 9, 27, 13, 190].indexOf(keyboardEvent.keyCode) !== -1 ||*/ // Allow: Ctrl+A (keyboardEvent.keyCode === 65 && keyboardEvent.ctrlKey === true) || // Allow: Ctrl+C (keyboardEvent.keyCode === 67 && keyboardEvent.ctrlKey === true) || // Allow: Ctrl+V (keyboardEvent.keyCode === 86 && keyboardEvent.ctrlKey === true) || // Allow: Ctrl+X (keyboardEvent.keyCode === 88 && keyboardEvent.ctrlKey === true) /*|| // Allow: home, end, left, right (keyboardEvent.keyCode >= 35 && keyboardEvent.keyCode <= 39)*/ ) { // let it happen, don't do anything return true; } if (this.alowDecimal) { const decPoint = '.'; const thousandSeparator = ','; const pattern = /^\d[\d,]*(\.\d+)?$/; if (keyboardEvent.keyCode === 46) { inputChar = inputChar + '0'; } else if (keyboardEvent.keyCode === 44) { inputChar = inputChar + '000'; } if (!pattern.test(event.target.value + inputChar)) { keyboardEvent.preventDefault(); } } else { const pattern = /[0-9\+\-\ ]/; if (!pattern.test(inputChar)) { keyboardEvent.preventDefault(); } } } }