working autocomplete, should implement search

This commit is contained in:
2023-01-23 03:58:39 +01:00
parent 4553cba89f
commit 893013cdae
4 changed files with 66 additions and 93 deletions

View File

@@ -12,12 +12,10 @@ class EntityRead(Entity):
class EntityCreate(Writer): class EntityCreate(Writer):
name: str
address: str address: str
entity_data: Individual | Corporation = Field(..., discriminator='type') entity_data: Individual | Corporation = Field(..., discriminator='type')
class EntityUpdate(BaseModel): class EntityUpdate(BaseModel):
name: str
address: str address: str
entity_data: Individual | Corporation = Field(..., discriminator='type') entity_data: Individual | Corporation = Field(..., discriminator='type')

View File

@@ -2,9 +2,9 @@ import { FormlyJsonschema } from "@ngx-formly/core/json-schema";
import { FormlyJsonschemaOptions } from "@ngx-formly/core/json-schema/formly-json-schema.service"; import { FormlyJsonschemaOptions } from "@ngx-formly/core/json-schema/formly-json-schema.service";
import { FormlyFieldConfig } from "@ngx-formly/core"; import { FormlyFieldConfig } from "@ngx-formly/core";
import { JSONSchema7 } from 'json-schema'; import { JSONSchema7 } from 'json-schema';
import {JsonschemasService } from "./jsonschemas.service"; import { JsonschemasService } from "./jsonschemas.service";
import {Observable, map, tap} from "rxjs"; import { Observable, map } from "rxjs";
import {Injectable} from "@angular/core"; import { Injectable } from "@angular/core";
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@@ -14,21 +14,29 @@ export class CrudFormlyJsonschemaService extends FormlyJsonschema {
super(); super();
} }
override toFieldConfig(schema: JSONSchema7, options?: FormlyJsonschemaOptions): FormlyFieldConfig { override toFieldConfig(schema: JSONSchema7): FormlyFieldConfig {
return super.toFieldConfig(schema, options); let fieldConfig = super.toFieldConfig(schema, new CrudFormlyJsonschemaOptions());
return fieldConfig;
} }
getCreateFields(resourceName: string): Observable<FormlyFieldConfig> { getCreateFields(resourceName: string): Observable<FormlyFieldConfig> {
return this.jsonSchemasService.getCreateResource(resourceName).pipe( return this.jsonSchemasService.getCreateResource(resourceName).pipe(
map((schemas: any) => this.toFieldConfig(schemas)), map((schemas: any) => this.toFieldConfig(schemas)),
tap(console.log),
) )
} }
getUpdateFields(resourceName: string): Observable<FormlyFieldConfig> { getUpdateFields(resourceName: string): Observable<FormlyFieldConfig> {
return this.jsonSchemasService.getUpdateResource(resourceName).pipe( return this.jsonSchemasService.getUpdateResource(resourceName).pipe(
map((schemas: any) => this.toFieldConfig(schemas)), map((schemas: any) => this.toFieldConfig(schemas)),
tap(console.log),
) )
} }
} }
export class CrudFormlyJsonschemaOptions implements FormlyJsonschemaOptions {
map = (field: any, schema: any) => {
if (schema.hasOwnProperty('foreignKey')) {
field.foreignKey = schema['foreignKey'];
}
return field;
}
}

View File

@@ -12,6 +12,9 @@ import { FieldType, FieldTypeConfig } from '@ngx-formly/core';
class="form-label">{{ props.label }} class="form-label">{{ props.label }}
<span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span> <span *ngIf="props.required && props['hideRequiredMarker'] !== true" aria-hidden="true">*</span>
</label> </label>
<div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors">
<formly-validation-message [field]="field"></formly-validation-message>
</div>
<div class="input-group" *ngIf="! this.field.props.readonly"> <div class="input-group" *ngIf="! this.field.props.readonly">
<input type="hidden" <input type="hidden"
[formControl]="formControl" [formControl]="formControl"

View File

