Template column does not display

Hello, 

I can't display the template column in a dynamically generated. Inside the template i have a custom component for displaying a menu.

HTML:

<ejs-grid #grid 
        [rowHeight]="27" 
        (rowDrop)="rowDrop($event)" 
        allowPaging='true' 
        allowReordering='true'
        allowResizing='true' 
        [allowRowDragAndDrop]='boldGridService._hasOrderFlag' 
        allowSorting='true'
        (actionComplete)="actionComplete($event)" 
        [showColumnChooser]='true' 
        [enableHeaderFocus]="true"
        (columnDataStateChange)="actionComplete($event)" 
        [allowFiltering]='true' 
        [dataSource]='data'
        [pageSettings]='pageSettings' 
        [filterSettings]='filterSettings' 
        [toolbar]="toolbar"
        (actionFailure)="onActionFailure($event)">
        <e-columns>

            <ng-container *ngFor="let column of boldGridService.headers">

                <e-column 
                [type]="column.propertyType" [field]="column.propertyName"  
                [headerText]="column.regionalizedName | translate" 
                [visible]="true" [format]="''"
                [isPrimaryKey]="false" [showInColumnChooser]="true"
                [width]="column.propertyType == 'Boolean' ? '100' : 'auto'" 
                [valueAccessor]="valueAccess"
                [displayAsCheckBox]="column.propertyType == 'Boolean'">
                </e-column>

            </ng-container>

            <e-column 
                [headerText]="'☰'" 
                headerTextAlign='Center' 
                [visible]="true" 
                [format]="''" 
                [isPrimaryKey]="false"
                [showColumnMenu]="false" 
                [showInColumnChooser]="false" 
                width="60">

                <ng-template id="actionTemplate" #actionTemplate let-actionItem>

                    <div style="height: 27px;">
                        <app-action-buttons [item]="actionItem" [entityType]="entityType" [actions]="gridActions"
                            (onActionClickEvent)="onActionClick($event)" [detailsMode]="false">
                        </app-action-buttons>

                    </div>

                </ng-template>

            </e-column>


        </e-columns>
    </ejs-grid>

I am using a DataManager with a custom Adaptor implementation.
Any tips on how to display the component inside the grid?

Thanks,

19 Replies

MS Manivel Sellamuthu Syncfusion Team December 23, 2020 01:28 PM UTC

Hi Florian, 

Greetings from Syncfusion support. 

We have analyzed the  code example. We suggest you to set the id for the template as “template” to resolve the issue.  The Grid column template needs to  be have id as template for the columns to identify their templates. 

  <ejs-grid #grid [dataSource]='data'> 
        <e-columns> 
            <e-column headerText='Employee Image' width='150' textAlign='Center'> 
                <ng-template #template let-data> 
                    <div class="image"> 
                        <img src="./assets/grid/images/{{data.EmployeeID}}.png" alt="{{data.EmployeeID}}"/> 
                    </div> 
                </ng-template> 
            </e-column> 
            <e-column field='EmployeeID' headerText='Employee ID' width='125' textAlign='Right'></e-column> 
            <e-column field='FirstName' headerText='Name' width='120'></e-column> 


Please let us know, if you need further assistance. 

Regards, 
Manivel 



FB Florian Buca December 23, 2020 01:48 PM UTC

I also tried to name it template, but i was having one error regarding the template, so the fix i thought was the renaming part. 
If I change back to "template" i have the same error:

I use angular "^8.2.14" and syncfusion "18.4.30"

