packages/data/src/lib/entry-list-select/entry-list-select.component.ts
ControlValueAccessor
OnInit
OnChanges
encapsulation | ViewEncapsulation.None |
providers |
{
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EntryListSelectComponent), multi: true,
}
|
selector | ec-entry-list-select |
templateUrl | ./entry-list-select.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
constructor(modelConfig: ModelConfigService, symbol: SymbolService, componentFactoryResolver: ComponentFactoryResolver, cdr: ChangeDetectorRef)
|
|||||||||||||||
Parameters :
|
listConfig | |
Type : CrudConfig<EntryResource>
|
|
The config for the entry list |
model | |
Type : string
|
|
The model that is picked from |
selection | |
Type : Selection<EntryResource>
|
|
The selection that should be edited |
selectionConfig | |
Type : ListConfig<LiteEntryResource>
|
|
The config for the selection list. |
component | |
Type : Type<any>
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:52
|
|
Overrides the default component |
config | |
Type : FieldConfigProperty
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:50
|
|
Config that should be used, only needed when not using field input |
control | |
Type : AbstractControl
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:36
|
|
The belonging form control. This is not required if you pass in a field and group. |
debounce | |
Default value : 0
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:42
|
|
Debounce time in ms before the changed event emits. |
field | |
Type : Field
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:44
|
|
The instance of field that should be used in the template, can also be a property name. |
group | |
Type : FormGroup
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:32
|
|
The belonging form group |
item | |
Type : Item<any>
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:48
|
|
The belonging item |
lazy | |
Type : boolean
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:54
|
|
If true, the input will never reinit/reload. |
property | |
Type : string
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:46
|
|
The property name that is edited. Expects a form as item input |
changed | |
Type : EventEmitter
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:38
|
|
The changed ouput emits whenever the form control of the input changes. |
ready | |
Type : EventEmitter
|
|
Inherited from
InputComponent
|
|
Defined in
InputComponent:40
|
|
Emits when the component has been loaded |
formSubmitted | ||||||
formSubmitted(form: Form
|
||||||
Is called when the nested entry-form has been saved. Selects the fresh entry and clears the form
Parameters :
Returns :
void
|
init |
init()
|
Initializes the input. Reads relation from field. Generates model config + adds remove buttons.
Returns :
void
|
initSelection | ||||||
initSelection(config)
|
||||||
Initializes the selection with listConfig. Propagates change
Parameters :
Returns :
void
|
ngOnChanges |
ngOnChanges()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Calls init
Returns :
void
|
registerOnChange | ||||
registerOnChange(fn)
|
||||
registers change method. (handled by angular)
Parameters :
Returns :
void
|
registerOnTouched |
registerOnTouched()
|
Returns :
void
|
removeItem | ||||
removeItem(item)
|
||||
Removes the given item from the selection
Parameters :
Returns :
void
|
writeValue | ||||||
writeValue(value: any)
|
||||||
Called when the model changes
Parameters :
Returns :
void
|
connectControl |
connectControl()
|
Inherited from
InputComponent
|
Defined in
InputComponent:118
|
Returns :
void
|
focus | ||||||
focus(focus)
|
||||||
Inherited from
InputComponent
|
||||||
Defined in
InputComponent:69
|
||||||
Parameters :
Returns :
void
|
init |
init()
|
Inherited from
InputComponent
|
Defined in
InputComponent:77
|
Returns :
void
|
ngOnChanges | ||||
ngOnChanges(changes?)
|
||||
Inherited from
InputComponent
|
||||
Defined in
InputComponent:63
|
||||
Parameters :
Returns :
void
|
registerOnChange | ||||
registerOnChange(fn)
|
||||
Inherited from
InputComponent
|
||||
Defined in
InputComponent:143
|
||||
Registers change callback
Parameters :
Returns :
void
|
registerOnTouched |
registerOnTouched()
|
Inherited from
InputComponent
|
Defined in
InputComponent:148
|
Returns :
void
|
setDisabledState | ||||
setDisabledState(isDisabled)
|
||||
Inherited from
InputComponent
|
||||
Defined in
InputComponent:150
|
||||
Parameters :
Returns :
void
|
writeValue | ||||||
writeValue(value: any)
|
||||||
Inherited from
InputComponent
|
||||||
Defined in
InputComponent:133
|
||||||
writes value to editor on outside model change.
Parameters :
Returns :
void
|
loadComponent | ||||||||||||
loadComponent(component: Type
|
||||||||||||
Inherited from
DynamicSlotComponent
|
||||||||||||
Defined in
DynamicSlotComponent:17
|
||||||||||||
Loads the given component inside the fieldHost. Sets current item and field by default.
Parameters :
Returns :
ComponentRef<any>
|
Public cdr |
Type : ChangeDetectorRef
|
Public componentFactoryResolver |
Type : ComponentFactoryResolver
|
entryList |
Type : EntryListComponent
|
Decorators :
@ViewChild(EntryListComponent)
|
The nested entryList |
items |
Type : EntryResource[]
|
The current selected entries |
Public modelConfig |
Type : ModelConfigService
|
propagateChange |
Default value : () => {...}
|
Propagates formControl/ngModel changes |
Public symbol |
Type : SymbolService
|
value |
Type : []
|
Default value : []
|
The current value of the input |
componentInstance |
Type : InputComponent
|
Inherited from
InputComponent
|
Defined in
InputComponent:57
|
Holds a reference to the component instance. This is helpful when you want to modify the component after form intialization. You can access a form's InputComponents via FormComponent#inputs |
disabled |
Type : FormGroup
|
Inherited from
InputComponent
|
Defined in
InputComponent:34
|
If true, the input is readonly. Is set by ControlValueAccessor#setDisabled |
focusEvent |
Type : EventEmitter<boolean>
|
Default value : new EventEmitter()
|
Inherited from
InputComponent
|
Defined in
InputComponent:61
|
Emitter to focus the input field |
propagateChange |
Default value : () => {...}
|
Inherited from
InputComponent
|
Defined in
InputComponent:140
|
value |
Type : any
|
Inherited from
InputComponent
|
Defined in
InputComponent:59
|
The current value of the input. Needs to be saved for the case the component is not yet loaded |
Public componentFactoryResolver |
Type : ComponentFactoryResolver
|
Inherited from
DynamicSlotComponent
|
Defined in
DynamicSlotComponent:14
|
fieldHost |
Type : SlotHostDirective
|
Decorators :
@ViewChild(SlotHostDirective, {static: true})
|
Inherited from
DynamicSlotComponent
|
Defined in
DynamicSlotComponent:11
|
The FieldHostDirective will be used to nest custom components into the field |
import {
Component,
OnInit,
ViewEncapsulation,
forwardRef,
Input,
OnChanges,
ViewChild,
ComponentFactoryResolver,
ChangeDetectorRef,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Selection, ListConfig, Form } from '@ec.components/core';
import EntryResource from 'ec.sdk/lib/resources/publicAPI/EntryResource';
import { ModelConfigService } from '../model-config/model-config.service';
import { CrudConfig } from '../crud/crud-config.interface';
import { EntryListComponent } from '../entry-list/entry-list.component';
import { InputComponent, SymbolService } from '@ec.components/ui';
import LiteEntryResource from 'ec.sdk/lib/resources/publicAPI/LiteEntryResource';
@Component({
selector: 'ec-entry-list-select',
templateUrl: './entry-list-select.component.html',
encapsulation: ViewEncapsulation.None,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => EntryListSelectComponent),
multi: true,
},
],
})
/** Renders a Selection inside a list with full crud support. It can act as a replacement for ec-entry-select. */
export class EntryListSelectComponent extends InputComponent implements ControlValueAccessor, OnInit, OnChanges {
/** The model that is picked from */
@Input() model: string;
/** The selection that should be edited */
@Input() selection: Selection<EntryResource>;
/** The config for the entry list */
@Input() listConfig: CrudConfig<EntryResource>;
/** The nested entryList */
@ViewChild(EntryListComponent) entryList: EntryListComponent;
/** The current selected entries */
items: EntryResource[];
/** The config for the selection list. */
@Input() selectionConfig: ListConfig<LiteEntryResource>;
/** The current value of the input */
value = [];
constructor(
public modelConfig: ModelConfigService,
public symbol: SymbolService,
public componentFactoryResolver: ComponentFactoryResolver,
public cdr: ChangeDetectorRef,
) {
super(componentFactoryResolver);
}
/** Calls init */
ngOnInit() {
this.init();
}
ngOnChanges() {
/* this.init(); */
}
/** Initializes the input. Reads relation from field. Generates model config + adds remove buttons. */
init() {
if (this.field && !this.model) {
this.model = this.field.relation;
}
if (!this.model) {
return;
}
this.modelConfig.generateConfig(this.model, (this.listConfig || {}).fields).then((config) => {
this.listConfig = config;
this.selectionConfig = Object.assign({}, this.listConfig, {
disableHeader: false,
defaultFilter: false,
hidePagination: true,
fields: Object.assign(
{},
this.listConfig.fields,
{
_modified: Object.assign({}, config.fields._modified, { hideInList: true }),
},
{
button: {
label: this.symbol.resolve('entry.select.remove'),
form: false,
resolve: () => ' ',
view: 'link',
class: 'btn btn_clear',
icon: 'close',
action: (item, property) => {
this.selection.remove(item);
},
hideInList: this.disabled,
},
},
),
});
Object.keys(this.selectionConfig.fields).forEach((key) => {
if (this.selectionConfig.fields[key].type !== 'text') {
this.selectionConfig.fields[key].filterable = false;
}
});
this.initSelection();
});
}
/** Initializes the selection with listConfig. Propagates change */
initSelection(config = this.listConfig) {
this.selection = this.selection || new Selection(this.value, config);
this.items = this.selection.items.map((item) => item.getBody());
this.cdr.markForCheck();
this.selection.update$.subscribe(() => {
this.items = this.selection.items.map((item) => item.getBody());
this.propagateChange(this.selection.getValue());
this.cdr.markForCheck();
});
}
/** Is called when the nested entry-form has been saved. Selects the fresh entry and clears the form */
formSubmitted(form: Form<EntryResource>) {
if (!this.selection.has(form)) {
this.selection.add(form);
} else {
// already in selection => update body
const index = this.selection.index(form);
this.selection.items[index].body = form.getBody();
this.selection['update'].next(this.selection); // trigger update manually
}
}
/** Removes the given item from the selection */
removeItem(item) {
this.selection.remove(item);
}
/** Called when the model changes */
writeValue(value: any) {
this.value = value || [];
if (this.selection) {
this.selection.replaceWith(this.value);
}
}
/** Propagates formControl/ngModel changes */
propagateChange = (_: any) => { };
/** registers change method. (handled by angular) */
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() { }
}
<ec-entry-list-pop #entryListPop [model]="model" [selection]="selection"></ec-entry-list-pop>
<ec-list
[config]="selectionConfig"
[items]="items"
(columnClicked)="entryPop.edit($event.getBody())"
#selectionList
></ec-list>
<ec-entry-pop
[model]="model"
#entryPop
(submitted)="formSubmitted($event)"
(deleted)="removeItem($event)"
></ec-entry-pop>
<a class="btn btn_clear btn_square" (click)="entryPop.create()" *ngIf="!disabled && model">
<ec-icon name="add"></ec-icon>
</a>
<a class="btn btn_clear btn_square" (click)="entryListPop.show()" *ngIf="!disabled">
<ec-icon name="search"></ec-icon>
</a>