npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sdk-datagrid

v2.2.9

Published

Customizable (Angular) datagrid with data options for manipulation, and charts for visualization.

Downloads

262

Readme

Description:

The sdk-datagrid component is a mobile-friendly, fully-functional data grid that gives the developer complete control over the processing and appearance of the data. From a simple table to a complex, customizable (Excel-like) spreadsheet, this component adds so much power to any application.

NOTE: This package leverages the sdk-core-library for core configurations (i.e., colors, icons, etc.).

INSTALLATION:

Using NPM:

npm install --save sdk-datagrid

CONFIGURATION:

To configure the sdk-datagrid for your application, add the following lines to your app.module.ts file:

import { SDKDatagridModule } from 'sdk-datagrid';

@NgModule({
    imports: [
        SDKDatagridModule
    ]
})
export class AppModule { }

PROPERTIES:

/**************************************************************************
* Input/Output Parameters for updating the Grid
**************************************************************************/
@Input() updateGrid: boolean = false; // Applies changes/data to the grid.
@Output() updateGridChange = new EventEmitter<boolean>(); // Callback to set updateGrid variable.

/**************************************************************************
* Input/Output Parameters for editing a record
**************************************************************************/
@Input() editRecordIndex: number | null | undefined; // The record that is currently being edited.
@Output() editRecordIndexChange = new EventEmitter<number | null | undefined>(); // Callback to set editRecordIndex variable.

/**************************************************************************
* Input/Output Parameters for dataset change
**************************************************************************/
@Input() datasets: string[] = []; // List of datasets.
@Input() activeDataset: string = ""; // The current selected dataset.
@Output() activeDatasetChange = new EventEmitter<string>(); // Callback to set activeDataset variable.

/**************************************************************************
* Input/Output Parameters for updating columns
**************************************************************************/
@Input() columns: SDKDataGridColumn[] = []; // The columns to be used for the grid.
@Input() columnHeaderStyle: string = ""; // Style used for column headers.
@Output() columnsChange = new EventEmitter<SDKDataGridColumn[]>(); // Callback to set columns variable.

/**************************************************************************
* Input/Output Parameters for updating custom filters
**************************************************************************/
@Input() customFilters: SDKDataGridCustomFilter[] = []; // Custom filters added to standard filter provided in loaddata callback (filters).
@Output() customFiltersChange = new EventEmitter<SDKDataGridCustomFilter[]>(); // Callback to set custom filters variable.

/**************************************************************************
* Input/Output Parameters for exporting data
**************************************************************************/
@Input() dataExport: any = ""; // The data to export.
@Output() dataExportChange = new EventEmitter<any>(); // Callback to set dataExport variable.

/**************************************************************************
* Input/Output Parameters for settings data
**************************************************************************/
@Input() settings: SDKDataGridSettings[] = []; // Options that are saved outside the grid. This value should be set to the value retieved from the datagrid @Output method "settingsSavedEvent". Consider it a passthrough value.
@Input() clearSettingsCache: boolean = false; // Clears any grid storage of settings.
@Output() savedSettingsEvent: EventEmitter<SDKDataGridSettings[]> = new EventEmitter(); // Used as a callback to save settings.
@Output() clearSettingsCacheChange = new EventEmitter<boolean>(); // Callback to set clearSettingsCache variable.

/**************************************************************************
* Required Output Parameters
**************************************************************************/
@Output() loadDataEvent = new EventEmitter<any>(); // Callback with grid changes.

/**************************************************************************
* Optional Input/Output Parameters
**************************************************************************/
@Input() name: string = ""; // Unique name of the grid (per page).
@Input() title: string = ""; // Title of the grid.
@Input() titleStyle: string = ""; // Style used for title.
@Input() options: SDKDataGridOptions | undefined; // Grid options.
@Input() fontFamily: string = ""; // font-family used for grid.
@Input() data: any = ""; // The data to display in the grid.
@Input() rowValues: number[] = [10, 25, 50, 100, 500, 1000]; // Sets the values used for records per page.
@Input() defaultRows: number = 100; // Default value for records per page.
@Input() rows: number | undefined; // Current rows in dataset.
@Input() page: number | undefined; // Current page of dataset.
@Input() total: number | undefined; // Total records in dataset.

