7

I want to override the template of the DataTable component of primeng and this is how my code looks like:

my-datatable.component.ts

import { Component, OnInit, ElementRef, Renderer2, ChangeDetectorRef } from '@angular/core';
import { DataTable, DomHandler } from 'primeng/primeng';
import { ObjectUtils } from '../../../../node_modules/primeng/components/utils/ObjectUtils'
import { ColumnHeaders } from '../../../../node_modules/primeng/components/datatable/datatable'

@Component({
  selector: 'my-datatable',
  templateUrl: './my-datatable.component.html',
  styleUrls: ['./my-datatable.component.scss']    
})
export class MyDatatableComponent extends DataTable {

    constructor(el: ElementRef, domHandler: DomHandler, renderer: Renderer2, changeDetector: ChangeDetectorRef, objectUtils: ObjectUtils) { 
        super(el, domHandler, renderer, changeDetector, objectUtils);
        console.log('MyDatatableComponent');
    }

}

my-datatable.component.html, this file has the same template as of the base component. Idea was to first run and then make modifications

<div [ngStyle]="style" [class]="styleClass" [style.width]="containerWidth" [ngClass]="{'ui-datatable ui-widget':true,'ui-datatable-reflow':responsive,'ui-datatable-stacked':stacked,'ui-datatable-resizable':resizableColumns,'ui-datatable-scrollable':scrollable}">
  <div class="ui-datatable-loading ui-widget-overlay" *ngIf="loading"></div>
  <div class="ui-datatable-loading-content" *ngIf="loading">
    <i class="fa fa-circle-o-notch fa-spin fa-2x"></i>
  </div>
  <div class="ui-datatable-header ui-widget-header" *ngIf="header">
    <ng-content select="p-header"></ng-content>
  </div>
  <p-paginator [rows]="rows" [first]="first" [totalRecords]="totalRecords" [pageLinkSize]="pageLinks" styleClass="ui-paginator-bottom" (onPageChange)="paginate($event)" [rowsPerPageOptions]="rowsPerPageOptions" *ngIf="paginator && paginatorPosition!='bottom' || paginatorPosition =='both'"></p-paginator>
  <div class="ui-datatable-tablewrapper" *ngIf="!scrollable">
    <table [class]="tableStyleClass" [ngStyle]="tableStyle">
      <thead class="ui-datatable-thead">
        <tr *ngIf="!headerColumnGroup" class="ui-state-default" [pColumnHeaders]="columns"></tr>
        <ng-template [ngIf]="headerColumnGroup">
          <tr *ngFor="let headerRow of headerColumnGroup.rows" class="ui-state-default" [pColumnHeaders]="headerRow.columns"></tr>
        </ng-template>
      </thead>
      <tfoot *ngIf="hasFooter()" class="ui-datatable-tfoot">
        <tr *ngIf="!footerColumnGroup" class="ui-state-default" [pColumnFooters]="columns"></tr>
        <ng-template [ngIf]="footerColumnGroup">
          <tr *ngFor="let footerRow of footerColumnGroup.rows" class="ui-state-default" [pColumnFooters]="footerRow.columns"></tr>
        </ng-template>
      </tfoot>
      <tbody [ngClass]="{'ui-datatable-data ui-widget-content': true, 'ui-datatable-hoverable-rows': (rowHover||selectionMode)}" [pTableBody]="columns"></tbody>
    </table>
  </div>

  <ng-template [ngIf]="scrollable">
    <div class="ui-datatable-scrollable-wrapper ui-helper-clearfix" [ngClass]="{'max-height':scrollHeight}">
      <div *ngIf="frozenColumns" [pScrollableView]="frozenColumns" frozen="true" [ngStyle]="{'width':this.frozenWidth}" class="ui-datatable-scrollable-view ui-datatable-frozen-view"></div>
      <div [pScrollableView]="scrollableColumns" [ngStyle]="{'width':this.unfrozenWidth, 'left': this.frozenWidth}" class="ui-datatable-scrollable-view" [virtualScroll]="virtualScroll" (onVirtualScroll)="onVirtualScroll($event)" [ngClass]="{'ui-datatable-unfrozen-view': frozenColumns}"></div>
    </div>
  </ng-template>

  <p-paginator [rows]="rows" [first]="first" [totalRecords]="totalRecords" [pageLinkSize]="pageLinks" styleClass="ui-paginator-bottom" [alwaysShow]="alwaysShowPaginator" (onPageChange)="paginate($event)" [rowsPerPageOptions]="rowsPerPageOptions" *ngIf="paginator && paginatorPosition!='top' || paginatorPosition =='both'"></p-paginator>
  <div class="ui-datatable-footer ui-widget-header" *ngIf="footer">
    <ng-content select="p-footer"></ng-content>
  </div>

  <div class="ui-column-resizer-helper ui-state-highlight" style="display:none"></div>
  <span class="fa fa-arrow-down ui-datatable-reorder-indicator-up" style="position: absolute; display: none;"></span>
  <span class="fa fa-arrow-up ui-datatable-reorder-indicator-down" style="position: absolute; display: none;"></span>