error: TypeError: item.clearTemplate is not a function at ColumnsDirective.push../node_modules/@syncfusion/ej2-angular-base/src/complex-array-base.js.ArrayBase.clearTemplate (http://localhost:4500/vendor.js:198112:18) at _loop_1 (http://localhost:4500/vendor.js:198848:32) at clearTemplate (http://localhost:4500/vendor.js:198855:9) at GridComponent.push../node_modules/@syncfusion/ej2-angular-base/src/component-base.js.ComponentBase.clearTemplate (http://localhost:4500/vendor.js:198306:68) at GridComponent.push../node_modules/@syncfusion/ej2-grids/src/grid/base/grid.js.Grid.destroyTemplate (http://localhost:4500/vendor.js:290374:14) at ContentRender.push../node_modules/@syncfusion/ej2-grids/src/grid/renderer/content-renderer.js.ContentRender.refreshContentRows (http://localhost:4500/vendor.js:298686:25) at GridComponent.<anonymous> (http://localhost:4500/vendor.js:305616:47) at GridComponent.push../node_modules/@syncfusion/ej2-angular-base/src/component-base.js.ComponentBase.trigger (http://localhost:4500/vendor.js:198454:21) at Render.push../node_modules/@syncfusion/ej2-grids/src/grid/renderer/render.js.Render.dataManagerSuccess (http://localhost:4500/vendor.js:305532:14) at http://localhost:4500/vendor.js:305381:54
message: "item.clearTemplate is not a function"
stack: "TypeError: item.clearTemplate is not a function↵    at ColumnsDirective.push../node_modules/@syncfusion/ej2-angular-base/src/complex-array-base.js.ArrayBase.clearTemplate (http://localhost:4500/vendor.js:198112:18)↵    at _loop_1 (http://localhost:4500/vendor.js:198848:32)↵    at clearTemplate (http://localhost:4500/vendor.js:198855:9)↵    at GridComponent.push../node_modules/@syncfusion/ej2-angular-base/src/component-base.js.ComponentBase.clearTemplate (http://localhost:4500/vendor.js:198306:68)↵    at GridComponent.push../node_modules/@syncfusion/ej2-grids/src/grid/base/grid.js.Grid.destroyTemplate (http://localhost:4500/vendor.js:290374:14)↵    at ContentRender.push../node_modules/@syncfusion/ej2-grids/src/grid/renderer/content-renderer.js.ContentRender.refreshContentRows (http://localhost:4500/vendor.js:298686:25)↵    at GridComponent.<anonymous> (http://localhost:4500/vendor.js:305616:47)↵    at GridComponent.push../node_modules/@syncfusion/ej2-angular-base/src/component-base.js.ComponentBase.trigger (http://localhost:4500/vendor.js:198454:21)↵    at Render.push../node_modules/@syncfusion/ej2-grids/src/grid/renderer/render.js.Render.dataManagerSuccess (http://localhost:4500/vendor.js:305532:14)↵    at http://localhost:4500/vendor.js:305381:54"
__proto__: Error
name: "actionFailure"


MS Manivel Sellamuthu Syncfusion Team December 24, 2020 09:44 AM UTC

Hi Florian, 
 
Thanks for your update. 
 
From the shared actionFailure stacktrace we can understand that there is an issue in the template. We have already discussed about how to render other components in a grid column in the below documentation. 
 
 
If you still faced the issue, we request you to share the complete Grid to replicate the issue at our end for proceeding futher. 
 
Regards, 
Manivel 



FB Florian Buca December 24, 2020 11:15 AM UTC

As you can imagine I was reading the documentation before posting this problem.

You can find here an environment that reproduces the problem above: 


FB Florian Buca December 29, 2020 11:24 AM UTC

Hi Manivel,

Any updates on the topic?


MS Manivel Sellamuthu Syncfusion Team December 29, 2020 01:48 PM UTC

Hi Florian, 

Sorry for the delay getting back to you. 

From the shared code example we suspect that you want to dynamically generate the columns. The reported issue occurs due to ng-containers used inside the columns. So we suggest you to set the columns in the Typescript way to resolve the issue. Please refer the below code example and sample for more information. 

<div class="control-section"> 
    <ejs-grid [dataSource]='data' [columns]="columns" height='350'> 
    </ejs-grid> 
</div> 

export class AppComponent { 
    public data: Object[] = []; 
    public columns: Object[]; 
 
    ngOnInit(): void { 
        this.data = orderDetails; 
        this.columns = [  
          // here you  can generate the fields dynamically    
          { field: 'OrderID', headerText: 'Order ID', width: 120, textAlign: 'Right' }, 
          { field: 'CustomerName', headerText: 'Customer Name', width: 150 }, 
          { field: 'OrderDate', headerText: 'Order Date', width: 130, format: 'yMd', textAlign: 'Right' }, 
          { field: 'Freight', width: 120, format: 'C2', textAlign: 'Right' }, 
          { field: 'ShippedDate', headerText: 'Shipped Date', width: 140, format: 'yMd', textAlign: 'Right' }, 
          { field: 'ShipCountry', headerText: 'Ship Country', width: 150 }] 
    } 
} 


Please let us know, if you need further assistance on this. 

Regards, 
Manivel 



FB Florian Buca December 29, 2020 03:06 PM UTC

Hello again Manivel,

I tried to map the columns from the ts, and i got the following:

I tried to set the template column from the ts. that did not work.
If I pass the column like you suggested, the grid keeps refreshing making 1 call at every 1ms.


I really hope we can solve this problem as soon as we can.
Thank you



FB Florian Buca December 29, 2020 03:24 PM UTC

Also, maybe this helps.

I switched back to the previous code, and at the first load it gets error "item.clearTemplate". 
At the second load, it loads the template for the last column but for the one that has a switch action, i need to apply one sort command.


You can check the my recorded screen here.

Thanks


MS Manivel Sellamuthu Syncfusion Team December 30, 2020 12:45 PM UTC

Hi Florian, 

Thanks for your update. 

We have checked the provided sample and found that updating the columns in the processResponse method of the bold-grid.service.ts is the cause of the issue.  

By default while updating the columns the grid will be refreshed. The processResponse will trigger after the successful of server response. Since you are updating the columns in the processResponse method of the Grid, column change and processResponse is occurring continuously, which causes the issue. 

So we have used a flag variable to prevent the assigning of columns, to prevent the issue. Please refer the below code example and modified sample for more information. 

 
export class BoldGridService extends UrlAdaptor { 
. . . 
  public isInitial: boolean = true; 
 
    public processResponse(): object { 
    let request: any = super.processResponse.apply(this, arguments); 
 
    let result = []; 
    let count = 0; 
    let fields = []; 
 
    if (request.isSuccess === true) { 
      count = request.payload.totalNoOfRecords; 
      result = request.payload.records; 
      fields = request.payload.header; 
      if (this.isInitial) { 
        this.isInitial = false; 
      this.setColumns(request.payload.header); 
      this.assignClientColumns(); 
      } 
 
    } else { 
      // handle error here! 
    } 
    //this.tableCommunicationService.requestComplete.next({ result: result, count: count, fields: fields }); 
    return { 
      result: result, 
      count: count, 
      fields: fields, 
      currentColumns: fields, 
      keys: fields 
    }; 
    //return { result: request.result, count: request.count, keys: fields }; 
  } 


Please let us know, if you need further assistance. 

Regards, 
Manivel


FB Florian Buca December 30, 2020 01:26 PM UTC

Hello Manivel,

That flag seems to work ok.
I am left with one single problem now. The template column. 
As you can see in the sample i have defined the templates into variables but they don't display if i assign it through template property.

How can this be done from the ts?

Thank you,


MS Manivel Sellamuthu Syncfusion Team December 31, 2020 12:25 PM UTC

Hi Florian, 

Thanks for your update. 

We are glad that the provided suggestion helped. 

You can apply the templates dynamically from the typescript using dataBound event of the Grid. Please refer the below code example and sample for more information. 

[bold-grid.component.ts] 

export class BoldGridComponent implements OnInit { 
 
  @ViewChild("grid", { staticfalse }) public grid: AGridComponent; 
  @ViewChild("template ", { staticfalse }) public actionTemplate: any; 
  @ViewChild("checkItem") 
  public temp1TemplateRef<{}>; 
    @ViewChild("actionItem") 
  public temp2TemplateRef<{}>; 
 
    dataBound () { 
    (this.grid.getColumns()[9].template as any) = this.temp1; 
    (this.grid.getColumns()[10].template as any) = this.temp2; 
  } 
[bold-grid.component.html] 
 
  <ejs-grid #grid [rowHeight]="27" (dataBound)="dataBound($event)" (rowDrop)="rowDrop($event)" allowPaging="true" allowReordering="false" 
    allowResizing="true" [allowRowDragAndDrop]="boldGridService._hasOrderFlag" allowSorting="true" 
    allowEditing="true" (actionComplete)="actionComplete($event)" [showColumnChooser]="true" 
    [enableHeaderFocus]="false" (columnDataStateChange)="actionComplete($event)" [allowFiltering]="false" 
    [dataSource]="data" [pageSettings]="pageSettings" [filterSettings]="filterSettings" [toolbar]="toolbar" 
    [columns]="boldGridService.clientHeaders" [enableHover]="false" (actionFailure)="onActionFailure($event)"> 
 
  </ejs-grid> 
</div> 
 
<ng-template id="actionItem" #actionItem let-actionItem> 
 
  <div style="height: 27px;"> 
    <app-action-buttons [item]="actionItem" [entityType]="entityType" [actions]="gridActions" 
      (onActionClickEvent)="onActionClick($event)" [detailsMode]="false"> 
    </app-action-buttons> 
 
  </div> 
 
</ng-template> 
 
  <ng-template #checkItem let-checkItemy> 
 
  <div class="custom-control custom-switch mb-2"> 
    <label> 
      <input [checked]="checkItem.isDisabled" 
        (click)="onActionClickEvent.emit({item: checkItem, action: 19});" type="checkbox" 
        class="custom-control-input"> 
      <span class="custom-control-label"></span> 
    </label> 
  </div> 
 
</ng-template> 


Please let us know, if you need further assistance. 

Regards, 
Manivel 



FB Florian Buca January 4, 2021 10:27 AM UTC



MS Manivel Sellamuthu Syncfusion Team January 5, 2021 10:43 AM UTC

Hi Vlad, 

Thanks for your update. 

We have validated the provided sample and found that the template inside the actionItem is not configured properly. The template works fine if we commented the template or if we use the other templates. So we suggest you to ensure the template is configured properly. 

 
<ng-template id="actionItem" #actionItem let-actionItem> 
custom template here 
  <!-- <div style="height: 27px;"> 
    <app-action-buttons [item]="actionItem" [entityType]="entityType" [actions]="gridActions" 
      (onActionClickEvent)="onActionClick($event)" [detailsMode]="false"> 
    </app-action-buttons> 
  </div> --> 
 
</ng-template> 


 

Please let us know, if you need further assistance. 

Regards, 
Manivel 



FB Florian Buca January 5, 2021 10:58 AM UTC

I managed to solve it by providing the template at column rendering and now both templates are rendering ok. The databound was not working for me.

I have one more problem though. 
I noticed that after setting the isInitial variable to false it stops sending a continuum request but it makes 2 requests before stopping.
I want to be only one request.

You can find the sample here:


MS Manivel Sellamuthu Syncfusion Team January 6, 2021 05:44 PM UTC

Hi Ben, 

Thanks for your update. 

We have validated the provided sample and we could see that the columns are obtained from the first network request. After the request to the server only the columns are applied to the Grid, so the Grid is refreshed. Due to this case it is not feasible to prevent the second network request in initial rendering. 

Regards, 
Manivel 



SP santosh Palai replied to Manivel Sellamuthu June 17, 2021 05:36 AM UTC

Hi Ben, 

Thanks for your update. 

We have validated the provided sample and we could see that the columns are obtained from the first network request. After the request to the server only the columns are applied to the Grid, so the Grid is refreshed. Due to this case it is not feasible to prevent the second network request in initial rendering. 

Regards, 
Manivel 


Hello, Template column data(i.e-language, copy icon & delete icon in Action column) is not displaying. Only expand & collapse icons are displaying.
Here is the screenshot.


Here is my html.
<ejs-treegrid #treegrid (actionBegin)='treeGridChange($event)' [dataSource]='allTableContents'
              childMapping='subcontents' [treeColumnIndex]='0' [editSettings]='editSettings' [toolbar]='toolbar'
              locale='en-US' allowPaging='true' [pageSettings]='pageSettings' showColumnChooser='true'
              allowFiltering='true' [filterSettings]='filterSettings' [gridLines]='lines'
              (rowDataBound)='rowDataBound($event)'>

              <e-columns>

                <e-column *ngFor="let item of displayedColumns; let idx = index" textAlign='Right'
                  [isPrimaryKey]='idx == 0 ? true : false' [field]='item.name' [width]="idx == 0 ? 200 : 150"
                  [headerText]='item.name'
                  [editType]="item.type == 'dropdown' ? 'dropdownedit' : item.type == 'multi_dropdown' ? 'dropdownedit' : item.type == 'date' ? 'datepickeredit' : 'stringedit'"
                  [edit]="(item.type == 'dropdown' || item.type == 'multi_dropdown') ? item.optionData : ''">


                  <ng-template #template let-rowData>

                    {{rowData._lang}}
                    <mat-slide-toggle
                      *ngIf="rowData.default_content_id == '' || rowData.default_content_id == null || rowData.default_content_id == undefined"
                      class="flex-fill order-1" [(ngModel)]="rowData['isActive']" (change)="toggle(rowData)"
                      [matTooltip]="rowData['isActive'] ? 'Deactivate the content' : 'Activate the content'">
                    </mat-slide-toggle>

                    <button
                      *ngIf="rowData.default_content_id == '' || rowData.default_content_id == null || rowData.default_content_id == undefined"
                      mat-icon-button class="order-2" (click)="copyMContent(rowData)" matTooltip="Copy">
                      <ion-icon src="../../../assets/apie_img/icons/copy-outline.svg"></ion-icon>
                    </button>

                    <button
                      *ngIf="rowData.default_content_id == '' || rowData.default_content_id == null || rowData.default_content_id == undefined"
                      class="ml-2 order-3" mat-icon-button (click)="deleteContent(rowData.id)" matTooltip="Delete">
                      <ion-icon src="../../../assets/apie_img/icons/trash-outline.svg"></ion-icon>
                    </button>

                  </ng-template>
                </e-column>

              </e-columns>

            </ejs-treegrid>


PS Pon Selva Jeganathan Syncfusion Team June 18, 2021 12:57 PM UTC

Hi santosh, 
 
Thanks for contacting Syncfusion forum. 
 

Query: template column does not display

We have checked your query by preparing sample(template column), but we are unable to reproduce the issue at our end. Please refer to the below sample, 
After following the above reference, still faced issue please share us the following details.  
  1. Kindly share us complete tree grid code example.
  2. Share the details of your product version. 
  3. Share the video demo of the issue.
  4. Kindly share the Complete StackTrace of the Script Error(if any).
  5. If possible, reproduce the reported issue in the shared sample Or share us issue reproducing sample.  
 
The provided information will be helpful to provide you response as early as possible.   
 
Regards,
Pon selva
 



SP santosh Palai June 19, 2021 09:56 AM UTC

Thank you   @Pon Selva Jeganathan,

It is working now after change the code style like present in below sample
.
https://stackblitz.com/edit/angular-vzkx8m-zu2f3a?file=app.component.html 

Thanks for your reference
.



PS Pon Selva Jeganathan Syncfusion Team June 21, 2021 02:19 PM UTC

Hi Santosh,   
  
Thanks for the update.    
  
We are glad to hear that the query has been resolved by a shared sample.    
  
Kindly get back to us for further assistance.  
  
Regards,  
Pon selva  
 


Loader.
Up arrow icon