We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Angular2 Grid row details template: how to correctly provide the template in <component.html> instead of <index.html>

Hi,

I am trying to use a row details template for the grid control (as described in https://help.syncfusion.com/angular/grid/row#details-template). Everything works as described, but in my actual application, I ran into two problems:

  1. The template only seems to work if it is placed into index.html. I would like to move the detail template into the Angular2 components html file instead to keep it reusable. I could not find any way to get this to work...
  2. (I am an Angular2 newbie, so maybe related to 1.) Placing Angular2 components (or even other Syncfusion components) into the template seems to not work at all? Also Angular2 databinding (using the {{ variable }} syntax) does not work inside the template, it only accepts the jsrender {{: syntax. I would prefer using Angular2 type templates instead of the JsRender templates, but could not find any way how to use it correctly.

I already tried to switch the template script media type from "text/x-jsrender" to "text/ng-template" (as suggested in some other forum entries) but this seems to not work (I get an "cannot find property __viewRef" exception when trying to expand the detail, similar to a completely missing template)...

Could you please give me a hint to point me into the right direction or can you maybe provide a sample?

Thanks and best regards!


23 Replies

JK Jayaprakash Kamaraj Syncfusion Team June 27, 2017 12:46 PM UTC

Hi Erne, 

Based on your requirement we have prepared a sample that can be downloaded from the following location. 


gridComponent.html 

<ej-grid [allowPaging]="true" [pageSettings.pageSize]="pagesize" [dataSource]="gridData"> 
    <e-columns> 
        <e-column field="EmployeeID" headerText="Employee ID" width="90" textAlign="right"></e-column> 
        <e-column field="FirstName" headerText="First Name" width="90"></e-column> 
        <e-column field="LastName" headerText="Last Name" width="90"></e-column> 
        <e-column field="Country" headerText="Country" width="90"></e-column> 
    </e-columns> 
    <ng-template e-dtemplate> 
        <div class="test"></div> 
    </ng-template> 
</ej-grid> 
 
ej.grid.detail-template.ts 
 
ngOnInit() { 
        var template = this.viewContainerRef.createEmbeddedView(this.templateRef, { '$implicit': [] }); 
        var templID = ej.getGuid('angulartmplstr'); 
        var tempEle = ej.buildTag('div#' + templID); 
        $(tempEle).append(template.rootNodes); 
        ej.createObject('detailsTemplate', $($(tempEle).append(template.rootNodes)).html(), this.parent); 
        this.parent.model.detailsTemplate = $($(tempEle).append(template.rootNodes)).html(); 
        ej.createObject('_templateRef', this.templateRef, this.parent); 
        ej.createObject('_viewRef', this.viewContainerRef, this.parent); 
        let old = ej.template['text/x-template']; 
        var p = this.parent; 
         
        ej.template['text/x-template'] = function (self, selector, data, index, prop) { 
            return old(self, selector, data, index,  prop || p); 
        }; 
        ej.template.render = ej.template['text/x-template']; 
 
        $(tempEle).remove(); 
    } 

Regards, 

Jayaprakash K. 



HE Holger Erne June 28, 2017 08:11 PM UTC

Hi Jayaprakash,

thanks for your feedback - that is actually more than I expected :-). One more question though: How do I get access to the detail data in the template?

I try do do something like:

    <ng-template e-dtemplate> 
        <div class="test">{{detaildata.FirstName}}</div>
    </ng-template> 

Thanks and best regards!



FS Farveen Sulthana Thameeztheen Basha Syncfusion Team June 30, 2017 11:00 AM UTC

Hi Erne, 

Based on your requirement, we have prepared sample using “ng-template” for rendering templates. In this sample we have given the data as ‘data.FirstName’ in ng-template.  Instead of giving like this “{{detaildata.FirstName}}”, you have to use ‘data.FirstName’

Refer to the below sample and code example:-  


Grid.componenet.html 
<ej-grid [allowPaging]="true" [pageSettings.pageSize]="pagesize" [dataSource]="gridData"> 
    <e-columns> 
        <e-column field="EmployeeID"  [isPrimaryKey]="true" headerText="Employee ID" width="90" textAlign="right"></e-column> 
        <e-column field="FirstName" headerText="First Name" width="90"></e-column> 
         
    </e-columns> 
    <ng-template e-dtemplate let-data> 
        <div class="test"> 
            <input ej-button [text]='data.FirstName'/> 
        </div> 
    </ng-template> 
</ej-grid> 
 
Grid.component.ts 
 
import { Component } from '@angular/core'; 
@Component({ 
    selector: 'ej-app', 
    templateUrl: 'src/grid/grid.component.html', 
 
}) 
export class GridComponent { 
    public gridData: any; 
    public pagesize: number; 
    constructor() { 
        this.gridData = window.employeeView; 
        this.pagesize = 5; 
        
    } 
} 


Please get back to us if you need any further assistance. 

Regards, 

Farveen sulthana T 



HE Holger Erne June 30, 2017 01:14 PM UTC

Hi Farvee,

thanks for providing a sample - however, this does not work (please see the attached screenshot). The input element does not display the Firstname, it is always empty. The debugger shows an exception when trying to expland a row, which seems to be related to the "data" variable not being initialized (see attached screenshot, too). Based on your sample, I only did npm install && npm start, nothing else.

I also looked through the sources and checked to see if I can fix - but without success. The main point which is unclear to me is how the "data" variable is initialized and passed (which is then used by the <ng-template let-data> attribute). Could you please explain?


Thanks!



Attachment: 20170630_15h11_26_16ed317.zip


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 3, 2017 01:39 PM UTC

Hi Erne,  
 
We have logged your requirement as usability feature “ng-template support for Grid template” and it will be included in the Volume 3, 2017 Release which has been scheduled to roll out by the end of July, 2017.  
 
Regards,  
Seeni Sakthi Kumar S. 



HE Holger Erne July 3, 2017 01:58 PM UTC

Hi Seeni Sakthi Kumar,

in the meantime: is there really no workaround getting databinding to work in the detail template (at least Farveen sent out a sample demonstrating this)? I would like to demonstrate this to a customer, so it would be really nice to have this working, even if it is a not so clean solution...

Thanks and best regards!


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 4, 2017 11:10 AM UTC

Hi Erne,  
 
We have achieved your requirement by programmatically creating the Detail Template Directive Creation as shown in the following code example.  
 
 
ej.grid.detail-template.ts 
 
    export class EJ_Grid_RowTemplate extends EJTemplateDirective { 
        public parent: GridComponent; 
         . . .  
                . .  
        ngOnInit() { 
             . . . 
                . . .  
            ej.template['text/x-template'] = function (self, selector, data, index, prop) { 
                return old(self, selector, data, index,  prop || p); 
            }; 
            ej.template.render = ej.template['text/x-template']; 
 
            $(tempEle).remove(); 
        } 
    } 
 
 
import { EJ_Grid_DetailTemplate } from './gridtemplates/ej.grid.detail-template'; 
import { Component } from '@angular/core'; 
 
@Component({ 
    selector: 'ej-app', 
    templateUrl: 'src/grid/grid.component.html', 
 
}) 
export class GridComponent { 
            public gridData: any; 
       .. .  
            . .  
        } 
 
 
<ej-grid [allowpaging]="true" [datasource]="gridData"> 
        . .  
             . .  
    <ng-template e-dtemplate let-data> 
        <div class="test"> 
            <input type="text" [value]='data.FirstName' /> 
        </div> 
    </ng-template> 
</ej-grid> 
 
 
In our previous update, ej-button has been rendered and now we have rendered a simple input textbox. We have modified the sample that can be downloaded from the following location.  
 
 
Regards,  
Seeni Sakthi Kumar S. 
 
 



HE Holger Erne July 4, 2017 01:18 PM UTC

Hi,

thank you very much for the updated sample - it is now working as expected. However, I still do not understand how databinding works, so could you please explain it a bit more thoroughly - especially the "let-data" bit - is this name a "magic" name or where does the detail data mapping between the grids dataSource and the item template actually occur?

I searched through your sources to find any instance where the "data" object (which obviously is the detail item data) is initialized. If I understand correctly, "data" gets injected through the template constructor (in ej.grid.detail-template.ts EJ_Grid_DetailTemplate::ngOnInit() where ej.template['text/x-template'] = function(..., data, ...) {};). However, I could not find the place, where it actually get instantiated (so I could see/debug) and how the "[dataSource]=gridData" grid items are assigned to the "data" object for the template?

If I try to replicate this in my application, the "data" object is still not initialized, so I cannot access it in my template and I seem to get the same error/exception as with your previous sample. Any ideas?

Thanks and best regards!





SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 5, 2017 11:45 AM UTC

Hi Holger,  
 
We suspect that you are not using the latest version of the Essential Studio. To render the templates in the Grid, class EJTemplateDirective is required which is placed in template.ts of angular2 source. This has been included in the Essential Studio v15.2.0.40 and later versions. So, we suggest to ensure this at your end. With the help of this alone, EJ_Grid_DetailTemplate of './gridtemplates/ej.grid.detail-template' is rendering templates in our application.  
 
In the following code example, ej.template.render is public helper function of the ej Core which helps to render the templates with the given data. This helper function will call jsRender’s render() method to place a given element with data.  
 
    ngOnInit() { 
        var template = this.viewContainerRef.createEmbeddedView(this.templateRef, { '$implicit': [] }); 
        var templID = ej.getGuid('angulartmplstr'); 
        var tempEle = ej.buildTag('div#' + templID); 
                 . .  
                            . . . 
        let old = ej.template['text/x-template']; 
        var p = this.parent; 
         
        ej.template['text/x-template'] = function (self, selector, data, index, prop) { 
            return old(self, selector, data, index,  prop || p); 
        }; 
        ej.template.render = ej.template['text/x-template']; 
 
        $(tempEle).remove(); 
    } 
 
Regards,  
Seeni Sakthi Kumar S. 



HE Holger Erne July 5, 2017 03:55 PM UTC

Hi,

I seem to be using version 15.2.43 (at least that is the version under node_modules), so I think this should be good?

Attached is another screenshot ("screenshot1") from my environment - you can see the debugger stopping inside the ej.template['text/x-template'] constructor, showing the correct "data" parameter being passed (my detail data items are of type "Mstkn", so this is perfect). However, if I continue running, I get an exception again (screenshot2, screenshot3) - in the detail html template it can obviously not correctly access the data.torqueSeq property (although this is correctly passed as seen on screenshot1).

I don't think there is a lot missing - maybe only a small typo somewhere...

Any Ideas? What else could I check?

Would it make sense to upload my project for you to take a look?


Best regards!


Attachment: Screenshots_94a4b34c.zip


HE Holger Erne July 5, 2017 04:38 PM UTC

Hi,

I see that there is V15.2.46 of syncfusion-javascript available - shall I update?

Best regards!



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 6, 2017 01:05 PM UTC

Hi Holger,  
 
You can upgrade to latest version for utilizing this work around solution.  
 
Regards,  
Seeni Sakthi Kumar S. 



HE Holger Erne July 7, 2017 07:49 AM UTC

Hi,

I have upgradet to the latest version (syncfusion-javascript@15.2.46) now, but it only works partially. Please see my Incident 182695 for more details, a sample project and a video recording of the problem.

Thanks!



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 10, 2017 12:46 PM UTC

Hi Holger,  
 
We couldn’t able to play the given video and it seems like the video has been corrupted. Moreover, the provided Angular CLI Project is not runnable. Please attach a runnable sample. You can also reproduce the issue in that sample attached in our previous update. 
 
Regards,  
Seeni Sakthi Kumar S, 



HE Holger Erne July 10, 2017 01:39 PM UTC

Hi,

it should be pretty easy to get the sample project up and running, please follow these steps:

  1. unpack the sample zip archive (from my previous post)
  2. open a command window in the root folder
  3. run "npm install" to download the dependencies
  4. run "ng serve" to run the application
Of course you need npm and angular-cli installed beforehand (I use angular-cli version 1.0.0 (node 6.9.5/win 32)).

I have attached the sample video again (recoded as MP4, this plays back on my Win10 machine using the standard windows "Movies&TV" player). The video shows the following (in the order given here):
  • expanding the first row works ok
  • expanding the fourth row throws an exception and leaves the input element empty
  • expanding the third row behaves identical to the fourth row
  • expanding the second row works and now populates the thrid and fourth row details correctly.

So overall it seems like the detail expansion only works, if expanded row by row in order starting from the first row...

Thanks and best regards!

Attachment: 20170707_09h33_45_b4656e29.zip


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 12, 2017 01:02 PM UTC

Hi Customer,  
 
We could see you are using the 15.2.43 version of the Angular Components which is the cause of the problem. So we suggest to change and upgrade to 15.2.46 to utilize this functionality.  
 
Regards,  
Seeni Sakthi Kumar S. 



HE Holger Erne July 12, 2017 02:00 PM UTC

Hi Seeni,

I still see the behaviour shown in the video, even with 15.2.46 (although you previously mentioned this should work starting from 15.2.0.40 (!)). I did the following in the sample project you received last week:

  • npm install
  • npm install syncfusion-javascript@latest --save
  • ng serve

This shows the exact same behaviour - expanding the first item works, expanding any non-sequential next item (e.g. the fourth item) does not work.

Did you actually try to run my sample?

Best regards!




HE Holger Erne July 12, 2017 02:15 PM UTC

Hi,I digged around a bit more and found that the package.json also references "ej-angular2" in version 15.2.43. However, there seems to not be any version greater than 15.2.43 anywhere available. If I try to install ejangular@latest, it will give me 15.2.43. If I manually try to force it to 15.2.46, it will throw an error saying that this version is not available...So if you are saying I shall update to 15.2.46, which exact components do you mean? Please provide detailed instructions.Best regards!


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 13, 2017 08:47 AM UTC

Hi Holger,  
 
We are sorry for the inconvenience.  
 
We can reproduce the problem at our end. The given solution has been failed to work in the following scenario that the Index and Data for the specific templates were passed inaccurately and the templates down the Grid rows were not generated. Sequential rows were generated the templates one by one but not the alternate rows or the rows down the Grid which is the cause of the problem. Since it is a work around solution, we cannot overcome this at the application level. As said earlier in our previous updates, we will provide the source fix in the Volume 3, 2017 release.  
 
Regards,  
Seeni Sakthi Kumar S. 



HE Holger Erne July 13, 2017 10:06 AM UTC

Hi Seeni,

thanks for the clarification. However, what was quite disappointing, is that you recommended twice upgrading your software will fix the problem - so this wrong information wasted quite some time on my end.

It is as it is - so I will wait for the update.

Best regards!



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team July 14, 2017 04:33 AM UTC

Hi Holger,  
 
We are sorry for the inconvenience.  
 
You can avail the fix in the Volume 3, 2017 which has been scheduled to roll out by the end of July, 2017. 
 
Regards,  
Seeni Sakthi Kumar S. 



LL Luka Lizatovic February 12, 2018 08:42 PM UTC

How to format eg. ej-grid on component level in angular?
When I want to format eg .ej-grid css style is apply only when I paste css in global styles.css file
, but I want to format eg. 2 grids differently how to achieve this?
Will it be somewhat easier to format in angular Essentials JS2 ?




SE Sathyanarayanamoorthy Eswararao Syncfusion Team February 14, 2018 07:19 AM UTC

Hi Luka,  
  
Thanks for contacting Syncfusion support.  
  
Query1: How to format eg. ej-grid on component level in angular?  
 
This query has been discussed in the below public site. Please refer the below link for the details. 
 
  
  
Query2:  I want to format eg. 2 grids differently how to achieve this?  
  
Your requirement can be achieved by using ‘/ng-deep/’. In this sample we have render 2 grids separate component and applied different component level styles for each grid using this ng-deep selector.     
Please refer to the following code example and reference link.    
  
@Component({   
    selector: 'grid2',   
    template: `<ej-grid [dataSource]='data'>   
               </ej-grid>`,   
    styles: [`:host  ::ng-deep .e-grid .e-rowcell {   
      color: red   
    }`]   
})          
  
  
  
  
Regards,  
Sathyanarayanamoorthy  


Loader.
Up arrow icon