Skip to content

Example for Angular formatters #465

Closed
grid-js/website
#255
@ubergeoff

Description

@ubergeoff

Proposal and/or example for future Angular GridJS custom formatter columns
Ability to add Custom Angular components as "formatter"

Please see my proposed solution/example

export class GridDemoComponent implements OnInit {
    columns: OneDArray<any> = [
        {
            name: 'CheckBox',
            sort: false,
            width: '5px',
            formatter: (cellData) => {
                return createDivContainer((div) => {
                    div.appendChild(this.createCheckBox(cellData).location.nativeElement);
                });
            }
        },
        'Name',
        'Email',
        'Phone Number',
        {
            name: 'Button',
            sort: false,
            width: '30px',
            formatter: (cellData) => {
                return createDivContainer((div) => {
                    div.appendChild(this.createButton(cellData).location.nativeElement);
                });
            }
        }
    ];

    data$: Observable<any[]>;
    private dataSubject = new BehaviorSubject<any[]>([]);

    constructor(
        private dialog: MatDialog,
        private componentFactory: ComponentFactoryResolver,
        private viewContainerRef: ViewContainerRef
    ) {}

    ngOnInit(): void {
        this.data$ = this.dataSubject.pipe(debounceTime(1000));

        this.dataSubject.next([
            [true, 'John', 'john@example.com', '(353) 01 222 3333', 22],
            [false, 'Mark', 'mark@gmail.com', '(01) 22 888 4444', 33]
        ]);
    }

    openModal(rowData) {
        this.dialog.open(DialogComponent, { data: rowData });
    }

    createComponent<T>(type: Type<T>): ComponentRef<T> {
        const componentFactory = this.componentFactory.resolveComponentFactory(type);
        return this.viewContainerRef.createComponent<T>(componentFactory);
    }

   // any custom Angular component
    createButton(cellData) {
        const button = this.createComponent<ActionButtonComponent>(ActionButtonComponent);
        button.instance.eventFunction = () => this.openModal(cellData);

        return button;
    }

    // Angular Material component
    createCheckBox(cellData) {
        const checkBox = this.createComponent<MatCheckbox>(MatCheckbox);
        checkBox.instance.checked = cellData;

        return checkBox;
    }
}

And the createDivContainer function:

import { h, createRef as gCreateRef } from 'gridjs';

export function createDivContainer(creatorFunction) {
    const ref = gCreateRef();
    const div = h('div', { ref: ref });
    setTimeout(() => {
        if (ref.current?.children.length === 0) {
            creatorFunction(ref.current);
        }
    }, 0);
    return div;
}

Would this be considered a good practice..?

Are there any further enhancement that can be applied to the above example..?

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions