timtos
timtos

Reputation: 2305

Add a button to an ag-grid column header

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...

Upvotes: 3

Views: 16043

Answers (2)

Kevin Hoskins
Kevin Hoskins

Reputation: 11

I realize that this is an old post, but it doesn't seem to have an elegant answer yet. The op came close, but it only works for a single id and doesn't play nice with sorting the header. My solution is as follows:

Update the template with a custom clickable element:

...
<div ref="eLabel" class="ag-header-cell-label" role="presentation">
    <a href onclick="agHandleClick(event)" ref="eCustomButton" class="ag-header-icon ag-header-cell-custom-button"></a>
    <span ref="eText" class="ag-header-cell-text" role="columnheader"></span>
...
</div>

In onGridReady, add the "agHandleClick" function to windows:

let _window: Window = window;
_window['agHandleClick'] = (event) => {
    event.preventDefault();
    event.stopPropagation();
    event.stopImmediatePropagation();
    // Logic
    console.log('header click', event);
};

Upvotes: 0

Lynx
Lynx

Reputation: 51

In React agGrid I did what you need. Hope it helps. I did it with custom header example in agGrid https://www.ag-grid.com/javascript-grid-header-rendering/#example-header-component

In Column defs, as an example I added expandAll property

[{
    headerName: "Group",
    field: "group",
    expandAll: true
}]

in CustomHeader.js

let expand = null;
if (this.props.api.getColumnDef(this.props.column.colId).expandAll) {
    let text = this.state.expanded ? 'Collapse' : 'Expand';
    xpand = <span onClick={this.onExpandRequested.bind(this)}>{text}</span>
}

return (
    <React.Fragment>{expand}{headerTitle}{sort}</React.Fragment>
);

onExpandRequested (isExpanded) {

    if (this.state.expanded) {

        this.props.api.collapseAll();
    } else {

        this.props.api.expandAll();
    }
    this.setState({expanded: !this.state.expanded});
}

Upvotes: 0

Related Questions