Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"@angular/platform-browser": "^7.2.4",
"@angular/platform-browser-dynamic": "^7.2.4",
"@angular/router": "^7.2.4",
"@ng-select/ng-select": "^2.15.3",
"@types/flatpickr": "^3.1.2",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.6",
Expand Down
2 changes: 2 additions & 0 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { GridClientSideComponent } from './examples/grid-clientside.component';
import { GridColspanComponent } from './examples/grid-colspan.component';
import { GridDraggableGroupingComponent } from './examples/grid-draggrouping.component';
import { GridEditorComponent } from './examples/grid-editor.component';
import { GridEditorAngularComponent } from './examples/grid-editor-angular.component';
import { GridFormatterComponent } from './examples/grid-formatter.component';
import { GridFrozenComponent } from './examples/grid-frozen.component';
import { GridGroupingComponent } from './examples/grid-grouping.component';
Expand All @@ -31,6 +32,7 @@ const routes: Routes = [
{ path: 'basic', component: GridBasicComponent },
{ path: 'colspan', component: GridColspanComponent },
{ path: 'editor', component: GridEditorComponent },
{ path: 'editor-angular', component: GridEditorAngularComponent },
{ path: 'formatter', component: GridFormatterComponent },
{ path: 'frozen', component: GridFrozenComponent },
{ path: 'headerbutton', component: GridHeaderButtonComponent },
Expand Down
3 changes: 3 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
<li routerLinkActive="active">
<a [routerLink]="['/rowdetail']">21- Row Detail View</a>
</li>
<li routerLinkActive="active">
<a [routerLink]="['/editor-angular']">22- Editors Angular Components</a>
</li>
</ul>
</div>
</section>
Expand Down
7 changes: 7 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import { FormsModule } from '@angular/forms';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { Injector, APP_INITIALIZER, NgModule } from '@angular/core';
import { LOCATION_INITIALIZED } from '@angular/common';
import { NgSelectModule } from '@ng-select/ng-select';
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

import { AppComponent } from './app.component';
import { EditorNgSelectComponent } from './examples/editor-ng-select.component';
import { GridAddItemComponent } from './examples/grid-additem.component';
import { GridBasicComponent } from './examples/grid-basic.component';
import { GridClientSideComponent } from './examples/grid-clientside.component';
import { GridColspanComponent } from './examples/grid-colspan.component';
import { GridDraggableGroupingComponent } from './examples/grid-draggrouping.component';
import { GridEditorComponent } from './examples/grid-editor.component';
import { GridEditorAngularComponent } from './examples/grid-editor-angular.component';
import { GridFormatterComponent } from './examples/grid-formatter.component';
import { GridFrozenComponent } from './examples/grid-frozen.component';
import { GridGraphqlComponent } from './examples/grid-graphql.component';
Expand Down Expand Up @@ -68,12 +71,14 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
@NgModule({
declarations: [
AppComponent,
EditorNgSelectComponent,
GridAddItemComponent,
GridBasicComponent,
GridClientSideComponent,
GridColspanComponent,
GridDraggableGroupingComponent,
GridEditorComponent,
GridEditorAngularComponent,
GridFormatterComponent,
GridFrozenComponent,
GridGraphqlComponent,
Expand All @@ -100,6 +105,7 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
BrowserModule,
FormsModule,
HttpClientModule,
NgSelectModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
Expand All @@ -119,6 +125,7 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
],
entryComponents: [
// dynamically created components
EditorNgSelectComponent,
RowDetailPreloadComponent,
RowDetailViewComponent,
],
Expand Down
157 changes: 157 additions & 0 deletions src/app/examples/custom-angularComponentEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { ComponentRef } from '@angular/core';
import {
AngularUtilService,
Column,
Editor,
EditorValidator,
EditorValidatorOutput,
} from './../modules/angular-slickgrid';

/*
* An example of a 'detached' editor.
* KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
*/
export class CustomAngularComponentEditor implements Editor {
/** Angular Component Reference */
componentRef: ComponentRef<any>;

/** default item Id */
defaultId: string;

/** default item object */
defaultItem: any;

constructor(private args: any) {
this.init();
}

/** Angular Util Service */
get angularUtilService(): AngularUtilService {
return this.columnDef && this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.params.angularUtilService;
}

/** Get the Collection */
get collection(): any[] {
return this.columnDef && this.columnDef && this.columnDef.internalColumnEditor.collection || [];
}

/** Get Column Definition object */
get columnDef(): Column {
return this.args && this.args.column || {};
}

/** Get Column Editor object */
get columnEditor(): any {
return this.columnDef && this.columnDef.internalColumnEditor || {};
}

get hasAutoCommitEdit() {
return this.args.grid.getOptions().autoCommitEdit;
}

/** Get the Validator function, can be passed in Editor property or Column Definition */
get validator(): EditorValidator {
return this.columnEditor.validator || this.columnDef.validator;
}

init() {
if (!this.columnEditor || !this.columnEditor.params.component) {
throw new Error(`[Angular-Slickgrid] For the Editors.angularComponent to work properly, you need to provide your component to the "component" property and make sure to add it to your "entryComponents" array.
Example: this.columnDefs = [{ id: 'title', field: 'title', editor: { component: MyComponent, model: Editors.angularComponent, collection: [...] },`);
}
if (this.columnEditor && this.columnEditor.params.component) {
this.componentRef = this.columnEditor.params.angularUtilService.createAngularComponentAppendToDom(this.columnEditor.params.component, this.args.container);
Object.assign(this.componentRef.instance, { collection: this.collection });

this.componentRef.instance.onModelChanged.subscribe((item) => {
this.save();
});
}
}

save() {
const validation = this.validate();
if (validation && validation.valid) {
if (this.hasAutoCommitEdit) {
this.args.grid.getEditorLock().commitCurrentEdit();
} else {
this.args.commitChanges();
}
}
}

cancel() {
this.componentRef.instance.selectedId = this.defaultId;
this.componentRef.instance.selectedItem = this.defaultItem;
if (this.args && this.args.cancelChanges) {
this.args.cancelChanges();
}
}

hide() {
// optional, implement a hide method on your Angular Component
if (this.componentRef && this.componentRef.instance && typeof this.componentRef.instance.hide === 'function') {
this.componentRef.instance.hide();
}
}

show() {
// optional, implement a show method on your Angular Component
if (this.componentRef && this.componentRef.instance && typeof this.componentRef.instance.show === 'function') {
this.componentRef.instance.show();
}
}

destroy() {
// destroy the Angular Component
if (this.componentRef && this.componentRef.destroy) {
this.componentRef.destroy();
}
}

focus() {
// optional, implement a focus method on your Angular Component
if (this.componentRef && this.componentRef.instance && typeof this.componentRef.instance.focus === 'function') {
this.componentRef.instance.focus();
}
}

applyValue(item: any, state: any) {
item[this.columnDef.field] = state;
}

getValue() {
return this.componentRef.instance.selectedId;
}

loadValue(item: any) {
const itemObject = item && item[this.columnDef.field];
this.componentRef.instance.selectedId = itemObject && itemObject.id || '';
this.componentRef.instance.selectedItem = itemObject && itemObject;
}

serializeValue(): any {
return this.componentRef.instance.selectedItem;
}

isValueChanged() {
return (!(this.componentRef.instance.selectedId === '' && this.defaultId == null)) && (this.componentRef.instance.selectedId !== this.defaultId);
}

validate(): EditorValidatorOutput {
if (this.validator) {
const value = this.componentRef.instance.selectedId;
const validationResults = this.validator(value, this.args);
if (!validationResults.valid) {
return validationResults;
}
}

// by default the editor is always valid
// if user want it to be required, he would have to provide his own validator
return {
valid: true,
msg: null
};
}
}
34 changes: 34 additions & 0 deletions src/app/examples/editor-ng-select.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Component } from '@angular/core';
import { Subject } from 'rxjs';

@Component({
template: `
<ng-select class="no-style-select"
[items]="collection"
autofocus
bindValue="id"
bindLabel="name"
[clearable]="false"
(change)="onChange($event)"
[(ngModel)]="selectedId"
>
<ng-template ng-label-tmp ng-option-tmp let-item="item">
{{ item?.name }}
</ng-template>
</ng-select>`
})
export class EditorNgSelectComponent {
selectedId: string;
selectedItem: any;
collection; // this will be filled by the collection of your column definition
onModelChanged = new Subject<any>(); // object

onChange(item: any) {
this.selectedItem = item;
this.onModelChanged.next(item);
}

focus() {
// do a focus
}
}
49 changes: 49 additions & 0 deletions src/app/examples/grid-editor-angular.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<div class="container">
<h2>{{title}}</h2>
<div class="subtitle" [innerHTML]="subTitle"></div>
<br>

<div class="col-sm-6">
<label>autoEdit setting</label>
<span id="radioAutoEdit">
<label class="radio-inline control-label" for="radioTrue">
<input type="radio" name="inlineRadioOptions" id="radioTrue" checked [value]="isAutoEdit" (change)="setAutoEdit(true)"> ON (single-click)
</label>
<label class="radio-inline control-label" for="radioFalse">
<input type="radio" name="inlineRadioOptions" id="radioFalse" [value]="isAutoEdit" (change)="setAutoEdit(false)"> OFF (double-click)
</label>
</span>
<div class="row col-sm-12">
<span>
<button class="btn btn-default btn-sm" (click)="undo()">
<i class="fa fa-undo"></i>
Undo last edit(s)
</button>
<label class="checkbox-inline control-label" for="autoCommitEdit">
<input type="checkbox" id="autoCommitEdit" [value]="gridOptions.autoCommitEdit" (click)="changeAutoCommit()">
Auto Commit Edit
</label>
</span>
</div>
</div>


<div class="col-sm-6">
<div class="alert alert-info" *ngIf="updatedObject">
<strong>Updated Item:</strong> {{updatedObject | json}}
</div>
<div class="alert alert-warning" *ngIf="alertWarning">
<strong>Updated Item:</strong> {{alertWarning}}
</div>
</div>

<div class="col-sm-12">
<angular-slickgrid gridId="grid2"
(onAngularGridCreated)="angularGridReady($event)"
(sgOnCellChange)="onCellChanged($event.detail.eventData, $event.detail.args)"
(sgOnClick)="onCellClicked($event.detail.eventData, $event.detail.args)"
(sgOnValidationError)="onCellValidation($event.detail.eventData, $event.detail.args)"
[columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset">
</angular-slickgrid>
</div>
</div>
Loading