Base solution for your next web application
Open Closed

Editable Grid (Turbo Table) #6133


User avatar
0
mardianto created

Hi Support,

I need an example on how to achieved editable table in ASPNETZERO turbo table. I try to read the primeNG turbo table but still confuse on some part.

I've manage to achieve the editable table but somehow the data was not pass back to the object

i'm using aspnetzero angular spa version

Many Thanks for the help


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @mardianto

    Could you share your typescript and html code ?

  • User Avatar
    0
    mardianto created

    Hi @ismcagdas ,

    i've managed to do it with this line of code below

    at html :

    <div [@routerTransition]>
        <div class="m-subheader ">
            <div class="d-flex align-items-center">
                <div class="mr-auto col-md-6">
                    <h3 class="m-subheader__title m-subheader__title--separator">
                        <span>{{l("Document Numbers")}}</span>
                    </h3>
                    <button class="btn btn-success m-btn m-btn--icon m-btn--icon-only" (click)="addNew()">
                        <i class="fa fa-plus"></i>
                    </button>
                    <button type="button" class="btn btn-info m-btn m-btn--icon m-btn--icon-only" (click)="saveGrid()">
                        <i class="fa fa-edit"></i>
                    </button>
                    <button class="btn btn-danger m-btn m-btn--icon m-btn--icon-only" *ngIf="canDeleteDoc && 
                    isDocSelected">
                        <i class="fa fa-trash"></i>
                    </button>
                </div>
            </div>
        </div>
        <div class="m-content">
            <div class="m-portlet m-portlet--mobile">
                <div class="m-portlet__body">
                    <form class="horizontal-form" autocomplete="off">
                        <div class="m-form m-form--label-align-right">
                            <div class="row align-items-center m--margin-bottom-10">
                                <div class="col-xl-12">
                                    <div class="form-group m-form__group align-items-center">
                                        <div class="input-group">
                                            <input name="filterText" autoFocus class="form-control m-input" 
                                            [placeholder]="l('SearchWithThreeDot')"
                                                type="text">
                                            <span class="input-group-btn">
                                                <button class="btn btn-primary" type="submit"><i class="flaticon-search-1"></i>
                                                </button>
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </form>
                    <!-- isDataChanged : {{ isDataChanged }} -->
                    <div class="row align-items-center">
                        <!--<Primeng-Datatable-Start>-->
                        <!-- selectionMode="single"
                        (onRowSelect)="onRowSelectDoc($event)"
                        (onRowUnselect)="onRowUnselectDoc($event)"  -->
                        <div class="primeng-datatable-container" [busyIf]="primengTableHelper.isLoading">
                            <p-table #dataTable
                                (onLazyLoad)="getDocumentNumbers($event)" 
                                [value]="primengTableHelper.records"
                                rows="{{primengTableHelper.defaultRecordsCountPerPage}}" 
                                [paginator]="false"
                                [lazy]="true"
                                [scrollable]="true"
                                ScrollWidth="100%"
                                [responsive]="primengTableHelper.isResponsive"
                                [resizableColumns]="primengTableHelper.resizableColumns"
                                (onEditComplete)="onEditComplete($event)">
                                <ng-template pTemplate="header">
                                    <tr>
                                        <th pSortableColumn="rowData.documentNumber.type">Type</th>
                                        <th>Prefix</th>
                                        <th>Separator</th>
                                        <th>Digit</th>
                                        <th>Separator</th>
                                        <th>Suffix</th>
                                        <th>Last Number</th>
                                    </tr>
                                </ng-template>
                                <ng-template pTemplate="body" let-rowData>
                                    <tr>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <select id="DocType" name="DocType" class="form-control" 
                                                        [(ngModel)]="rowData.documentNumber.type"
                                                        (ngModelChange)="docTypeChanged($event)">
                                                        <option *ngFor="let t of docTypeCmb" [value]="t.value">{{t.displayText}}</option>
                                                    </select>
                                                    <!-- <input pInputText type="text" [(ngModel)]="rowData.documentNumber.type"> -->
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.type}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <input pInputText type="text" [(ngModel)]="rowData.documentNumber.prefix">
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.prefix}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <input pInputText type="text" [(ngModel)]="rowData.documentNumber.separator1">
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.separator1}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <input pInputText type="text" [(ngModel)]="rowData.documentNumber.digit"
                                                        required>
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.digit}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <input pInputText type="text" [(ngModel)]="rowData.documentNumber.separator2">
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.separator2}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <input pInputText type="text" [(ngModel)]="rowData.documentNumber.suffix">
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.suffix}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                        <td pEditableColumn>
                                            <p-cellEditor>
                                                <ng-template pTemplate="input">
                                                    <input pInputText type="text" 
                                                    [(ngModel)]="rowData.documentNumber.lastNumbering">
                                                </ng-template>
                                                <ng-template pTemplate="output">
                                                    {{rowData.documentNumber.lastNumbering}}
                                                </ng-template>
                                            </p-cellEditor>
                                        </td>
                                    </tr>
                                </ng-template>
                            </p-table>
                            <div class="primeng-no-data" *ngIf="primengTableHelper.totalRecordsCount == 0">
                                {{l('NoData')}}
                            </div>
                            <div class="primeng-paging-container">
                                <p-paginator 
                                    rows="{{primengTableHelper.defaultRecordsCountPerPage}}" 
                                    #paginator
                                    [totalRecords]="primengTableHelper.totalRecordsCount"
                                    [rowsPerPageOptions]="primengTableHelper.predefinedRecordsCountPerPage">
                                </p-paginator>
                                <span class="total-records-count">
                                    {{l('TotalRecordsCount', primengTableHelper.totalRecordsCount)}}
                                </span>
                            </div>
                        </div>
                        <!--<Primeng-Datatable-End>-->
                    </div>
                </div>
            </div>
        </div>
        <pre>{{ primengTableHelper.records | json }}</pre>
    </div>
    

    at typescript

    import { AppComponentBase } from '@shared/common/app-component-base';
    import { OnInit, Component, ViewEncapsulation, Injector, ViewChild } from '@angular/core';
    import { appModuleAnimation } from '@shared/animations/routerTransition';
    import { Table } from 'primeng/table';
    import { Paginator, LazyLoadEvent } from 'primeng/primeng';
    import { DocumentNumbersServiceProxy, GetDocumentNumberForView, CreateOrEditDocumentNumberDto, ComboboxItemDto } from '@shared/service-proxies/service-proxies';
    import { CreateOrEditDocumentNumberModalComponent } from './create-or-edit-documentNumber-modal.component';
    import { EnumDocumentType } from '@shared/AppEnums';
    
    @Component({
        templateUrl: './document-numbers.component.html',
        encapsulation: ViewEncapsulation.None,
        animations: [appModuleAnimation()]
    })
    export class DocumentNumbersComponent extends AppComponentBase implements OnInit {
        @ViewChild('createOrEditDocumentNumberModal') createOrEditDocumentNumberModal: CreateOrEditDocumentNumberModalComponent;
        @ViewChild('dataTable') dataTable: Table;
        @ViewChild('paginator') paginator: Paginator;
    
        //filter
        uiDocumentType = '';
    
        //row object
        docIdKey: number;
        isDataChanged = false;
    
        //permissions
        canCreateDoc = this.isGranted('Pages.Configuration.DocumentNumbers.Create');
        canEditDoc = this.isGranted('Pages.Configuration.DocumentNumbers.Edit');
        canDeleteDoc = this.isGranted('Pages.Configuration.DocumentNumbers.Delete');
    
        docTypeCmb: ComboboxItemDto[] = [];
    
        constructor(
            injector: Injector,
            private _documentNumbersServiceProxy: DocumentNumbersServiceProxy
         ) {
            super(injector);
        }
    
        ngOnInit(): void {
            this._documentNumbersServiceProxy.getDocumentTypeForCombobox().subscribe(e => {
                this.docTypeCmb = e.items;
            });
        }
    
        getDocumentNumbers(event?: LazyLoadEvent): void {
            // if (this.primengTableHelper.shouldResetPaging(event)) {
            //     this.paginator.changePage(0);
            //     return;
            // }
    
            this.primengTableHelper.showLoadingIndicator();
            this._documentNumbersServiceProxy.getAll(
                this.uiDocumentType,
                this.primengTableHelper.getSorting(this.dataTable),
                this.primengTableHelper.getSkipCount(this.paginator, event),
                this.primengTableHelper.getMaxResultCount(this.paginator, event)
            ).subscribe(result => {
                this.primengTableHelper.totalRecordsCount = result.totalCount;
                this.primengTableHelper.records = result.items;
                this.primengTableHelper.hideLoadingIndicator();
            });
        }
    
        docTypeChanged(event) {
            console.log(event);
        }
    
        saveGrid() {
            this.isDataChanged = false;
            for (let doc of this.primengTableHelper.records) {
               console.log(doc);
               let dataSave = new CreateOrEditDocumentNumberDto();
               dataSave.id = doc.documentNumber.id;
               dataSave.type = doc.documentNumber.type.valueOf();
               dataSave.prefix = doc.documentNumber.prefix;
               dataSave.separator1 = doc.documentNumber.separator1;
               dataSave.digit = doc.documentNumber.digit;
               dataSave.separator2 = doc.documentNumber.separator2;
               dataSave.suffix = doc.documentNumber.suffix;
               dataSave.lastNumbering = doc.documentNumber.lastNumbering;
    
               this._documentNumbersServiceProxy.createOrEdit(dataSave).subscribe(() => {
                    this.notify.info(this.l('SavedSuccessfully'));
               });
            }
    
            this.getDocumentNumbers();
        }
    
        reloadPage(): void {
            this.paginator.changePage(this.paginator.getPage());
        }
    
        onEditComplete(event) {
            console.log(event);
            this.isDataChanged = true;
        }
    
        addNew() {
            if (this.isDataChanged) {
                this.message.warn(this.l('Edit mode is active'));
                return;
            } else {
                this.primengTableHelper.records = [...this.primengTableHelper.records];
                let newData = new GetDocumentNumberForView();
                newData.documentNumber.type = 1;
                newData.documentNumber.prefix = '';
                newData.documentNumber.separator1 = '';
                newData.documentNumber.digit = 0;
                newData.documentNumber.separator2 = '';
                newData.documentNumber.suffix = '';
                newData.documentNumber.lastNumbering = 0;
    
                console.log(newData);
                this.primengTableHelper.records.push(newData);
            }
        }
    }
    

    this the the result

    But now i have another problem, how to inject / insert new row in turbo table ? function addNew() always produce this error :

    and other thing is, i want to implements canDeactivate to prevent user leaving page when in edit mode. I try to follow some of tutorial in the net, Angular how keep user from lost his data Angular prevent route change and now still not able to implement canDeactivate correctly, i'm still learning angular so that stuff give me a headached.

    Maybe you can give me some guideline on how to implement prevent user leaving when in edit mode in aspnetzero

    Many Thanks for the help, i'm really appriciate your effort

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @mardianto

    Have you fixed your problem ?