I have a default ag-grid header, that is configured just like I need it. It is not movable, it is pinned and stuff like that. Now I have the challenge that seemed pretty simple but perhaps is the hardest thing to do using ag-grid - just spend the last two days on this... I just want to add one little button that I can react on in my angular component. I tried it with Header Templates: I can add a button here but I am not able to react on the click event. Then I tried Header Components but then, I have to take care of all the different features like sorting, filtering, menu, styling, ... Result: Suddenly, I can move the former pinned column around, it looks different than the other columns and and and. Just hell! What is the easiest way to add a button to one column header but keep the styling and functionality just as it is? UPDATE After playing around with the ag-grid demo code from ag-grid, trying to use Header Components, I am back trying to use Header Templates. My current solution is to use the template to add my buttons and to wire up the events in code on the GridReady event. Something like: <div class="ag-cell-label-container" role="presentation"> <span ref="eMenu" class="ag-header-icon ag-header-cell-menu-button"></span> <div ref="eLabel" class="ag-header-cell-label" role="presentation"> <div> <span id="ID1"><i class="someclass1"></i></span> <span id="ID2"><i class="someclass2"></i></span> </div> <span ref="eSortOrder" class="ag-header-icon ag-sort-order"></span> <span ref="eSortAsc" class="ag-header-icon ag-sort-ascending-icon"></span> <span ref="eSortDesc" class="ag-header-icon ag-sort-descending-icon"></span> <span ref="eSortNone" class="ag-header-icon ag-sort-none-icon"></span> <span ref="eText" class="ag-header-cell-text" role="columnheader"></span> <span ref="eFilter" class="ag-header-icon ag-filter-icon"></span> </div> </div> And then to wire up the events: const elm1: HTMLElement = document.getElementById('ID1') as HTMLElement; Observable.fromEvent(elm1, 'click').takeWhile(() => this._isAlive).subscribe((event: MouseEvent) => { event.preventDefault(); event.stopPropagation(); // Logic }); Seems to work but I definitely hope that there is a more professional way to do it... Continue reading...