Skip to content
Snippets Groups Projects
Commit 7a758d36 authored by Alex ORLUC's avatar Alex ORLUC
Browse files

FEAT #13271 TIME 4 add select with autocomplete

parent d9c24ca4
No related branches found
No related tags found
No related merge requests found
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
<mat-form-field floatLabel="never" class="basket-search"> <mat-form-field floatLabel="never" class="basket-search">
<input class="metaSearch" type="text" matInput [matAutocomplete]="autoCriteria" <input class="metaSearch" type="text" matInput [matAutocomplete]="autoCriteria"
[placeholder]="'lang.quickSearch' | translate" [formControl]="searchTermControl"> [placeholder]="'lang.quickSearch' | translate" [formControl]="searchTermControl">
<button mat-icon-button matPrefix type="button" (click)="focusFilter()" [title]="'lang.displayCriteria' | translate"> <button mat-icon-button matPrefix type="button" (click)="focusFilter()"
[title]="'lang.displayCriteria' | translate">
<mat-icon class="fas fa-clipboard-list"></mat-icon> <mat-icon class="fas fa-clipboard-list"></mat-icon>
</button> </button>
<mat-autocomplete [class]="hideCriteriaList ? 'hide' : ''" #autoCriteria="matAutocomplete" <mat-autocomplete [class]="hideCriteriaList ? 'hide' : ''" #autoCriteria="matAutocomplete"
...@@ -28,7 +29,8 @@ ...@@ -28,7 +29,8 @@
<span style="background: white;height: 1px;flex: 1;margin-top: 10px;margin-left: 10px;"></span> <span style="background: white;height: 1px;flex: 1;margin-top: 10px;margin-left: 10px;"></span>
</mat-panel-title> </mat-panel-title>
<mat-panel-description class="myCriterias" (click)="$event.stopPropagation()"> <mat-panel-description class="myCriterias" (click)="$event.stopPropagation()">
<button type="button" mat-button class="button-form-primary" style="width: auto; height: 24px; line-height: 0px;" [matMenuTriggerFor]="IndexingModelsMenu"> <button type="button" mat-button class="button-form-primary"
style="width: auto; height: 24px; line-height: 0px;" [matMenuTriggerFor]="IndexingModelsMenu">
{{'lang.mySearchTemplates' | translate}}&nbsp; {{'lang.mySearchTemplates' | translate}}&nbsp;
<i class="fa fa-chevron-down" style="margin: 0 0 0 10px;"></i> <i class="fa fa-chevron-down" style="margin: 0 0 0 10px;"></i>
</button> </button>
...@@ -39,13 +41,15 @@ ...@@ -39,13 +41,15 @@
</span> </span>
<mat-form-field floatLabel="never" appearance="outline" class="smallInput" <mat-form-field floatLabel="never" appearance="outline" class="smallInput"
(click)="$event.stopPropagation();" style="width: 220px !important; padding-top: 10px;"> (click)="$event.stopPropagation();" style="width: 220px !important; padding-top: 10px;">
<input matInput id="searchTerm" placeholder="{{'lang.filterBy' | translate}}" #listFilter autocomplete="off" <input matInput id="searchTerm" placeholder="{{'lang.filterBy' | translate}}"
(click)="$event.stopPropagation();" (keydown)="$event.stopPropagation()"> #listFilter autocomplete="off" (click)="$event.stopPropagation();"
(keydown)="$event.stopPropagation()">
</mat-form-field> </mat-form-field>
</div> </div>
<ng-container <ng-container
*ngFor="let searchTemplate of searchTemplates | filterList:listFilter.value:'label'; let i=index"> *ngFor="let searchTemplate of searchTemplates | filterList:listFilter.value:'label'; let i=index">
<button mat-menu-item (click)="selectSearchTemplate(searchTemplate)" [title]="searchTemplate.label" style="display: flex;align-items: center;"> <button mat-menu-item (click)="selectSearchTemplate(searchTemplate)"
[title]="searchTemplate.label" style="display: flex;align-items: center;">
<div style="flex:1;"> <div style="flex:1;">
{{searchTemplate.label | shorten: 45: '...'}} {{searchTemplate.label | shorten: 45: '...'}}
</div> </div>
...@@ -58,7 +62,9 @@ ...@@ -58,7 +62,9 @@
</button> </button>
</ng-container> </ng-container>
</mat-menu> </mat-menu>
<mat-icon class="far fa-copy" style="color: white; width: 30px; text-align: center; padding-top: 2px;" (click)="$event.stopPropagation();saveSearchTemplate()"> <mat-icon class="far fa-copy"
style="color: white; width: 30px; text-align: center; padding-top: 2px;"
(click)="$event.stopPropagation();saveSearchTemplate()">
</mat-icon> </mat-icon>
</mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>
...@@ -75,7 +81,7 @@ ...@@ -75,7 +81,7 @@
</mat-autocomplete> </mat-autocomplete>
</mat-form-field> </mat-form-field>
</div>--> </div>-->
<div style="display: grid;align-items: center;grid-template-columns: repeat(2, 1fr);"> <div style="display: grid;align-items: start;grid-template-columns: repeat(2, 1fr);max-height: 300px;overflow: hidden;overflow-y: auto;">
<div style="display: grid;align-items: baseline;grid-template-columns: 35% 60% 5%;" <div style="display: grid;align-items: baseline;grid-template-columns: 35% 60% 5%;"
*ngFor="let field of currentCriteria;let i=index"> *ngFor="let field of currentCriteria;let i=index">
<ng-container *ngIf="field.type === 'string'"> <ng-container *ngIf="field.type === 'string'">
...@@ -93,8 +99,7 @@ ...@@ -93,8 +99,7 @@
</span> </span>
<mat-form-field class="input-form" floatLabel="never"> <mat-form-field class="input-form" floatLabel="never">
<input [id]="field.identifier" type="number" matInput [formControl]="field.control" <input [id]="field.identifier" type="number" matInput [formControl]="field.control"
[placeholder]="'lang.typeValue' | translate" [placeholder]="'lang.typeValue' | translate" min="0" step="1">
min="0" step="1">
</mat-form-field> </mat-form-field>
</ng-container> </ng-container>
<ng-container *ngIf="['select', 'radio', 'checkbox'].indexOf(field.type) > -1"> <ng-container *ngIf="['select', 'radio', 'checkbox'].indexOf(field.type) > -1">
...@@ -106,6 +111,17 @@ ...@@ -106,6 +111,17 @@
[datas]="field.values" [multiple]="true" style="width:100%;"> [datas]="field.values" [multiple]="true" style="width:100%;">
</plugin-select-search> </plugin-select-search>
</ng-container> </ng-container>
<ng-container *ngIf="['selectAutocomplete'].indexOf(field.type) > -1">
<span class="criteria-label">
<i class="fa {{field.icon}}"></i> {{field.label}}&nbsp;:&nbsp;
</span>
<plugin-select-autocomplete-search #pluginSelectAutocompleteSearch [id]="field.identifier"
[showResetOption]="true" [label]="field.label"
[placeholderLabel]="'lang.chooseValue' | translate" [formControlSelect]="field.control"
[datas]="field.values" [routeDatas]="field.routeDatas" [multiple]="true"
style="width:100%;">
</plugin-select-autocomplete-search>
</ng-container>
<ng-container *ngIf="field.type === 'date'"> <ng-container *ngIf="field.type === 'date'">
<span class="criteria-label"> <span class="criteria-label">
<i class="fa {{field.icon}}"></i> {{field.label}}&nbsp;:&nbsp; <i class="fa {{field.icon}}"></i> {{field.label}}&nbsp;:&nbsp;
...@@ -113,18 +129,21 @@ ...@@ -113,18 +129,21 @@
<mat-form-field class="input-form input-date" floatLabel="never" (click)="picker.open()" <mat-form-field class="input-form input-date" floatLabel="never" (click)="picker.open()"
style="cursor:pointer;"> style="cursor:pointer;">
<mat-date-range-input [rangePicker]="picker"> <mat-date-range-input [rangePicker]="picker">
<input matStartDate placeholder="Début" (dateChange)="field.control.value.start=$event.value"> <input matStartDate placeholder="Début"
<input matEndDate placeholder="Fin" (dateChange)="field.control.value.end=$event.value"> (dateChange)="field.control.value.start=$event.value">
</mat-date-range-input> <input matEndDate placeholder="Fin"
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle> (dateChange)="field.control.value.end=$event.value">
<mat-date-range-picker #picker></mat-date-range-picker> </mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field> </mat-form-field>
</ng-container> </ng-container>
<ng-container *ngIf="['senders','recipients'].indexOf(field.identifier) > -1"> <ng-container *ngIf="['senders','recipients'].indexOf(field.identifier) > -1">
<span class="criteria-label"> <span class="criteria-label">
<i class="fa {{field.icon}}"></i> {{field.label}}&nbsp;:&nbsp; <i class="fa {{field.icon}}"></i> {{field.label}}&nbsp;:&nbsp;
</span> </span>
<app-contact-autocomplete [id]="field.identifier" [control]="field.control" style="width:100%;"> <app-contact-autocomplete [id]="field.identifier" [control]="field.control"
style="width:100%;">
</app-contact-autocomplete> </app-contact-autocomplete>
</ng-container> </ng-container>
<ng-container *ngIf="field.identifier === 'folders'"> <ng-container *ngIf="field.identifier === 'folders'">
......
...@@ -173,10 +173,18 @@ export class CriteriaToolComponent implements OnInit { ...@@ -173,10 +173,18 @@ export class CriteriaToolComponent implements OnInit {
}; };
} }
this.currentCriteria.forEach((field: any) => { this.currentCriteria.forEach((field: any) => {
if (!this.functions.empty(field.control.value)) { if (field.type === 'date') {
objCriteria[field.identifier] = { if (!this.functions.empty(field.control.value.start) || !this.functions.empty(field.control.value.end)) {
values: field.control.value objCriteria[field.identifier] = {
}; values: field.control.value
};
}
} else {
if (!this.functions.empty(field.control.value)) {
objCriteria[field.identifier] = {
values: field.control.value
};
}
} }
}); });
this.searchUrlGenerated.emit(objCriteria); this.searchUrlGenerated.emit(objCriteria);
...@@ -190,8 +198,12 @@ export class CriteriaToolComponent implements OnInit { ...@@ -190,8 +198,12 @@ export class CriteriaToolComponent implements OnInit {
} else if (['doctype', 'destination'].indexOf(identifier) > -1) { } else if (['doctype', 'destination'].indexOf(identifier) > -1) {
return this.criteria.filter((field: any) => field.identifier === identifier)[0].values.filter((val: any) => val.id === value)[0].title; return this.criteria.filter((field: any) => field.identifier === identifier)[0].values.filter((val: any) => val.id === value)[0].title;
} else { } else {
return this.criteria.filter((field: any) => field.identifier === identifier)[0].values.filter((val: any) => val.id === value)[0].label; if (this.criteria.filter((field: any) => field.identifier === identifier)[0].type === 'selectAutocomplete') {
return 'toto';
} else {
return this.criteria.filter((field: any) => field.identifier === identifier)[0].values.filter((val: any) => val.id === value)[0].label;
}
} }
} }
...@@ -311,8 +323,35 @@ export class CriteriaToolComponent implements OnInit { ...@@ -311,8 +323,35 @@ export class CriteriaToolComponent implements OnInit {
}); });
} }
set_role_field(elem: any) { set_initiator_field(elem: any) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.http.get(`../rest/indexingModels/entities`).pipe(
tap((data: any) => {
let title = '';
elem.values = elem.values.concat(data.entities.map((entity: any) => {
title = entity.entity_label;
for (let index = 0; index < entity.level; index++) {
entity.entity_label = '&nbsp;&nbsp;&nbsp;&nbsp;' + entity.entity_label;
}
return {
id: entity.id,
title: title,
label: entity.entity_label,
disabled: false
};
}));
resolve(true);
})
).subscribe();
});
}
set_role_field(elem: any) {
elem.type = 'selectAutocomplete';
elem.routeDatas = elem.identifier === 'role_dest' ? ['/rest/autocomplete/users'] : ['/rest/autocomplete/users', '/rest/autocomplete/entities'];
/*return new Promise((resolve, reject) => {
this.http.get(`../rest/users`).pipe( this.http.get(`../rest/users`).pipe(
tap((data: any) => { tap((data: any) => {
const arrValues: any[] = []; const arrValues: any[] = [];
...@@ -327,7 +366,7 @@ export class CriteriaToolComponent implements OnInit { ...@@ -327,7 +366,7 @@ export class CriteriaToolComponent implements OnInit {
resolve(true); resolve(true);
}) })
).subscribe(); ).subscribe();
}); });*/
} }
getSearchTemplates() { getSearchTemplates() {
......
...@@ -53,6 +53,7 @@ import { NoteEditorComponent } from './notes/note-editor.component'; ...@@ -53,6 +53,7 @@ import { NoteEditorComponent } from './notes/note-editor.component';
import { PluginAutocomplete } from '../plugins/autocomplete/autocomplete.component'; import { PluginAutocomplete } from '../plugins/autocomplete/autocomplete.component';
import { PluginSelectSearchComponent } from '../plugins/select-search/select-search.component'; import { PluginSelectSearchComponent } from '../plugins/select-search/select-search.component';
import { PluginSelectAutocompleteSearchComponent } from '../plugins/select-autocomplete-search/plugin-select-autocomplete-search.component';
import { DragDropDirective } from '../app/viewer/upload-file-dnd.directive'; import { DragDropDirective } from '../app/viewer/upload-file-dnd.directive';
import { AddressBanAutocompleteComponent } from './contact/ban-autocomplete/address-ban-autocomplete.component'; import { AddressBanAutocompleteComponent } from './contact/ban-autocomplete/address-ban-autocomplete.component';
...@@ -112,6 +113,7 @@ import { TranslateService } from '@ngx-translate/core'; ...@@ -112,6 +113,7 @@ import { TranslateService } from '@ngx-translate/core';
PluginAutocomplete, PluginAutocomplete,
FieldListComponent, FieldListComponent,
PluginSelectSearchComponent, PluginSelectSearchComponent,
PluginSelectAutocompleteSearchComponent,
DiffusionsListComponent, DiffusionsListComponent,
DragDropDirective, DragDropDirective,
ContactAutocompleteComponent, ContactAutocompleteComponent,
...@@ -155,6 +157,7 @@ import { TranslateService } from '@ngx-translate/core'; ...@@ -155,6 +157,7 @@ import { TranslateService } from '@ngx-translate/core';
PluginAutocomplete, PluginAutocomplete,
FieldListComponent, FieldListComponent,
PluginSelectSearchComponent, PluginSelectSearchComponent,
PluginSelectAutocompleteSearchComponent,
DiffusionsListComponent, DiffusionsListComponent,
DragDropDirective, DragDropDirective,
ContactAutocompleteComponent, ContactAutocompleteComponent,
......
<mat-form-field [class]="class + ' search-select'" [floatLabel]="appService.getViewMode() || showLabel ? '' : 'never'">
<mat-label *ngIf="appService.getViewMode() || showLabel">{{label}}</mat-label>
<mat-select [id]="id" [formControl]="formControlSelect" [placeholder]="placeholderLabel" #test
(selectionChange)="launchEvent($event)" (openedChange)="resetACDatas()" [required]="required" [multiple]="multiple">
<input matInput class="mat-select-search-input mat-select-search-hidden" />
<div class="mat-select-search-inner"
[ngClass]="{'mat-select-search-inner-multiple': matSelect.multiple}">
<input matInput id="searchSelectInput" [formControl]="formControlSearch" class="mat-select-search-input"
#searchSelectInput (keydown)="_handleKeydown($event)" (input)="onInputChange($event.target.value)"
(blur)="onBlur($event.target.value)" [placeholder]="'lang.search' | translate" />
<button mat-button *ngIf="formControlSearch.value" mat-icon-button aria-label="Clear" (click)="_reset(true)"
class="mat-select-search-clear">
<mat-icon class="fa fa-times"></mat-icon>
</button>
</div>
<div *ngIf="value && _options?.length === 0 && datas.length > 5" class="mat-select-search-no-entries-found">
{{'lang.noResult' | translate}}
</div>
<mat-option *ngIf="showResetOption" [value]="null"><i>({{'lang.emptyValue' | translate}})</i></mat-option>
<mat-option *ngFor="let value of filteredDatas | async" [value]="returnValue === 'id' ? value.id : value"
[title]="value.title !== undefined ? value.title : value.label" [disabled]="value.disabled"
[class.opt-group]="value.isTitle" [style.color]="value.color">
<span [innerHTML]="value.label"></span>
</mat-option>
<mat-option *ngFor="let value of selecteded" [value]="returnValue === 'id' ? value.id : value"
[title]="value.title !== undefined ? value.title : value.label" [disabled]="value.disabled"
[class.opt-group]="value.isTitle" [style.color]="value.color">
<span [innerHTML]="value.label"></span>
</mat-option>
</mat-select>
<mat-error *ngIf="formControlSelect.status!=='VALID' && formControlSelect.touched && !hideErrorDesc">
{{getErrorMsg(formControlSelect.errors)}}</mat-error>
<mat-icon *ngIf="suffixIcon !== null" style="height: auto;" matSuffix [style.color]="suffixIcon.color"
class="fas fa-circle selectSuffixIcon" [title]="suffixIcon.title !== undefined ? suffixIcon.title : ''">
</mat-icon>
</mat-form-field>
\ No newline at end of file
@import '../../css/vars.scss';
$mat-menu-side-padding: 16px !default;
$scrollbar-width: 17px;
$clear-button-width: 20px;
$multiple-check-width: 33px;
.mat-select-search-hidden {
visibility: hidden;
}
.mat-select-search-inner {
position: absolute;
top: 0;
width: calc(100% + #{2 * $mat-menu-side-padding - $scrollbar-width});
border-bottom: 1px solid #cccccc;
background: white;
z-index: 100;
&.mat-select-search-inner-multiple {
width: calc(100% + #{2 * $mat-menu-side-padding - $scrollbar-width + $multiple-check-width});
}
}
::ng-deep.mat-select-search-panel {
/* allow absolute positioning relative to outer options container */
transform: none !important;
max-height: 350px !important;
max-width: inherit !important;
}
.mat-select-search-input {
padding: $mat-menu-side-padding;
padding-right: $mat-menu-side-padding + $clear-button-width;
box-sizing: border-box;
}
.mat-select-search-no-entries-found {
padding: $mat-menu-side-padding;
}
.mat-select-search-clear {
position: absolute;
right: 0;
top: 4px;
}
::ng-deep.cdk-overlay-pane-select-search {
/* correct offsetY so that the selected option is at the position of the select box when opening */
margin-top: -50px;
}
.mat-error {
font-size: 10px;
text-align: right;
font-weight: bold;
}
.selectSuffixIcon {
font-size: 10px;
text-align: right;
}
.search-select {
::ng-deep.mat-selected:not(.mat-option-disabled) {
font-weight: bold;
}
}
.opt-group {
position: sticky;
top: 50px;
background: white;
z-index: 1;
::ng-deep.mat-pseudo-checkbox {
display: none;
}
}
\ No newline at end of file
import {
AfterViewInit, ChangeDetectorRef,
Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, QueryList,
ViewChild,
Renderer2,
Output
} from '@angular/core';
import { ControlValueAccessor, FormControl } from '@angular/forms';
import { MatOption } from '@angular/material/core';
import { MatSelect } from '@angular/material/select';
import { take, takeUntil, startWith, map, debounceTime, filter, tap, switchMap } from 'rxjs/operators';
import { Subject, ReplaySubject, Observable, forkJoin, of } from 'rxjs';
import { LatinisePipe } from 'ngx-pipes';
import { TranslateService } from '@ngx-translate/core';
import { AppService } from '../../service/app.service';
import { SortPipe } from '../sorting.pipe';
import { FunctionsService } from '../../service/functions.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'plugin-select-autocomplete-search',
templateUrl: 'plugin-select-autocomplete-search.component.html',
styleUrls: ['plugin-select-autocomplete-search.component.scss', '../../app/indexation/indexing-form/indexing-form.component.scss'],
providers: [SortPipe]
})
export class PluginSelectAutocompleteSearchComponent implements OnInit, OnDestroy, AfterViewInit, ControlValueAccessor {
/** Label of the search placeholder */
@Input() placeholderLabel = this.translate.instant('lang.chooseValue');
@Input() formControlSelect: FormControl = new FormControl();
@Input() datas: any = [];
@Input() returnValue: 'id' | 'object' = 'id';
@Input() label: string;
@Input() id: string = '';
@Input() showResetOption: boolean;
@Input() showLabel: boolean = false;
@Input() required: boolean = false;
@Input() hideErrorDesc: boolean = true;
@Input() multiple: boolean = false;
@Input() optGroupTarget: string = null;
/**
* Route datas used in async autocomplete. Incompatible with @datas
*/
@Input() routeDatas: string[];
/**
* ex : [ { id : 'group1' , label: 'Group 1'} ]
*/
@Input() optGroupList: any = null;
/**
* ex : {class:'fa-circle', color:'#fffff', title: 'foo'}
*/
@Input() suffixIcon: any = null;
@Input() class: string = 'input-form';
/**
* Catch external event after select an element in autocomplete
*/
@Output() afterSelected = new EventEmitter();
@Output() afterOpened = new EventEmitter();
/** Reference to the search input field */
@ViewChild('searchSelectInput', { read: ElementRef, static: true }) searchSelectInput: ElementRef;
@ViewChild('test', { static: true }) matSelect: MatSelect;
public filteredDatas: Observable<string[]>;
public filteredDatasMulti: ReplaySubject<any[]> = new ReplaySubject<any[]>(1);
/** Reference to the MatSelect options */
public _options: QueryList<MatOption>;
/** Previously selected values when using <mat-select [multiple]="true">*/
private previousSelectedValues: any[];
/** Whether the backdrop class has been set */
private overlayClassSet = false;
/** Event that emits when the current value changes */
private change = new EventEmitter<string>();
/** Subject that emits when the component has been destroyed. */
private _onDestroy = new Subject<void>();
formControlSearch = new FormControl();
selecteded: any = [];
/** Current search value */
get value(): string {
return this._value;
}
private _value: string;
onChange: Function = (_: any) => { };
onTouched: Function = (_: any) => { };
constructor(
public http: HttpClient,
public translate: TranslateService,
private latinisePipe: LatinisePipe,
private changeDetectorRef: ChangeDetectorRef,
private renderer: Renderer2,
public appService: AppService,
public functions: FunctionsService,
private sortPipe: SortPipe) { }
ngOnInit() {
if (this.optGroupList !== null) {
this.initOptGroups();
}
// set custom panel class
const panelClass = 'mat-select-search-panel';
if (this.matSelect.panelClass) {
if (Array.isArray(this.matSelect.panelClass)) {
this.matSelect.panelClass.push(panelClass);
} else if (typeof this.matSelect.panelClass === 'string') {
this.matSelect.panelClass = [this.matSelect.panelClass, panelClass];
} else if (typeof this.matSelect.panelClass === 'object') {
this.matSelect.panelClass[panelClass] = true;
}
} else {
this.matSelect.panelClass = panelClass;
}
// when the select dropdown panel is opened or closed
this.matSelect.openedChange
.pipe(takeUntil(this._onDestroy))
.subscribe((opened) => {
if (opened) {
// focus the search field when opening
if (!this.appService.getViewMode()) {
this._focus();
}
} else {
// clear it when closing
// this._reset();
this.formControlSearch.reset();
}
});
// set the first item active after the options changed
this.matSelect.openedChange
.pipe(take(1))
.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
this._options = this.matSelect.options;
this._options.changes
.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
const keyManager = this.matSelect._keyManager;
if (keyManager && this.matSelect.panelOpen) {
// avoid "expression has been changed" error
setTimeout(() => {
keyManager.setFirstItemActive();
});
}
});
});
this.formControlSearch.valueChanges
.pipe(
debounceTime(300),
filter(value => value !== null && value.length > 2),
// distinctUntilChanged(),
// tap(() => this.loading = true),
switchMap((data: any) => this.getDatas(data)),
tap((data: any) => {
/*if (data.length === 0) {
if (this.manageDatas !== undefined) {
this.listInfo = this.translate.instant('lang.noAvailableValue') + ' <div>' + this.translate.instant('lang.typeEnterToCreate') + '</div>';
} else {
this.listInfo = this.translate.instant('lang.noAvailableValue');
}
} else {
this.listInfo = '';
}*/
this.datas = this.datas.filter((val: any) => this.formControlSelect.value.indexOf(val.id) > -1).concat(data.filter((val: any) => this.formControlSelect.value.indexOf(val.id) === -1));
this.filteredDatas = of(this.datas);
// this.loading = false;
})
).subscribe();
// this.initMultipleHandling();
}
resetACDatas() {
this.datas = this.datas.filter((val: any) => this.formControlSelect.value.indexOf(val.id) > -1);
this.filteredDatas = of(this.datas);
}
initOptGroups() {
this.datas.unshift({ id: 0, label: 'toto', disabled: true });
let tmpArr = [];
this.optGroupList = this.sortPipe.transform(this.optGroupList, 'label');
this.optGroupList.forEach(group => {
tmpArr.push({ id: group.id, label: group.label, disabled: true });
tmpArr = tmpArr.concat(this.datas.filter(data => data[this.optGroupTarget] === group.id).map(data => {
return {
...data,
title: data.label,
label: '&nbsp;&nbsp;&nbsp' + data.label
};
}));
});
this.datas = tmpArr;
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
ngAfterViewInit() {
if (this.datas.length > 5) {
this.setOverlayClass();
}
}
/**
* Handles the key down event with MatSelect.
* Allows e.g. selecting with enter key, navigation with arrow keys, etc.
* @param {KeyboardEvent} event
* @private
*/
_handleKeydown(event: KeyboardEvent) {
if (event.keyCode === 32) {
// do not propagate spaces to MatSelect, as this would select the currently active option
event.stopPropagation();
}
}
writeValue(value: string) {
const valueChanged = value !== this._value;
if (valueChanged) {
this._value = value;
this.change.emit(value);
}
}
onInputChange(value: any) {
const valueChanged = value !== this._value;
if (valueChanged) {
this._value = value;
this.onChange(value);
this.change.emit(value);
}
}
onBlur(value: string) {
this.writeValue(value);
this.onTouched();
}
registerOnChange(fn: Function) {
this.onChange = fn;
}
registerOnTouched(fn: Function) {
this.onTouched = fn;
}
/**
* Focuses the search input field
* @private
*/
public _focus() {
// save and restore scrollTop of panel, since it will be reset by focus()
// note: this is hacky
const panel = this.matSelect.panel.nativeElement;
const scrollTop = panel.scrollTop;
// focus
this.renderer.selectRootElement('#searchSelectInput').focus();
panel.scrollTop = scrollTop;
}
/**
* Resets the current search value
* @param {boolean} focus whether to focus after resetting
* @private
*/
public _reset(focus?: boolean) {
this.formControlSearch.reset();
this.resetACDatas();
this.renderer.selectRootElement('#searchSelectInput').focus();
}
/**
* Sets the overlay class to correct offsetY
* so that the selected option is at the position of the select box when opening
*/
private setOverlayClass() {
if (this.overlayClassSet) {
return;
}
const overlayClass = 'cdk-overlay-pane-select-search';
this.matSelect.overlayDir.attach
.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
// note: this is hacky, but currently there is no better way to do this
if (this.searchSelectInput !== undefined) {
this.searchSelectInput.nativeElement.parentElement.parentElement
.parentElement.parentElement.parentElement.classList.add(overlayClass);
}
});
this.overlayClassSet = true;
}
/**
* Initializes handling <mat-select [multiple]="true">
* Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
*/
private initMultipleHandling() {
// if <mat-select [multiple]="true">
// store previously selected values and restore them when they are deselected
// because the option is not available while we are currently filtering
this.matSelect.valueChange
.pipe(takeUntil(this._onDestroy))
.subscribe((values) => {
if (this.matSelect.multiple) {
let restoreSelectedValues = false;
if (this._value && this._value.length
&& this.previousSelectedValues && Array.isArray(this.previousSelectedValues)) {
if (!values || !Array.isArray(values)) {
values = [];
}
const optionValues = this.matSelect.options.map(option => option.value);
this.previousSelectedValues.forEach(previousValue => {
if (values.indexOf(previousValue) === -1 && optionValues.indexOf(previousValue) === -1) {
// if a value that was selected before is deselected and not found in the options, it was deselected
// due to the filtering, so we restore it.
values.push(previousValue);
restoreSelectedValues = true;
}
});
}
if (restoreSelectedValues) {
this.matSelect._onChange(values);
}
this.previousSelectedValues = values;
}
});
}
private _filter(value: string, showSelectedValues: boolean = false): string[] {
if (value === '__SELECTED') {
return this.datas.filter((option: any) => this.formControlSelect.value.indexOf(option['id']) > -1);
} else if (typeof value === 'string' && value !== '') {
const filterValue = this.latinisePipe.transform(value.toLowerCase());
return this.datas.filter((option: any) => !option['disabled'] && this.latinisePipe.transform(option['label'].toLowerCase()).includes(filterValue));
} else {
return this.datas;
}
}
launchEvent(ev: any) {
if (this.afterSelected !== undefined) {
this.afterSelected.emit(ev.value);
}
}
getErrorMsg(error: any) {
if (error.required !== undefined) {
return this.translate.instant('lang.requiredField');
} else if (error.pattern !== undefined || error.email !== undefined) {
return this.translate.instant('lang.badFormat');
} else {
return 'unknow validator';
}
}
getDatas(data: string) {
const arrayObs: any = [];
const test: any = [];
this.routeDatas.forEach(element => {
arrayObs.push(this.http.get('..' + element, { params: { 'search': data } }));
});
return forkJoin(arrayObs).pipe(
map(items => {
items.forEach((element: any) => {
element.forEach((element2: any) => {
test.push({
id: element2.id,
label: element2.idToDisplay
});
});
});
return test;
})
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment