Skip to content
This repository was archived by the owner on Nov 21, 2024. It is now read-only.

Commit bf2d031

Browse files
committed
fix(select-input): Fix work typeahead and add async loading #81
1 parent 16c42ba commit bf2d031

File tree

6 files changed

+81
-30
lines changed

6 files changed

+81
-30
lines changed

libs/web/src/base/base-resources-grid/base-resource-select-input/base-resource-select-input.component.ts

+17
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ export class BaseResourceSelectInputComponent extends BaseResourcesListComponent
5151

5252
config: BaseResourceSelectInputConfig;
5353

54+
prevValue: string;
55+
5456
get value() {
5557
return this.model;
5658
}
@@ -123,4 +125,19 @@ export class BaseResourceSelectInputComponent extends BaseResourcesListComponent
123125
this.search();
124126
}
125127
}
128+
changeInputValue(value: string) {
129+
const filter: any = {};
130+
if (this.cachedResourcesService && this.prevValue !== value) {
131+
this.cachedResourcesService.ignoreCache = true;
132+
this.cachedResourcesService.loadAll(value, filter);
133+
}
134+
this.prevValue = value;
135+
}
136+
focusInput(value: string) {
137+
const filter: any = {};
138+
if (this.cachedResourcesService) {
139+
this.cachedResourcesService.ignoreCache = true;
140+
this.cachedResourcesService.loadAll(value, filter);
141+
}
142+
}
126143
}

libs/web/src/controls/select-input/select-input.component.html

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
[typeaheadOptionsInScrollableView]="5" [typeaheadMinLength]="0" [attr.placeholder]="placeholder" (typeaheadOnSelect)="value = $event.item"
77
(typeaheadNoResults)="onTypeaheadNoResults($event)" [ngClass]="inputClass" [disabled]="readonly && inputReadonly" [attr.id]="'input'+name"
88
[attr.name]="'input'+name" [tooltip]="tooltipText" tooltipPlacement="{{tooltipPlacement}}" tooltipTrigger="{{tooltipTriggers}}"
9-
[isDisabled]="!tooltipEnable" (onShown)="showTooltip()" #tooltip="bs-tooltip" #inputElement/>
9+
[isDisabled]="!tooltipEnable" (onShown)="showTooltip()" #tooltip="bs-tooltip" (focus)="inputFocus(textValue)" (typeaheadLoading)="loading($event)"
10+
autocomplete="off" #typeahead="bs-typeahead" #inputElement/>
1011
</div>
1112
<span class="help-block" *ngIf="!tooltipEnable && (errorMessage || infoMessage)" [innerHtml]="(errorMessage || infoMessage) | safeHtml"></span>
1213
</div>
@@ -16,7 +17,8 @@
1617
[typeaheadOptionsInScrollableView]="5" [typeaheadMinLength]="0" [attr.placeholder]="placeholder" (typeaheadOnSelect)="value = $event.item"
1718
(typeaheadNoResults)="onTypeaheadNoResults($event)" [ngClass]="inputClass" [disabled]="readonly && inputReadonly" [attr.id]="'input'+name"
1819
[attr.name]="'input'+name" [tooltip]="tooltipText" tooltipPlacement="{{tooltipPlacement}}" tooltipTrigger="{{tooltipTriggers}}"
19-
[isDisabled]="!tooltipEnable" (onShown)="showTooltip()" #tooltip="bs-tooltip" #inputElement/>
20+
[isDisabled]="!tooltipEnable" (onShown)="showTooltip()" #tooltip="bs-tooltip" (focus)="inputFocus(textValue)" (typeaheadLoading)="loading($event)"
21+
autocomplete="off" #typeahead="bs-typeahead" #inputElement/>
2022
</div>
2123
</div>
2224
</div>

libs/web/src/controls/select-input/select-input.component.ts

+46-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
1+
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
22
import { Injector } from '@angular/core';
33
import { SafeHtml } from '@angular/platform-browser';
44
import { TooltipDirective } from 'ngx-bootstrap/tooltip';
5+
import { TypeaheadDirective } from 'ngx-bootstrap/typeahead';
56
import { debounceTime } from 'rxjs/operators';
67
import { Subject } from 'rxjs/Subject';
8+
import { setTimeout } from 'timers';
79

