Add year range in types of input component

This commit is contained in:
Konstantinos Triantafyllou 2023-05-09 15:38:37 +03:00
parent c321390ccb
commit 49f9bec70d
1 changed files with 97 additions and 14 deletions

View File

@ -15,13 +15,12 @@ import {
ViewChild,
ViewChildren
} from "@angular/core";
import {AbstractControl, UntypedFormArray, UntypedFormControl, ValidatorFn} from "@angular/forms";
import {AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup, ValidatorFn} from "@angular/forms";
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {BehaviorSubject, Subscription} from "rxjs";
import {EnvProperties} from "../../utils/properties/env-properties";
import {properties} from "../../../../environments/environment";
import {ClickEvent} from "../../utils/click/click-outside-or-esc.directive";
import {element} from "protractor";
export type InputType =
'text'
@ -31,7 +30,8 @@ export type InputType =
| 'autocomplete_soft'
| 'textarea'
| 'select'
| 'chips';
| 'chips'
| 'year-range';
export interface Option {
icon?: string,
@ -48,6 +48,16 @@ export interface Placeholder {
static?: boolean
}
export interface YearRange {
from: ControlConfiguration,
to: ControlConfiguration
}
export interface ControlConfiguration {
control: string,
placeholder: string
}
declare var UIkit;
/**
@ -63,11 +73,11 @@ declare var UIkit;
<div *ngIf="formControl" [id]="id">
<div class="input-wrapper" [class.disabled]="formControl.disabled" [class.opened]="opened"
[class.focused]="focused" [ngClass]="inputClass" [class.hint]="hint"
[class.active]="(formAsControl?.value || selectable || formAsArray?.length > 0 || getLabel(formAsControl?.value)) && !focused"
[class.active]="!focused && (formAsControl?.value || selectable || formAsArray?.length > 0 || getLabel(formAsControl?.value) || yearRangeActive)"
[class.danger]="(formControl.invalid && (formControl.touched || !!searchControl?.touched)) || (!!searchControl?.invalid && !!searchControl?.touched)">
<div #inputBox class="input-box" [class.select]="selectable" click-outside-or-esc
[class.static]="placeholderInfo?.static" (clickOutside)="click($event)">
<div *ngIf="!placeholderInfo?.static && placeholderInfo.label" class="placeholder">
<div *ngIf="!placeholderInfo?.static && placeholderInfo?.label" class="placeholder">
<label>{{placeholderInfo.label}} <sup *ngIf="required">*</sup></label>
</div>
<div class="uk-flex" [class.uk-flex-middle]="type !== 'textarea'"
@ -140,6 +150,19 @@ declare var UIkit;
</div>
</div>
</ng-template>
<ng-template [ngIf]="type === 'year-range' && yearRange && formAsGroup">
<div class="uk-width-2-5">
<input #input class="input uk-text-truncate" [attr.placeholder]="yearRange.from.placeholder"
(click)="activeIndex = 0;$event.preventDefault()"
[formControl]="getFormByName(yearRange.from.control)">
</div>
<div class="uk-width-1-5 uk-text-center">-</div>
<div class="uk-width-2-5">
<input #input class="input uk-text-truncate" [attr.placeholder]="yearRange.to.placeholder"
(click)="activeIndex = 1;$event.preventDefault()"
[formControl]="getFormByName(yearRange.to.control)">
</div>
</ng-template>
<div
*ngIf="(formControl.disabled && disabledIcon) || icon || (selectable && selectArrow) || type === 'autocomplete' || searchable"
class="uk-margin-small-left icon">
@ -157,6 +180,7 @@ declare var UIkit;
</button>
</ng-template>
</div>
<!-- use action-icon class in order to apply css in your icon button-->
<ng-content select="[action]"></ng-content>
</div>
<div class="tools">
@ -179,7 +203,7 @@ declare var UIkit;
</div>
</div>
<span *ngIf="formControl?.invalid && formControl?.touched" class="uk-text-danger">
<span *ngIf="formControl.errors.error">{{formControl.errors.error}}</span>
<span *ngIf="errors?.error">{{errors?.error}}</span>
<span *ngIf="type === 'URL' || type === 'logoURL'">Please provide a valid URL (e.g. https://example.com)</span>
</span>
<span class="uk-text-small uk-text-danger">
@ -213,7 +237,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
@Input() tooltip: boolean = false;
@Input() searchable: boolean = false;
/** Text */
@ViewChild('input') input: ElementRef;
@ViewChildren('input') input: QueryList<ElementRef>;
/** Textarea options */
@ViewChild('textArea') textArea: ElementRef;
@Input('rows') rows: number = 3;
@ -236,6 +260,10 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
@Input() visibleChips: number = 1;
@Input() separators: string[] = [];
@Input() noWrap: boolean = false;
/** Year Range Configuration */
@Input() yearRange: YearRange;
public activeIndex: 0 | 1 | null = null;
@Input() visibleRows: number = -1;
@Input() extendEnter: () => void = null;
@Output() focusEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
@ -259,7 +287,9 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
@Input()
set placeholder(placeholder: string | Placeholder) {
if (typeof placeholder === 'string') {
if(this.type === 'year-range') {
this.placeholderInfo = null;
} else if (typeof placeholder === 'string') {
this.placeholderInfo = {label: placeholder, static: false};
} else {
if (placeholder.static && (this.type === 'autocomplete' || this.hint)) {
@ -432,6 +462,22 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
this.unsubscribe();
}
getFormByName(name: string): UntypedFormControl {
if (this.formControl instanceof UntypedFormGroup) {
return <UntypedFormControl>this.formControl.get(name);
} else {
return null;
}
}
get formAsGroup(): UntypedFormGroup {
if (this.formControl instanceof UntypedFormGroup) {
return this.formControl;
} else {
return null;
}
}
get formAsControl(): UntypedFormControl {
if (this.formControl instanceof UntypedFormControl) {
return this.formControl;
@ -448,6 +494,25 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
}
get yearRangeActive(): boolean {
if(this.yearRange) {
return this.formAsGroup && (this.getFormByName(this.yearRange.from.control)?.value || this.getFormByName(this.yearRange.to.control)?.value);
}
return false;
}
get errors(): any {
if(this.formAsGroup) {
return (this.formAsGroup.errors
?this.formAsGroup.errors:(this.getFormByName(this.yearRange.from.control).errors
?this.getFormByName(this.yearRange.from.control).errors:this.getFormByName(this.yearRange.to.control).errors));
} else if(this.formAsControl) {
return this.formAsControl.errors;
} else {
return this.searchControl.errors;
}
}
reset() {
this.secure = true;
this.unsubscribe();
@ -455,7 +520,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
if (this.type === 'logoURL') {
this.secure = (!this.initValue || this.initValue.includes('https://'));
}
if (this.optionsArray) {
if (this.optionsArray?.length > 0) {
this.filteredOptions = this.filter('');
this.cdr.detectChanges();
}
@ -475,7 +540,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
}));
}
if (this.formControl.validator) {
if (this.formAsControl?.validator) {
let validator = this.formControl.validator({} as AbstractControl);
this.required = (validator && validator.required);
}
@ -502,8 +567,20 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
}
}));
if(this.formAsGroup) {
this.subscriptions.push(this.formAsGroup.get(this.yearRange.from.control).valueChanges.subscribe(value => {
if(this.formAsGroup.get(this.yearRange.from.control).valid) {
if(this.activeIndex === 0 && value.length > 0) {
this.activeIndex = 1;
this.input.get(this.activeIndex).nativeElement.focus();
}
}
}));
}
if (this.input) {
this.input.nativeElement.disabled = this.formControl.disabled;
this.input.forEach(input => {
input.nativeElement.disabled = this.formControl.disabled;
});
}
}
@ -598,14 +675,17 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
focus(value: boolean, event = null) {
if(!this.activeIndex) {
this.activeIndex = 0;
}
if (this.focused) {
this.formControl.markAsTouched();
}
this.focused = value;
this.cdr.detectChanges();
if (this.focused) {
if (this.input) {
this.input.nativeElement.focus();
if (this.input?.length > 0) {
this.input.get(this.activeIndex).nativeElement.focus();
} else if (this.textArea) {
this.textArea.nativeElement.focus();
} else if (this.searchInput) {
@ -618,9 +698,12 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
this.open(true);
}
} else {
this.activeIndex = null;
this.open(false);
if (this.input) {
this.input.nativeElement.blur();
this.input.forEach(input => {
input.nativeElement.blur();
})
} else if (this.textArea) {
this.textArea.nativeElement.blur();
} else if (this.searchInput) {