Merge pull request 'Input: Update the form validators when the input is changed' (#2) from develop into data-transfer-v2

Reviewed-on: #2
This commit is contained in:
Konstantina Galouni 2023-03-07 12:00:42 +01:00
commit c4e7e6adca
2 changed files with 49 additions and 39 deletions

View File

@ -85,7 +85,10 @@ declare var UIkit;
<ng-template [ngIf]="type === 'autocomplete'">
<input *ngIf="focused" [attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
#searchInput class="input" [formControl]="searchControl" [class.uk-text-truncate]="!focused">
<div *ngIf="!focused && !selectable" class="input uk-text-truncate">{{getLabel(formAsControl.value)}}</div>
<ng-container *ngIf="!focused && !selectable">
<div *ngIf="!getLabel(formControl.value)" class="input placeholder uk-text-truncate">{{placeholderInfo?.static?placeholderInfo.label:getLabel(formAsControl.value)}}</div>
<div *ngIf="getLabel(formControl.value)" class="input uk-text-truncate">{{getLabel(formAsControl.value)}}</div>
</ng-container>
<ng-container *ngIf="!focused && selectable" >
<div *ngIf="!getLabel(formControl.value)" class="input uk-text-truncate">{{noValueSelected}}</div>
<div *ngIf="getLabel(formControl.value)" class="input uk-text-truncate">{{getLabel(formControl.value)}}</div>
@ -97,7 +100,7 @@ declare var UIkit;
</ng-template>
<ng-template [ngIf]="type === 'chips'">
<div class="uk-grid uk-grid-small uk-grid-row-collapse uk-width-expand" uk-grid>
<div *ngFor="let chip of formAsArray.controls; let i=index" [class.uk-hidden]="!focused && i > 0"
<div *ngFor="let chip of formAsArray.controls; let i=index" [class.uk-hidden]="!focused && i > visibleChips - 1"
class="chip">
<div class="uk-label uk-label-small uk-flex uk-flex-middle"
[attr.uk-tooltip]="(tooltip)?('title: ' + getLabel(chip.value) + '; delay: 500; pos: bottom-left'):null">
@ -112,9 +115,9 @@ declare var UIkit;
[attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
[formControl]="searchControl" [class.uk-text-truncate]="!focused">
</div>
<div *ngIf="!focused && formAsArray.length > 1"
<div *ngIf="!focused && formAsArray.length > visibleChips"
class="uk-width-expand uk-flex uk-flex-column uk-flex-center more">
+ {{(formAsArray.length - 1)}} more
+ {{(formAsArray.length - visibleChips)}} more
</div>
</div>
</ng-template>
@ -124,15 +127,16 @@ declare var UIkit;
<ng-template [ngIf]="formControl.enabled">
<icon *ngIf="!searchControl?.value && icon" [name]="icon" [flex]="true"></icon>
<icon *ngIf="!icon && selectable && selectArrow" [name]="selectArrow" [flex]="true"></icon>
<button *ngIf="!!searchControl?.value && type === 'autocomplete'" class="uk-close uk-icon"
<button *ngIf="!!searchControl?.value && type === 'autocomplete'" class="uk-close uk-icon"
(click)="resetSearch($event)">
<icon [flex]="true" name="close"></icon>
</button>
<button *ngIf="!!formControl?.value && searchable" class="uk-close uk-icon" (click)="resetValue($event)">
<button *ngIf="!searchControl?.value && !!formControl?.value && (searchable || !selectable)" class="uk-close uk-icon" (click)="resetValue($event)">
<icon [flex]="true" name="close"></icon>
</button>
</ng-template>
</div>
<ng-content select="[action]"></ng-content>
</div>
<div class="tools">
<ng-content select="[tools]"></ng-content>
@ -155,10 +159,10 @@ declare var UIkit;
<span *ngIf="formControl.errors.error">{{formControl.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-danger uk-text-small">
<span class="uk-text-small uk-text-danger">
<ng-content select="[error]"></ng-content>
</span>
<span *ngIf="formControl?.valid" class="uk-text-warning uk-text-small">
<span *ngIf="formControl?.valid" class="uk-text-small uk-text-warning uk-margin-xsmall-top">
<ng-content select="[warning]"></ng-content>
<span *ngIf="!secure">
<span class="uk-text-bold">Note:</span> Prefer urls like "<span class="uk-text-bold">https://</span>example.com/my-secure-image.png"
@ -166,34 +170,13 @@ declare var UIkit;
<span class="uk-text-bold">Browsers may not load non secure content.</span>
</span>
</span>
<span class="uk-text-small">
<i class="uk-text-small uk-text-meta uk-margin-xsmall-top">
<ng-content select="[note]"></ng-content>
</span>
</i>
`
})
export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChanges {
private static INPUT_COUNTER: number = 0;
/** Deprecated options*/
/** @deprecated */
@Input('label') label: string;
/** @deprecated */
@Input() extraLeft: boolean = true;
/** @deprecated */
@Input() gridSmall: boolean = false;
/** @deprecated */
@Input() hideControl: boolean = false;
/** @deprecated */
@Input() flex: 'middle' | 'top' | 'bottom' = 'middle';
/** @deprecated */
@Input() iconLeft: boolean = false;
/** @deprecated */
@Input() removable: boolean = true;
/** @deprecated */
@Input() smallChip: boolean = false;
/** @deprecated */
@Input() panelWidth: number = 300;
/** @deprecated */
@Input() panelClass: string = null;
/** Basic information */
@Input('formInput') formControl: AbstractControl;
@Input('type') type: InputType = 'text';
@ -226,6 +209,8 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
/** Chip options */
@Input() addExtraChips: boolean = false;
@Input() showOptionsOnEmpty: boolean = true;
@Input() visibleChips: number = 1;
@Input() separators: string[] = [];
@Output() focusEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
/** LogoUrl information */
public secure: boolean = true;
@ -324,6 +309,14 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
}
}
@HostListener('keydown', ['$event'])
onKeyDown(event: KeyboardEvent) {
if (this.separators.includes(event.key)) {
event.preventDefault();
this.add(event, true);
}
}
click(event: ClickEvent) {
this.focus(!event.clicked, event);
}
@ -338,8 +331,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
this.formAsArray.push(new UntypedFormControl(value, this.validators));
});
} else {
this.formControl = new UntypedFormControl(this.value);
this.formControl.setValidators(this.validators);
this.formControl = new UntypedFormControl(this.value, this.validators);
}
if (this.disabled) {
this.formControl.disable();
@ -356,6 +348,9 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
if (changes.value) {
this.formControl.setValue(this.value);
}
if(changes.validators) {
this.updateValidators();
}
if (changes.formControl || changes.validators || changes.options) {
this.reset();
}
@ -456,6 +451,18 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
});
}
updateValidators() {
if(this.formAsArray) {
this.formAsArray.controls.forEach(control => {
control.setValidators(this.validators);
control.updateValueAndValidity();
})
} else {
this.formControl.setValidators(this.validators);
this.formControl.updateValueAndValidity();
}
}
remove(index: number, event) {
if (this.focused) {
this.formAsArray.removeAt(index);
@ -484,15 +491,17 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
return options;
}
add(event) {
if (this.addExtraChips && this.searchControl.value && this.searchControl.valid) {
add(event, addChips = false) {
if (addChips && this.searchControl.value && this.searchControl.valid) {
if (event && event.stopPropagation) {
event.stopPropagation();
}
this.formAsArray.push(new UntypedFormControl(this.searchControl.value, this.validators));
this.formAsArray.markAsDirty();
this.searchControl.setValue('');
} else if(!this.focused) {
this.searchControl.setValue('');
}
this.searchControl.setValue('');
}
getLabel(value: any): string {
@ -534,7 +543,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
this.searchInput.nativeElement.blur();
}
if (this.searchControl) {
this.add(event);
this.add(event, this.addExtraChips);
}
}
this.focusEmitter.emit(this.focused);

View File

@ -18,8 +18,9 @@ import {NotificationHandler} from "../../utils/notification-handler";
<div *ngIf="body" class="uk-grid uk-child-width-1-1" uk-grid [formGroup]="inviteForm">
<div input [formInput]="inviteForm.get('name')" placeholder="From"></div>
<div input [formInput]="inviteForm.get('recipients')" type="chips"
placeholder="Recipients" hint="Add a recipient"
[addExtraChips]="true" [validators]="validators">
placeholder="Recipients" hint="Add a recipient" [visibleChips]="3"
[addExtraChips]="true" [validators]="validators" [separators]="[',']">
<div note>Separate emails with commas</div>
</div>
<div>
<label class="uk-text-meta">Message *</label>