How to create nested Custom Column Menu Item similar to columns

Hi,
How can we create nested Custom Column Menu Item similar to columns in below image.

Screenshot (452).png


1 Reply

PG Praveenkumar Gajendiran Syncfusion Team September 23, 2021 06:49 AM UTC

Hi Venkatesh,

Thanks for contacting Syncfusion support.

Based on your query, we understand you want to render nested custom column menu item. So, we have prepared a custom sample to add the Aggregate option functionalities(nested custom column menu item) in the column menu's feature as demonstrated in the below code example. Please refer the below sample, code example and screenshot for more information.

In the below sample, we add the custom column menu item in the “columnMenuItems” property and then the open/show the custom dialog when mouseover on the custom menu item, in the custom dialog’s content we have the Aggregate option functionalities to perform the aggregate action, likewise you can add/perform any functionalities to meet your requirement. 
export class ColumnMenuSample extends SampleBase { 
  constructor() { 
    super(...arguments); 
    this.filterSettings = { type: 'CheckBox' }; 
    this.flag = true; 
    this.columnMenuItems = [ 
      'AutoFitAll', 
      'AutoFit', 
      'SortAscending', 
      'SortDescending', 
      'Filter', 
      text: 'Aggregate'id: 'gridAggregate' }, 
      'ColumnChooser', 
    ]; 
    this.buttons = [ 
      { 
        buttonModel: { 
          content: 'OK', 
          cssClass: 'e-flat', 
          isPrimary: true, 
        }, 
        click: (args=> { 
          this.btnClick1(args); 
        }, 
      }, 
    ]; 
    this.listData1 = [ 
      { text: 'Sum of'id: 'Sum' }, 
      { text: 'Average of'id: 'Average' }, 
    ]; 
  } 
  columnMenuOpen(args) { 
    if (args.element.id && args.element.id == 'Grid_columnmenu') { 
      args.element.addEventListener( 
        'mouseover', 
        function (e) { 
          if (e.target.id == 'gridAggregate') { 
            var dy = e.target.offsetParent.offsetTop; 
            var dx = 
              e.target.offsetParent.offsetWidth + 
              e.target.offsetParent.offsetLeft; 
            (this.dialogInstance.position = { X: dxY: dy }), 
              this.dialogInstance.show();   //show the dialog when mouseover on target element 
          } else { 
            this.dialogInstance.hide(); 
          } 
        }.bind(this) 
      ); 
      this.grid.element.addEventListener( 
        'mouseover', 
        function (e) { 
          this.dialogInstance.hide(); 
        }.bind(this) 
      ); 
    } 
  } 
  beforeOpen(args) { 
    //dialog's onBeforeope event 
    if (this.flag) { 
      var listObj2Data = []; 
      this.grid.columns.forEach(columns); 
      function columns(items) { 
        if (items.type == 'number') { 
          var lData = { text: ''id: '' }; 
          lData.text = items.headerText; 
          lData.id = items.field; 
          listObj2Data.push(lData); 
        } 
      } 
      this.listObj2.dataSource = listObj2Data// bind the Grid's numeric columns list. 
      this.flag = false; 
    } 
  } 
  btnClick1() { 
    //dialog's ok button click function 
    //here we preform the Grid's aggregate action manually with the selected type and column in the list. 
    var aType = this.listObj1.getSelectedItems().data; 
    var aColumn = this.listObj2.getSelectedItems().data; 
    var aggregate = []; 
    for (var j = 0j < aType.lengthj++) { 
      var firstLevelObj = { columns: [] }; 
 
      for (var i = 0i < aColumn.lengthi++) { 
        var secondLevelObj = { 
          type: '', 
          field: '', 
          footerTemplate: 'Sum: ${Sum}', 
        }; 
        secondLevelObj.field = aColumn[i].id; 
        secondLevelObj.type = aType[j].id; 
        secondLevelObj.footerTemplate = 
          aType[j].id + ': ${' + aType[j].id + '}'; 
        firstLevelObj.columns.push(secondLevelObj); 
      } 
      aggregate.push(firstLevelObj); 
    } 
    this.grid.aggregates = aggregate; 
    this.dialogInstance.hide(); 
    this.grid.columnMenuModule.columnMenu.close(); 
  } 
  render() { 
    return ( 
      <div className="control-pane"> 
        <div className="control-section" id="dialog-target"> 
          <GridComponent 
            id="Grid" 
            ref={(g=> (this.grid = g)} 
            dataSource={orderDetails} 
            allowPaging={true} 
            allowSorting={true} 
            allowFiltering={true} 
            showColumnMenu={true} 
            filterSettings={this.filterSettings} 
            columnMenuItems={this.columnMenuItems} 
            columnMenuOpen={this.columnMenuOpen.bind(this)} 
          > 
            <ColumnsDirective> 
              ... 
            </ColumnsDirective> 
            <Inject 
              services={[   ResizeGroupSort, ColumnMenuFilter,PageAggregate, ]} 
            /> 
          </GridComponent> 
          <DialogComponent 
            id="dialog" 
            width="200px" 
            target="#dialog-target" 
            header="Aggregate" 
            ref={(dialog=> (this.dialogInstance = dialog)} 
            beforeOpen={this.beforeOpen.bind(this)} 
            //beforeOpen={this.beforeOpen = this.beforeOpen.bind(this)} 
            visible={false} 
            height="auto" 
            closeOnEscape={true} 
            buttons={this.buttons} 
          > 
            <div id="dlgContent" className="dialogContent"> 
              <div id="dlgContent1"> 
                <ListViewComponent 
                  id="list1" 
                  ref={(list1=> (this.listObj1 = list1)} 
                  dataSource={this.listData1} 
                  showHeader={true} 
                  headerTitle="Types" 
                  showCheckBox={true} 
                /> 
              </div> 
              <div id="dlgContent2"> 
                <ListViewComponent 
                  id="list2" 
                  ref={(list2=> (this.listObj2 = list2)} 
                  dataSource={this.settings} 
                  showHeader={true} 
                  headerTitle="Columns" 
                  showCheckBox={true} 
                /> 
              </div> 
            </div> 
          </DialogComponent> 
        </div> 
      </div> 
    ); 
  } 
} 
 
render(<ColumnMenuSample />document.getElementById('sample')); 


Screenshot: 
 

Please get back
to us if you need further assistance. 
Regards,
Praveenkumar G 


Loader.
Up arrow icon