最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Rendering HTML in AG Grid Column Header (Community v20.0.0 +) - Stack Overflow

programmeradmin2浏览0评论

I previously upgraded my AG Grid package from an 18x to 20.0.0 (Community Version). In the previous version, I was simply able to pass an HTML string to the colDefs.headerName property and it would render HTML in the header.

This new version renders header and cell data as a string by default. So now the column headers are rendering like this:

<span ref="eText" class="ag-header-cell-text" role="columnheader">
   "<span id="header-span-1" style="visibility: visible; position: static; display: inline-block; padding-bottom: 5px;">Some Text</span>"
</span>

I previously upgraded my AG Grid package from an 18x to 20.0.0 (Community Version). In the previous version, I was simply able to pass an HTML string to the colDefs.headerName property and it would render HTML in the header.

This new version renders header and cell data as a string by default. So now the column headers are rendering like this:

<span ref="eText" class="ag-header-cell-text" role="columnheader">
   "<span id="header-span-1" style="visibility: visible; position: static; display: inline-block; padding-bottom: 5px;">Some Text</span>"
</span>

I obviously want to go with the easiest solution, which seems to be using a Cell Renderer (or something similar as described on https://www.ag-grid./javascript-grid-cell-rendering-ponents/) that simply returns the HTML. How could the following be achieved in using the headerName property?

colDef.cellRenderer = function(params) {
    var html = '<span id="header-span-1" style="visibility: visible; position: static; display: inline-block; padding-bottom: 5px;">Some Text</span>';
    return html;
}

If it can't, would someone please provide a working example of how to use a header ponent for what I'm specifically after? I saw where I could define a template, but it seems like overkill considering I only need what I've described above. I've searched around and can't seem to find an example.

UPDATE

Thanks to Dominic's response below, I was able to e up with a solution that didn't require excessive (and unnecessary) effort. Again, for my particular use case, I have limited control over the column data ing back from the server, but needed to have a way to format it - beyond the functionality provided by AG Grid's formatter and getter properties.

In my project, the column definitions are provided via a class...

export class colDefs {
    constructor(
        public headerName: any,
        public field: any,
        ...
    ) { } 
}

...and instantiated in the applicable typescript ponents like this:

for (var i = 0; i < arr.length; i++) {
  ... // Do stuff
  this.columnDefs[i] = new colDefs(headerName, field, ...);
  ... // Do stuff
 }

Taking Dominic's advice, I simply created a new class named HTMLRenderer (extended from HeaderComp). I also added a new property to exported class colDefs named "headerComponent", and I pass the HTMLRenderer as its value.

import { HeaderComp } from 'ag-grid-munity/dist/lib/headerRendering/header/headerComp';
class HTMLRenderer extends HeaderComp {
    init(params) { 
    super.init(params);
    // @ts-ignore: Unreachable code error
    this.eGui.querySelector('[ref="eText"]').innerHTML = params.displayName; 
  }
}

export class colDefs {
    constructor(
        public headerName: any,
        public headerComponent: any = HTMLRenderer,
        public field: any,
        ...
    ) { } 
}

Please take note of the // @ts-ignore: Unreachable code error ment. It's needed. Otherwise, if you're using typescript, it will throw an error and fail to pile.

Finally, in my typescript ponents that instantiate the colDefs class, I pass the applicable values. But for the headerComponent property, you MUST pass undefined, which basically says that we want to go with the default value as defined in the exported class:

for (var i = 0; i < arr.length; i++) {
  ... // Do stuff
  this.columnDefs[i] = new colDefs(headerName, undefined, field, ...);
  ... // Do stuff
 }

This did it for me without the overkill that would have been involved with creating a full header ponent for just a small string of HTML in the header. The HTML in my AG Grid column headers are rendering now!

Please note there is actually another approach for acplishing this that involves isolating the HTMLRenderer in its own class file. You ultimately have to register it as a provider in app.module AND in each typescript file you want to use it in...NOT to mention you also have to export the class AND make it an Injectable.

To me, this approach seems like too much work for the little bit of HTML I have in the column headers.

Share Improve this question edited Mar 23, 2019 at 3:45 Cœur 38.8k25 gold badges205 silver badges277 bronze badges asked Mar 22, 2019 at 0:09 tommydevtommydev 431 silver badge5 bronze badges 1
  • You need to write a header renderer. However, if your HTML string is simple and mostly concerned with formatting, you could write a simpler solution based on CSS classes and the headerClass field of the columns. – Chris Commented Mar 22, 2019 at 2:00
Add a ment  | 

4 Answers 4

Reset to default 3

Sadly they decided that HTML wouldn't be useful in the header or accidentally broke it so you can't even use something like ° or Δ for units. Even worse is that the architecture around the header renderer is awful - in order to customize it they want you to also take over handling for sorting, filtering, menu etc. Bizarre that this would be their first assumption but anyway... At least they should provide an innerRenderer like they do with cells.

The only thing they export is headerRootComp which seems totally useless. In order to not take over all the responsibility for the sorting etc mentioned you have to get the ponent that they use to render the default header. Note that this isn't officially exported and could change:

import { HeaderComp } from 'ag-grid-munity/dist/lib/headerRendering/header/headerComp';

class HeaderHTMLRenderer extends HeaderComp {
  init(params) {
    super.init(params);
    this.eGui.querySelector('[ref="eText"]').innerHTML = params.displayName;
  }
}

Pass this in as your default renderer:

defaultColDef={{
  headerComponent: HeaderHTMLRenderer,
}}

If you do not want to create a rendering ponent, really the simplest approach is to apply a css class:

gridOptions.columnDefs = [
    {
        headerName: 'MyCol',
        headerClass: 'col-css-class',
        ...
    };

If you need something more plex, you won't be able to do it without a rendering ponent.

This functionality was changed in AG Grid 27, now you MUST use a rendering ponent to display HTML. (Unfortunately)

For anyone who wants to extend default HeaderComp, here is a solution in plain JavaScript (ES6) which does not require Babel

class CustomHeaderComp extends (new agGrid.UserComponentRegistry()).agGridDefaults['agColumnHeader'] {
    init(params) {
        super.init(params)
        this.eGui.querySelector('[ref="eText"]').innerHTML = params.displayName
    }
}

For some reason HeaderComp is not exposed in latest version (28.2.1), that's why here we have to resolve it from UserComponentRegistry

发布评论

评论列表(0)

  1. 暂无评论