</div>

Also I have added this new component in the declarations array in the app.module.ts file. So, I know that it is being included, which is the reason why I am getting a parse error.

The errors which I encounter in the console is:

Unhandled Promise rejection: Template parse errors:
Can't bind to 'pColumnHeaders' since it isn't a known property of 'tr'. ("ass="ui-datatable-thead">
                  <tr *ngIf="!headerColumnGroup" class="ui-state-default" [ERROR ->][pColumnHeaders]="columns"></tr>
                  <ng-template [ngIf]="headerColumnGroup">
         "): ng:///AppModule/CsxDatatableComponent.html@14:74
Can't bind to 'pColumnHeaders' since it isn't a known property of 'tr'. ("                      <tr *ngFor="let headerRow of headerColumnGroup.rows" class="ui-state-default" [ERROR ->][pColumnHeaders]="headerRow.columns"></tr>
                  </ng-template>
              </thead>
"): ng:///AppModule/CsxDatatableComponent.html@16:100
Can't bind to 'pColumnFooters' since it isn't a known property of 'tr'. ("ass="ui-datatable-tfoot">
                  <tr *ngIf="!footerColumnGroup" class="ui-state-default" [ERROR ->][pColumnFooters]="columns"></tr>
                  <ng-template [ngIf]="footerColumnGroup">
         "): ng:///AppModule/CsxDatatableComponent.html@20:74
Can't bind to 'pColumnFooters' since it isn't a known property of 'tr'. ("                      <tr *ngFor="let footerRow of footerColumnGroup.rows" class="ui-state-default" [ERROR ->][pColumnFooters]="footerRow.columns"></tr>
                  </ng-template>
              </tfoot>
"): ng:///AppModule/CsxDatatableComponent.html@22:100
Can't bind to 'pTableBody' since it isn't a known property of 'tbody'. ("datatable-data ui-widget-content': true, 'ui-datatable-hoverable-rows': (rowHover||selectionMode)}" [ERROR ->][pTableBody]="columns"></tbody>
          </table>
      </div>
"): ng:///AppModule/CsxDatatableComponent.html@25:137
Can't bind to 'pScrollableView' since it isn't a known property of 'div'. ("-helper-clearfix" [ngClass]="{'max-height':scrollHeight}">
              <div *ngIf="frozenColumns" [ERROR ->][pScrollableView]="frozenColumns" frozen="true" 
                  [ngStyle]="{'width':this.frozenWid"): ng:///AppModule/CsxDatatableComponent.html@31:41
Can't bind to 'pScrollableView' since it isn't a known property of 'div'. ("ozenWidth}" class="ui-datatable-scrollable-view ui-datatable-frozen-view"></div>
              <div [ERROR ->][pScrollableView]="scrollableColumns" [ngStyle]="{'width':this.unfrozenWidth, 'left': this.frozenWidt"): ng:///AppModule/CsxDatatableComponent.html@33:19
Can't bind to 'virtualScroll' since it isn't a known property of 'div'. ("is.unfrozenWidth, 'left': this.frozenWidth}"
                  class="ui-datatable-scrollable-view" [ERROR ->][virtualScroll]="virtualScroll" (onVirtualScroll)="onVirtualScroll($event)"
                  [ngClas"): ng:///AppModule/CsxDatatableComponent.html@34:55 ; Zone: <root> ; Task: Promise.then ;

pColumnHeaders, pColumnFooters are all components which are already exported via the DataTableModule. I am unable to figure out how to make these parsing errors go away, I am sure I am missing something.

Any help is much appreciated.

Update: This is how my app.module.ts looks. I have the DataTableModule, BrowserModule and FormsModule imported. I am able to use the standard primeNg datatable component on my views, just not able to override it.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

/* PRIME NG */
import { 
          AutoCompleteModule,
          PanelMenuModule, 
          MenuItem, 
          MenubarModule, 
          OverlayPanelModule, 
          TabViewModule, 
          ButtonModule, 
          CodeHighlighterModule,
          DropdownModule,
          DialogModule, 
          MultiSelectModule ,
          InputTextModule,
          TooltipModule,
          CheckboxModule,
          SplitButtonModule,
          RadioButtonModule,
          MessagesModule,
          ConfirmDialogModule,
          ConfirmationService,
          AccordionModule,
          PanelModule,
          FieldsetModule,
          CalendarModule,
          DataTableModule,
          MenuModule,
          BreadcrumbModule,
          TreeModule,
          DomHandler,
          ChartModule
        } from 'primeng/primeng';
import { ObjectUtils } from '../../node_modules/primeng/components/utils/ObjectUtils';


/* APP-SPECIFIC */
import { WindowRef } from './windowref';
import { routing } from './app.routing';
import { MyDatatableComponent } from './components/my-datatable.component';


@NgModule({
  declarations: [ 
    DatatableComponent,   
    ChartsGraphsComponent,
    CsxDatatableComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    routing,
    AutoCompleteModule,
    BrowserAnimationsModule,
    PanelMenuModule,
    MenubarModule,
    OverlayPanelModule, 
    TabViewModule,
    ButtonModule,
    CodeHighlighterModule,
    DropdownModule,
    MultiSelectModule,
    DialogModule,
    InputTextModule,
    TooltipModule,
    CheckboxModule,
    SplitButtonModule,
    RadioButtonModule,
    MessagesModule,
    ConfirmDialogModule,
    AccordionModule,
    PanelModule,
    FieldsetModule,
    CalendarModule,
    DataTableModule,
    MenuModule,
    BreadcrumbModule,
    TreeModule,
    ChartModule
  ],
  providers: [
    DomHandler,
    ObjectUtils
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
4
  • I'm having the same error. Commented Jun 17, 2017 at 17:46
  • PrimeNG looks interesting. Is there a way you could perhaps provide a complete setup in Plunker that can be run so you can see the errors. Then link it inside this post. You might get more traction on an answer then. I made a start here for you plnkr.co/edit/9FfNxYieqo6YhlScLSaJ?p=preview Commented Jun 22, 2017 at 19:25
  • whether u imported DataTableModule in app.module Commented Jun 23, 2017 at 10:33
  • Yes, I have updated the question with how my app.module looks like. And it has DataTableModule imported Commented Jun 23, 2017 at 15:10

1 Answer 1

3
+50

You see this error because the selectors you're trying to use are not exported by their respective modules, because they're part of the internal/private part of the PrimeNG framework.

Importing the DataTableModule will make no difference if the selectors you're trying to use are not exported.

In the case of [pColumnHeaders], defined in datatable.ts by the ColumnHeaders component, you'll see that the ColumnHeaders component is not exported in the DataTableModule definition:

@NgModule({
    imports: [CommonModule,SharedModule,PaginatorModule,FormsModule],
    exports: [DataTable,SharedModule],
    declarations: [DataTable,DTRadioButton,DTCheckbox,ColumnHeaders,ColumnFooters,TableBody,ScrollableView,RowExpansionLoader]
})
export class DataTableModule { }

Source of datatable.ts

For you to be able to use the [pColumnHeaders] selector, the DataTableModule would have to export the ColumnHeaders component like so:

@NgModule({
    imports: [CommonModule,SharedModule,PaginatorModule,FormsModule],
    exports: [DataTable,SharedModule,ColumnHeaders],
    declarations: [DataTable,DTRadioButton,DTCheckbox,ColumnHeaders,ColumnFooters,TableBody,ScrollableView,RowExpansionLoader]
})
export class DataTableModule { }

My guess is that this design is intentional and that you're trying to use 'private' and undocumented selectors that are not part of the API.

The question you have to ask yourself is what it is you're trying to achieve. Chances are that the PrimeNG DataTable API provides the interface to do that.

Sign up to request clarification or add additional context in comments.

1 Comment

Since Elwin's explanation for the reason of getting this error is correct. I am going to mark this answer as accepted. And also, Elwin should get the bounty for this. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.