@Output() saveGridDataEvent: EventEmitter<any> = new EventEmitter(); // Callback for saving changes to data.
@Output() deleteGridDataEvent: EventEmitter<any> = new EventEmitter(); // Callback for saving changes to data.
@Output() selectedRowActionEvent: EventEmitter<any> = new EventEmitter(); // // Callback for row actions. NOTE: The return object is { record: [the record], index: [the record index] }

/**************************************************************************
* Processing Parameters
**************************************************************************/
@Input() error: string = ""; // Any errors that occur during processing.
@Input() isDebug: boolean = false; // Turns on debugging.

USAGE:

Basic Setup

<sdk-datagrid
    [(updateGrid)]="updateGrid"
    [(columns)]="columns"
    [data]="data"
    [rows]="rows"
    [page]="page"
    [total]="total"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

.ts file

public updateGrid: boolean = false; // Required 2-way binding.
public columns: SDKDataGridColumn[] = []; // Required 2-way binding.
public data: any;
public rows: number | undefined;
public page: number | undefined;
public total: number | undefined;
public error: string = "";

// Callback function for loading data (required).
public async loadData(event: any = null) {
    this.isLoading = true;

    let body: string = this.buildBody(event);

    try {
        await this.httpService.Post(dataSource, body).then((data: any) => {
            if (data) {
                this.data = data["Data"];
                this.rows = parseInt(data["Rows"]);
                this.page = parseInt(data["Page"]);
                this.total = parseInt(data["Total"]);
                this.error = data["Error"];

                setTimeout(() => {
                    this.updateGrid = true; // Tell the grid to update.
                }, 100);
            }
        });
    } catch (error: any) {
        this.error = error.message;
    }

    this.isLoading = false;
}

// Change the body parameters to fit your API call.
private buildBody(event: any = null): string {
    let sorts: any = [];
    let filters: any = [];
    let formulas: any = [];

    this.column.forEach((column: SDKDataGridColumn) => {
        if (column.Sort) {
            sorts.push({ ColumnName: column.Name, Direction: column.Sort.direction, Position: column.Sort.position });
        }

        if (column.Filter) {
            let filtersOperation = Object.keys(Filters)[Object.values(Filters).indexOf(column.Filter.operation.toString())];

            filters.push({ ColumnName: column.Name, Operation: filtersOperation, Value: column.Filter.value });
        }

        if (column.Formulas) {
            let formulaOperation = Object.keys(FormulaOperation)[Object.values(FormulaOperation).indexOf(column.Formulas.operation.toString())];

            formulas.push({ ColumnName: column.Name, Operation: formulaOperation, Format: column.Formulas.format });
        }
    });

    let parameters: any = {
        rows: event.rows,
        page: event.page,
        sorts: sorts,
        filters: filters,
        formulas: formulas
    };

    return JSON.stringify(parameters);
}

Columns

If you want to specify the columns, define them using the SDKDataGridColumn object.

.ts file

@ViewChild('category') category!: TemplateRef<any>;
@ViewChild('dataTemplate') dataTemplate!: TemplateRef<any>;
@ViewChild('actionRight') actionRight!: TemplateRef<any>;

public updateGrid: boolean = false;
public editRecordIndex: number | null | undefined = null;
public columns: SDKDataGridColumn[] = [
    { Name: 'category', DisplayName: 'Category', required: true, style: 'color: red', notes: 'MUST be a valid Category.', editTemplate: () => this.category },
    { Name: 'air_date', DisplayName: 'Date', required: true, validCharacters: 'calendar', pattern: 'YYYY-MM-DD' },
    { Name: 'question', DisplayName: 'Question', height: '50px', width: '100px', dataTemplate: () => this.dataTemplate },
    { Name: 'value', DisplayName: 'Value', required: true, notes: 'Between 100 - 1000.', validCharacters: 'numeric' },
    { Name: 'answer', DisplayName: 'Answer', dataTemplate: () => this.dataTemplate },
    { Name: 'round', DisplayName: 'Round' },
    { Name: 'show_number', DisplayName: 'Show', validCharacters: 'custom', pattern: '^[0-9]{4}$' },
    { Name: 'fin', DisplayName: 'Completed' },
    { Name: 'Edit', DisplayName: 'Edit', dataTemplate: () => this.actionRight }
];
public data: any;
public rows: number | undefined;
public page: number | undefined;
public total: number | undefined;
public error: string = "";