810
import { BaseComponent } from './../../base/base-component/base-component.component';
911
import { SelectInputConfig } from './select-input.config';
@@ -17,13 +19,17 @@ export class SelectInputComponent extends BaseComponent {
1719

1820
@ViewChild('tooltip')
1921
tooltip: TooltipDirective;
22+
@ViewChild('typeahead')
23+
typeahead: TypeaheadDirective;
2024
@ViewChild('inputElement')
2125
inputElement: ElementRef;
2226

2327
@Input()
2428
debounceTime?: number;
2529
@Output()
2630
onChangeInputValue: EventEmitter<string> = new EventEmitter<string>();
31+
@Output()
32+
onInputFocus: EventEmitter<string> = new EventEmitter<string>();
2733
@Input()
2834
labelClass?= 'control-label';
2935
@Input()
@@ -55,10 +61,16 @@ export class SelectInputComponent extends BaseComponent {
5561
@Input()
5662
width: string = null;
5763
@Input()
58-
set items(items: any[]) {
64+
dataSource: Subject<any[]>;
65+
@Input()
66+
set items(items: any) {
5967
this._items = items;
68+
this.resizeList();
6069
}
61-
get items() {
70+
get items(): any {
71+
if (this.dataSource) {
72+
return this.dataSource;
73+
}
6274
return this._items;
6375
}
6476
@Input()
@@ -67,6 +79,7 @@ export class SelectInputComponent extends BaseComponent {
6779
if (this._textValue === '') {
6880
this.value = null;
6981
}
82+
this.debouncer$.next(this.textValue);
7083
}
7184
get textValue() {
7285
return this._textValue;
@@ -80,7 +93,8 @@ export class SelectInputComponent extends BaseComponent {
8093
private _showMe = false;
8194

8295
constructor(
83-
public injector: Injector
96+
public injector: Injector,
97+
public changeDetectorRef: ChangeDetectorRef
8498
) {
8599
super(injector);
86100
this.debouncer$ = new Subject<string>();
@@ -105,6 +119,9 @@ export class SelectInputComponent extends BaseComponent {
105119
this.debouncer$.pipe(debounceTime(this.debounceTime))
106120
.subscribe((value: string) => this.onChangeInputValue.emit(value));
107121
}
122+
inputFocus(value: string) {
123+
this.onInputFocus.emit(value);
124+
}
108125
get inputReadonly() {
109126
return this.onChangeInputValue.observers && this.onChangeInputValue.observers.length === 0;
110127
}
@@ -123,7 +140,6 @@ export class SelectInputComponent extends BaseComponent {
123140
// this.textValue = '';
124141
this.model = null;
125142
}
126-
this.debouncer$.next(this.textValue);
127143
this.modelChange.emit(this.model);
128144
}
129145
onTypeaheadNoResults(typeaheadNoResults: boolean) {
@@ -135,8 +151,10 @@ export class SelectInputComponent extends BaseComponent {
135151
if (this.hardValue) {
136152
this.value = this.hardValue;
137153
}
138-
this.value = this.value;
139154
super.init();
155+
if (!this.textValue) {
156+
this.value = this.value;
157+
}
140158
}
141159
getTitle(item: any): SafeHtml | string {
142160
if (item && item[this.titleField]) {
@@ -160,4 +178,26 @@ export class SelectInputComponent extends BaseComponent {
160178
}
161179
return '';
162180
}
181+
loading(status: boolean) {
182+
if (!status) {
183+
this.resizeList();
184+
}
185+
}
186+
resizeList() {
187+
setTimeout(() => {
188+
if (this.changeDetectorRef) {
189+
this.changeDetectorRef.detectChanges();
190+
if (this.typeahead && this.typeahead._container) {
191+
if (this.typeahead._container.element.nativeElement.children[0]) {
192+
const list: any = this.typeahead._container.element.nativeElement.children[0];
193+
if (this.width === null) {
194+
list.style.width = this.inputElement.nativeElement.offsetWidth + 'px';
195+
} else {
196+
list.style.width = this.width;
197+
}
198+
}
199+
}
200+
}
201+
}, 1);
202+
}
163203
}

libs/web/src/grids/content-types-grid/content-type-select-input/content-type-select-input.component.html

+12-9
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
<label *ngIf="title" [ngClass]="labelClass" [attr.for]="'input'+name">{{title | translate}}</label>
33
<div [ngClass]="{'input-group':!readonly && !select}" class="{{inputFrameClass}}" [tooltip]="tooltipText" placement="{{tooltipPlacement}}"
44
triggers="{{tooltipTriggers}}" [isDisabled]="!tooltipEnable" (onShown)="showTooltip()" #tooltip="bs-tooltip">
5-
<input *ngIf="statusListMessage || (select && !items.length)" value="{{statusListMessage | translate}}" [ngClass]="inputClass" disabled/>
6-
<input *ngIf="!statusListMessage && !select" [(ngModel)]="value && value.asString" [ngClass]="inputClass" #inputElement disabled/>
7-
<select-input *ngIf="!statusListMessage && select && items && items.length>0" [(model)]="value" [title]="title" titleField="asSelectOptionHtml" inputTitleField="asString"
8-
[readonly]="readonly" [items]="items" [inFormGroup]="false" [width]="width" #inputElement></select-input>
5+
<input *ngIf="statusListMessage" value="{{statusListMessage | translate}}" [ngClass]="inputClass" readonly/>
6+
<input *ngIf="!statusListMessage && !select" [(ngModel)]="value && value.asString" [ngClass]="inputClass" #inputElement readonly/>
7+
<select-input *ngIf="!statusListMessage && select" [(model)]="value" [title]="title" titleField="asSelectOptionHtml" inputTitleField="asString"
8+
[readonly]="readonly" (onChangeInputValue)="changeInputValue($event)" [dataSource]="cachedResourcesService.items$" (onInputFocus)="focusInput($event)"
9+
[inFormGroup]="false" [width]="width" #inputElement></select-input>
910
<span class="input-group-btn" *ngIf="!readonly && !select">
10-
<button class="btn btn-success" type="button" (click)="onLookup()"
11-
tooltip="{{lookupTooltip}}" placement="left" container="body">
12-
<span [ngClass]="[lookupIcon]"></span>
13-
</button>
11+
<button class="btn btn-default" type="button" (click)="value=null">
12+
<span class="fa fa-times"></span>
13+
</button>
14+
<button class="btn btn-success" type="button" (click)="onLookup()" tooltip="{{lookupTooltip}}" placement="left" container="body">
15+
<span [ngClass]="[lookupIcon]"></span>
16+
</button>
1417
</span>
1518
</div>
1619
<span class="help-block" *ngIf="!tooltipEnable && (errorMessage || infoMessage)" [innerHtml]="(errorMessage || infoMessage) | safeHtml"></span>
17-
</div>
20+
</div>

libs/web/src/grids/content-types-grid/content-type-select-input/content-type-select-input.component.ts

+1-12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export class ContentTypeSelectInputComponent extends BaseResourceSelectInputComp
2828
@Output()
2929
modelChange: EventEmitter<any | ContentType> = new EventEmitter<any | ContentType>();
3030

31+
loadAll = false;
3132
items: any[] | ContentType[];
3233
cachedResourcesService: ContentTypesService;
3334

@@ -41,13 +42,6 @@ export class ContentTypeSelectInputComponent extends BaseResourceSelectInputComp
4142
this.contentTypesService = injector.get(ContentTypesService);
4243
this.cachedResourcesService = this.contentTypesService.createCache();
4344
}
44-
changeInputValue(value: string) {
45-
const filter: any = {};
46-
if (this.cachedResourcesService) {
47-
this.cachedResourcesService.ignoreCache = true;
48-
this.cachedResourcesService.loadAll(value, filter);
49-
}
50-
}
5145
onLookup() {
5246
const itemModal: ContentTypesListModalComponent =
5347
this.app.modals(this.resolver).create(ContentTypesListModalComponent);
@@ -73,8 +67,3 @@ export class ContentTypeSelectInputComponent extends BaseResourceSelectInputComp
7367
return '';
7468
}
7569
}
76-
77-
78-
79-
// WEBPACK FOOTER //
80-
// C:/Projects/open-sources/@rucken/core/libs/web/src/grids/content-types-grid/content-type-select-input/content-type-select-input.component.ts

libs/web/src/grids/permissions-grid/permission-modal/permission-modal.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ <h4 class="modal-title">{{title | translate}}</h4>
1414
[readonly]="readonly" [focused]="true" #focusElement></text-input>
1515
<text-input [errors]="errors" [info]="info" name="title" [(model)]="item.title" [title]="modelMeta.titles.title" [readonly]="readonly"></text-input>
1616
<content-type-select-input [errors]="errors" [info]="info" name="contentType" [(model)]="item.contentType"
17-
[title]="modelMeta.titles.contentType" [select]="true" [readonly]="readonly"></content-type-select-input>
17+
[title]="modelMeta.titles.contentType" [select]="item.pk" [readonly]="readonly"></content-type-select-input>
1818
</div>
1919
<div class="modal-footer">
2020
<footer-buttons (onClose)="close()" (onOk)="ok()" [readonly]="readonly" [okTitle]="okTitle" [okInProcess]="okInProcess"></footer-buttons>

0 commit comments

Comments
 (0)