@@ -1,74 +1,13 @@
import {Component, OnInit} from '@angular/core'; import {AfterContentInit, Component, OnInit} from '@angular/core';
import {Observable, OperatorFunction, switchMapTo, of, from, exhaustAll, mergeAll, concatAll} from 'rxjs'; import {Observable, OperatorFunction, switchMapTo, of, from, exhaustAll, mergeAll, concatAll} from 'rxjs';
import { catchError } from 'rxjs/operators'; import { catchError } from 'rxjs/operators';
import { debounceTime, distinctUntilChanged, map, tap, merge } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, map, tap, merge } from 'rxjs/operators';
import { FieldType, FieldTypeConfig} from '@ngx-formly/core'; import { FieldType, FieldTypeConfig} from '@ngx-formly/core';
import {CrudService} from "../crud.service"; import {CrudService} from "../crud.service";
import {formatDate} from "@angular/common";
const states = [
'Alabama',
'Alaska',
'American Samoa',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'District Of Columbia',
'Federated States Of Micronesia',
'Florida',
'Georgia',
'Guam',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Marshall Islands',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Northern Mariana Islands',
'Ohio',
'Oklahoma',
'Oregon',
'Palau',
'Pennsylvania',
'Puerto Rico',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virgin Islands',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
];
@Component({ @Component({
selector: 'formly-array-type', selector: 'formly-foreignkey-type',
template: ` template: `
<div class="mb-3"> <div class="mb-3">
<label *ngIf="props.label && props['hideLabel'] !== true" [attr.for]="id" <label *ngIf="props.label && props['hideLabel'] !== true" [attr.for]="id"
@@ -79,28 +18,41 @@ const states = [
<div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors"> <div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors">
<formly-validation-message [field]="field"></formly-validation-message> <formly-validation-message [field]="field"></formly-validation-message>
</div> </div>
<div class="input-group" *ngIf="! this.hasValue()">
<input
class="form-control"
name="autocomplete"
[(ngModel)]="foreignId"
/>
<div class="input-group">
<input type="text" <input type="text"
class="form-control" class="form-control"
placeholder="Type the first letters..." placeholder="Type the first letters..."
[(ngModel)]="foreignId" (selectItem)="selectedItem($event)"
[ngbTypeahead]="search" > [(ngModel)]="foreignModel"
[ngbTypeahead]="search"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
[editable]="false" />
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-outline-secondary cil-plus" type="button">Button</button> <button class="btn btn-outline-secondary cil-plus" type="button">Add</button>
</div>
</div>
<div class="input-group" *ngIf="this.hasValue()">
<input type="text"
class="form-control"
value="{{this.foreignModel.label}}"
disabled=""
readonly="readonly"
/>
<div class="input-group-append">
<button class="btn btn-outline-secondary cil-plus" type="button">See</button>
</div>
<div class="input-group-append">
<button class="btn btn-outline-secondary cil-plus" type="button">Remove</button>
</div> </div>
</div> </div>
</div> </div>
`, `,
}) })
export class ForeignkeyTypeComponent extends FieldType<FieldTypeConfig> implements OnInit export class ForeignkeyTypeComponent extends FieldType<FieldTypeConfig> implements AfterContentInit
{ {
public foreignModel: any = {}
public foreignLabel: string = ""
public foreignId: string = "" public foreignId: string = ""
public foreignResource : string = ""; public foreignResource : string = "";
public errorMsg: string = ""; public errorMsg: string = "";
@@ -109,20 +61,24 @@ export class ForeignkeyTypeComponent extends FieldType<FieldTypeConfig> implemen
super(); super();
} }
asyncSelected: string = "toto";
typeaheadLoading: boolean = false; typeaheadLoading: boolean = false;
typeaheadNoResults: boolean = true; typeaheadNoResults: boolean = true;
dataSource: Observable<any> = new Observable(); dataSource: Observable<any> = new Observable();
formatter = (foreignModel: any) => foreignModel.label;
ngOnInit() {
this.foreignResource = this.field.key!.toString().split('_')[0]; ngAfterContentInit() {
this.dataSource = new Observable((observer: any) => { // @ts-ignore
observer.next(this.asyncSelected); this.foreignResource = this.field.foreignKey.reference.resource;
}) if (this.hasValue()) {
this.crudService.get(this.foreignResource, this.formControl.value).subscribe((value: any) => {
this.foreignModel = value;
this.foreignLabel = this.foreignModel.label;
});
}
} }
// fired every time search string is changed
search: OperatorFunction<string, readonly string[]> = (text$: Observable<string>) => { search: OperatorFunction<string, readonly string[]> = (text$: Observable<string>) => {
return text$.pipe( return text$.pipe(
debounceTime(200), debounceTime(200),
@@ -136,7 +92,15 @@ export class ForeignkeyTypeComponent extends FieldType<FieldTypeConfig> implemen
return this.crudService.getList(this.foreignResource, 0, 10, '_id', 'asc') return this.crudService.getList(this.foreignResource, 0, 10, '_id', 'asc')
.pipe( .pipe(
map((result: any) => result["items"]), map((result: any) => result["items"]),
tap(console.log),
); );
} }
selectedItem(event: any) {
this.formControl.setValue(event.item._id)
this.foreignLabel = event.item.label;
}
hasValue() {
return this.formControl.value !== undefined;
}
} }