// If editing is enabled...
public editData(index: any) {
    this.editRecordIndex = index;
}

public saveData(index: number, record: any) {
    // Update the record as a whole.
    let dataIndex = ((this.page ?? 1) - 1) * (this.rows ?? 0) + index;

    this.data[dataIndex] = { ...record };

    // Update each column in the record.
    for (let key in this.data[dataIndex]) {
        if (Object.prototype.hasOwnProperty.call(activeRow, key)) {
            this.data[index][key] = record[key];
        }
    }

    // Save to database and show message.
}

public cancelData() {
    this.editRecordIndex = null;
}

.html file

<sdk-datagrid
    [(updateGrid)]="updateGrid"
    [(columns)]="columns"
    [(editRecordIndex)]="editRecordIndex"
    [data]="data"
    [rows]="rows"
    [page]="page"
    [total]="total"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

<ng-template #category let-index="index" let-record="record">
    <div>
        <select style="margin-left: 10px;">
            <option value="">...</option>
            <option value="HISTORY">HISTORY</option>
            <option value="3-LETTER WORDS">3-LETTER WORDS</option>
            <option value="THE COMPANY LINE">THE COMPANY LINE</option>
            <option value="EPITAPHS & TRIBUTES">EPITAPHS & TRIBUTES</option>
            <option value="ESPN's TOP 10 ALL-TIME ATHLETES">ESPN's TOP 10 ALL-TIME ATHLETES</option>
        </select>
    </div>
</ng-template>

<ng-template #dataTemplate let-value="value">
    <div>{{ value }}</div>
</ng-template>

<ng-template #actionRight let-index="index" let-record="record" let-column="column" let-value="value">
    <div *ngIf="index !== editRecordIndex">
        <div title="Edit" class="icon cursor" (click)="editData(index)">edit</div>
        <div title="Delete" class="icon cursor delete">delete</div>
    </div>
    <div *ngIf="index === editRecordIndex">
        <div title="Save" class="icon cursor done" (click)="saveData(index, record)">done</div>
        <div title="Cancel" class="icon cursor delete" (click)="cancelData()">close</div>
    </div>
</ng-template>

Custom Options

If you want to add a custom option to the sdk-datagrid, use the optionAddons/windowAddons parameters. First, create your "custom" option and window components.

mycustom-option.component

.html file

<div (click)="showDataOptions('myCustom')">
    <div title="My Custom Option" class="sdk-icon" [ngClass]="optionTitle === 'myCustom' ? 'active' : ''">file_download</div>
    <div *ngIf="myCustomBadge !== ''" class="badge">
        <div class="label">{{ myCustomBadge }}</div>
    </div>
</div>

.ts file

import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
    selector: 'mycustom-option',
    templateUrl: './mycustom-option.component.html',
    styleUrls: ['./mycustom-option.component.scss']
})
export class MyCustomOptionComponent {
    @Input() optionTitle: string = ""; // Unique name for option.
    @Output() showDataOptionsEvent = new EventEmitter<any>(); // Method to show option window.

    public myCustomBadge: string = ""; // Used to add badge to custom option.

    public showDataOptions(type: string) {
        this.showDataOptionsEvent.emit(type);
    }
}

mycustom-window.component

.html file

<div *ngIf="dataClass === 'expand' && optionTitle === 'mycustom'" class="sdk-datagrid-window">
    <div class="header">
        <span class="title">My Custom Option</span>
        <span title="Close" class="sdk-icon close" (click)="close()">close</span>
    </div>
    <div class="actions">
        // Add your custom actions here (if applicable).
    </div>
    <div class="content">
        // Add your custom option functionality here.
    </div>
    <div class="footer">
        <button class="button" type="button" (click)="apply()">Apply</button>
    </div>
</div>

.ts file

import { Component, EventEmitter, Input, Output } from '@angular/core';

import { SDKDataGridColumn } from 'sdk-datagrid';

@Component({
    selector: 'mycustom-window',
    templateUrl: './mycustom-window.component.html',
    styleUrls: ['./mycustom-window.component.scss']
})
export class MyCustomWindowComponent {
    @Input() dataClass: string = ""; // Used to indicate if window is open/closed.
    @Input() optionTitle: string = ""; // Unique name for option.
    @Input() datasets: any[] = []; // Data array.
    @Input() columns: SDKDataGridColumn[] = []; // Columns defines for data.
    @Input() filters: any[] = []; // Filters defines for data.
    @Input() sorts: any[] = []; // Sorting defines for data.

    @Output() applyEvent = new EventEmitter<any>(); // Apply option.
    @Output() closeEvent = new EventEmitter<any>(); // Close window.

    public close() {
        this.closeEvent.emit();
    }

    public async apply() {
        this.applyEvent.emit();
        this.closeEvent.emit();
    }
}

Then add those components to your datagrid.

.ts file

import { MyCustomOptionComponent } from './mycustom/option/mycustom-option.component';
import { MyCustomWindowComponent } from './mycustom/window/mycustom-window.component';

public myCustomOptionComponent = MyCustomOptionComponent;
public myCustomWindowComponent = MyCustomWindowComponent;

.html file

<sdk-datagrid
    [(updateGrid)]="updateGrid"
    [(columns)]="columns"
    [data]="data"
    [rows]="rows"
    [page]="page"
    [total]="total"
    [optionAddons]="[myCustomOptionComponent]"
    [windowAddons]="[myCustomWindowComponent]"
    [error]="error"
    (loadDataEvent)="loadData($event)">
</sdk-datagrid>

NOTES:

  • In order to update the grid, you MUST set the updateGrid property to true. The grid will automatically set it back to false once the update is complete (hence the 2-way binding).

  • To customize filtering for a column:

    Define the FilterTypes and FilterValues in the columns object.

    public columns: SDKDataGridColumn[] = [
        { Name: 'category', DisplayName: 'Category', required: true, style: 'color: red', notes: 'MUST be a valid Category.', editTemplate: () => this.category },
        { Name: 'air_date', DisplayName: 'Date', required: true, validCharacters: 'calendar', pattern: 'YYYY-MM-DD' },
        { Name: 'question', DisplayName: 'Question', height: '50px', width: '100px', dataTemplate: () => this.dataTemplate },
        { Name: 'value', DisplayName: 'Value', required: true, notes: 'Between 100 - 1000.', validCharacters: 'numeric' },
        { Name: 'answer', DisplayName: 'Answer', dataTemplate: () => this.dataTemplate },
        { Name: 'round', DisplayName: 'Round', FilterTypes: [ Filters.Equals ], FilterValues: [ 'Jeopardy!', 'Double Jeopardy!' ] },
        { Name: 'show_number', DisplayName: 'Show', FilterTypes: [ Filters.LessThanOrEqual, Filters.GreaterThanOrEqual ], FilterValues: [ 4000, 4500, 5000 ], validCharacters: 'custom', pattern: '^[0-9]{4}$' },
        { Name: 'fin', DisplayName: 'Completed', FilterTypes: [ Filters.Equals ], FilterValues: [ true, false ] },
        { Name: 'Edit', DisplayName: 'Edit', actionSide: "right", dataTemplate: () => this.actionRight }
    ];

    To use a multi-select dropdown as your filter, define the FilterMultiSelect and FilterValues in the columns object.

    public columns: SDKDataGridColumn[] = [
    	{ Name: 'category', DisplayName: 'Category', required: true, style: 'color: red', notes: 'MUST be a valid Category.', editTemplate: () => this.category },
    	{ Name: 'air_date', DisplayName: 'Date', required: true, validCharacters: 'calendar', pattern: 'YYYY-MM-DD' },
    	{ Name: 'question', DisplayName: 'Question', isVisible: false, height: '50px', width: '100px', dataTemplate: () => this.dataTemplate },
    	{ Name: 'value', DisplayName: 'Value', required: true, notes: 'Between 100 - 1000.', validCharacters: 'numeric' },
    	{ Name: 'answer', DisplayName: 'Answer', showSort: false, showFilter: false, dataTemplate: () => this.dataTemplate },
    	{ Name: 'round', DisplayName: 'Round', FilterMultiSelect: true, FilterValues: [ 'Jeopardy!', 'Double Jeopardy!', 'Final Jeopardy!', 'Tiebreaker' ] },
    	{ Name: 'show_number', DisplayName: 'Show', FilterTypes: [ Filters.GreaterThanOrEqual, Filters.LessThanOrEqual ], FilterValues: [ 4000, 4500, 5000, 6000 ] },
    	{ Name: 'fin', DisplayName: 'Completed', FilterTypes: [ Filters.Equals ], FilterValues: [ true, false ]},
    	{ Name: 'Edit', DisplayName: 'Edit', actionSide: "right", dataTemplate: () => this.actionRight }
    ];
  • To create custom filters (SDKDataGridCustomFilter), the following properties are available:

    public Name: string = ""; // Unique filter name.
    public DisplayName?: string = "";  // Name to display to user.
    public Type?: FilterType = FilterType.Textbox; // Type of filter (Textbox, TextboxOnly, Checkbox, Dropdown).
    public notes?: string = "";
    
    // START: sdk-select properties for Dropdown filters.
    public FilterMultiSelect?: boolean = false; // Allows multiple filter values to be selected.
    public FilterTypes?: any[] = []; // Allows you to define specific filter types. NOTE: If FilterMultiSelect = true, this property is forced to [Filters.Equals, Filters.NotEquals].
    public FilterValues?: any[] = []; // Allows you to define specific filter values.
    public Filter?: any = null; // Values set for filter.
    public setFilterValues?: () => Promise<any[]>; // Optional callback method to load filter values.
    // END: sdk-select properties for Dropdown filters.
    
    FilterType Enums:
    - Textbox
    - TextboxOnly
    - Checkbox
    - Dropdown

    NOTE: If Type = FilterType.Textbox and is used with FilterTypes, the custom filter will have an Operation/Value layout. If FilterTypes is NOT used, the layout will ONLY have a Value.

  • To use columns (SDKDataGridColumn), the following properties are available:

    public Name: string = ""; // Original db name.
    public DisplayName?: string = "";  // System override of db name (Name).
    public FriendlyName?: string = "";  // User provides. Produces * indicator.
    public Sort?: any = null; // Sorting (asc/desc) applied to column data.
    public Filter?: any = null; // Filters applied to column data.
    public Formulas?: any = null; // Formulas applied to column.
    
    public showSort?: boolean = true; // Allows you to turn on/off sorting capabilities.
    public showFilter?: boolean = true; // Allows you to turn on/off filtering capabilities.
    public showTooltip?: boolean = false;
    public isAction?: boolean = false; // Is the column associated to an action.
    public isVisible?: boolean = true; // Allows you to turn on/off the visibility of the column.
    
    public actionSide?: string = "right" // right or left
    
    // START: Filter properties
    public FilterMultiSelect?: boolean = false; // Allows multiple filter values to be selected.
    public FilterTypes?: any[] = []; // Allows you to define specific filter types. NOTE: If FilterMultiSelect = true, this property is forced to [Filters.Equals, Filters.NotEquals].
    public FilterValues?: any[] = []; // Allows you to define specific filter values.
    public FilterType?: FilterType = FilterType.Textbox; // Type of filter (Textbox, TextboxOnly, Checkbox, Dropdown).
    // END: Filter properties
    
    // START: editTemplate option
    public allowEdit?: boolean = true;
    public required?: boolean = false;
    public notes?: string = "";
    public validCharacters?: string = "";
    public hint?: string = "";
    public pattern?: string = "";
    public height?: string = "";
    public width?: string = "";
    public border?: string = "";
    public style?: string = "";
    // END: editTemplate option
    
    // Custom templates
    public headerTemplate?: () => TemplateRef<any>;
    public dataTemplate?: () => TemplateRef<any>;
    public editTemplate?: () => TemplateRef<any>;
    
    // Custom methods
    public formatData?: (value: any) => string; // Optional callback method to format the data.
    public setFilterValues?: () => Promise<any[]>; // Optional callback method to load filter values.
  • To use options (SDKDataGridOptions), the following properties are available:

    public header?: boolean = true;
    public footer?: boolean = true;
    public paging?: boolean = true;
    public options?: boolean = true;
    
    public datasetTabs?: boolean = false;
    
    public autoClosePanel?: boolean = true;
    public minimizeOptions?: boolean = false;
    
    public settings?: boolean = false;
    public columns?: boolean = true;
    public filters?: boolean = true;
    public sorts?: boolean = true;
    public formulas?: boolean = true;
    public charts?: boolean = false;
    public export?: boolean = true;
    public edit?: boolean = false;
    public delete?: boolean = true;
    public nowrap?: boolean = false;
    
    public settingsStorage?: StorageType = StorageType.Local;