showColumnMenu has issues when datasource has only one record or page has only one record

Hi I am having issue with :

    grid = new ej.grids.Grid({

        dataSource: dataSource,

        enableAltRow: true,

        allowPaging: true,

        allowExcelExport: true,

        allowCsvExport: true,

        pageSettings: { pageSize: 12, pageCount: 15 },

        allowSorting: true,

        allowGrouping: true,

        allowFiltering: true,

        gridLines: 'Both',

        allowResizing: true,

        filterSettings: { type: 'Excel' },

        toolbar: ['Search', 'ExcelExport', 'CsvExport'],

        frozenColumns: 0,

        frozenRows: 1,

        allowScrolling: true,

        allowResizing: true,

        allowReordering: true,

        enableHover:false,

        height: 450,

        width:'100%',

        groupSettings: { showGroupedColumn: true },

        showColumnMenu: true,

        showFooter: true,

        columns: [

            { field: 'DebtorsImportId', isPrimaryKey: true, headerText: 'Import Id', width: 160, textAlign: 'Right' },

            { field: 'CustomerNumber', headerText: 'Cust No', width: 140, textAlign: 'Right', allowEditing: false },

            { field: 'CustomerName', headerText: 'Cust Name', width: 140, textAlign: 'Right', allowEditing: false },

            { field: 'InvoiceDate', headerText: 'Inv Date', width: 120, textAlign: 'Right', allowEditing: false, format: 'yyyy-MM-dd', type: 'date' },

            { field: 'DocNumber', headerText: 'Doc No', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'OpenAmount', headerText: 'Open Amount', width: 220, textAlign: 'Right', allowEditing: false },

            { field: 'Invoice', headerText: 'Invoice Amount', width: 220, textAlign: 'Right', allowEditing: false },

            { field: 'POorDocRef', headerText: 'PO/Doc Ref', width: 140, textAlign: 'Right', allowEditing: false },

            { field: 'TransactionDescription', headerText: 'Trans Desc', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'CreditClerkCode', headerText: 'Cr Clerk Code', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'ControllerEmail', headerText: 'Controller Email', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'ClerkActive', headerText: 'Clerk Active', width: 120, textAlign: 'Right',editType: 'booleanedit', type: 'boolean', allowEditing: false },

            { field: 'CustomerEmail', headerText: 'Customer Email', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'CustomerActive', headerText: 'Customer Active', width: 120, textAlign: 'Right',editType: 'booleanedit', type: 'boolean', allowEditing: false },

            { field: 'Franchise', headerText: 'Franchise', width: 120, textAlign: 'Right',editType: 'booleanedit', type: 'boolean', allowEditing: false },

            { field: 'HeadCorpCode', headerText: 'Head Corp Code', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'StoreNo', headerText: 'Store No', width: 120, textAlign: 'Right', allowEditing: false },

            { field: 'Hash', headerText: 'Hash', width: 120, textAlign: 'Right', allowEditing: false,visible:false },

            {

                field: 'ProcessedDate',

                headerText: 'Proc Date',

                width: 120, allowEditing: false, format: 'yyyy-MM-dd',

                textAlign: 'Right',

                filter: {

                    operator: 'equal', // Use the appropriate operator

                    type: 'Excel' // You can also use 'Excel' for an Excel-style filter

                }, /* type: 'date', */

                valueAccessor: (field, data) => {

                    // Log the full data object in a readable format

                    console.log('Data Object:', JSON.stringify(data, null, 2)); // Properly format the data object


                    let processedDate = data.processedDate; // Make sure this field exists in the data


                    if (processedDate === "0001-01-01T00:00:00") {


                       return 'Not Processed';

                    }


                    if (!processedDate || processedDate === '0001-01-01T00:00:00' || isNaN(Date.parse(processedDate))) {

                        return 'Not Processed'; // Display 'Test' if the date is not valid

                    }


                    let date = new Date(processedDate);

                    return date.getFullYear() + '-' +

                        ('0' + (date.getMonth() + 1)).slice(-2) + '-' +

                        ('0' + date.getDate()).slice(-2); // Format date to 'YYYY-MM-DD'

                }

            },



            { field: 'Processed', headerText: 'Processed', width: 150, textAlign: 'Right', allowEditing: false },

            {

                field: 'Reason', headerText: 'Reason', width: 120,textAlign: 'Right', editType: 'dropdownedit', edit: {

                    create: function () {

                        return document.createElement('input');

                    },

                    read: function (args) {

                        if (args && args.ej2_instances && args.ej2_instances[0]) {

                            return args.ej2_instances[0].value;

                        } else {

                            return null;

                        }

                    },

                    destroy: function (args) {

                        if (args && args.ej2_instances && args.ej2_instances[0]) {

                            args.ej2_instances[0].destroy();

                        }

                    },

                    write: function (args) {

                        if (args) {

                            var dropDownList = new ej.dropdowns.DropDownList({

                                dataSource: reasonsData,

                                fields: { text: 'text', value: 'value' },

                                value: args.rowData[args.column.field],

                                floatLabelType: 'Always',

                                placeholder: 'Select a reason',

                                validationRules: { required: true }

                            });

                            dropDownList.appendTo(args.element);

                        }

                    }

                }

            },

            { field: 'CustomerPayFull', headerText: 'Pay Full', width: 120, textAlign: 'Right', editType: 'booleanedit', type: 'boolean' },

            { field: 'CustomerPartPay', headerText: 'Pay Partial', textAlign: 'Right', width: 120, editType: 'booleanedit', type: 'boolean' },

            {

                field: 'CustomerRValue', headerText: 'Rand Value', width: 120, textAlign: 'Right',editType: 'numericedit',

                type: 'number', format: 'R0,0.00', edit: {

                    params: { decimals: 2, format: 'n2' }

                }

            },

            { field: 'CustomerUploadFile', headerText: 'Upload File', width: 140, textAlign: 'Right',editType: 'booleanedit', type: 'boolean' },

            { field: 'CustomerNotes', headerText: 'Notes', width: 120, editType: 'stringedit', type: 'string', textAlign: 'Right' }

         ],


         aggregates: [{

        columns: [

        {

            type: 'Custom',

            customAggregate: function (data) {

                var allData = grid.dataSource instanceof ej.data.DataManager

                    ? grid.dataSource.dataSource.json

                    : grid.dataSource;


                if (!Array.isArray(allData)) {

                    console.error('Expected allData to be an array, but got:', allData);

                    return 0;

                }


                return allData.reduce((total, record) => total + record.openAmount, 0);

            },

            field: 'OpenAmount',

            footerTemplate: function (data) {

                return 'Total: R' + data.Custom.toFixed(2);

            }

        },

        {

            type: 'Custom',

            customAggregate: function (data) {

                var allData = grid.dataSource instanceof ej.data.DataManager

                    ? grid.dataSource.dataSource.json

                    : grid.dataSource;


                if (!Array.isArray(allData)) {

                    console.error('Expected allData to be an array, but got:', allData);

                    return 0;

                }


                return allData.reduce((total, record) => total + record.invoice, 0);

            },

            field: 'Invoice',

            width: 'auto',

            textAlign: 'Right',

            footerTemplate: function (data) {

                return 'Total: R' + data.Custom.toFixed(2);

            }

        },

        {

            type: 'Sum',

            field: 'CustomerRValue',

            width: 'auto',

            textAlign: 'Right',

            groupFooterTemplate: function (data) {

                return 'Total: R' + data.Sum.toFixed(2);

            }

        }

    ]

}],

        toolbarClick: function (args) {

            if (args.item.id === 'Grid_excelexport') {

                grid.excelExport();

            }

            if (args.item.id === 'Grid_csvexport') {

                grid.csvExport();

            }

        },

        dataBound: function () {

                //console.log('Grid data bound:', grid.dataSource);


                // Set showColumnMenu and allowGrouping based on the number of rows displayed

            if (grid.dataSource) {

                    updateGridSettings(grid.pageSettings.pageSize, grid.pageSettings.currentPage);

            }

        }


    });


    grid.appendTo('#Grid');

}


function updateGridSettings(pageSize, currentPage) {

const startIndex = (currentPage - 1) * pageSize;

const endIndex = startIndex + pageSize;

const currentPageRows = grid.dataSource.slice(startIndex, endIndex);


if (currentPageRows.length <= 1) {

    grid.showColumnMenu = false;

    grid.allowGrouping = false;


} else {

    grid.showColumnMenu = true;

    grid.allowGrouping = true;


}

If I select Autofit all columns on a page that has only one row then I get error :

Uncaught TypeError: Cannot read properties of null (reading 'className')

    at aG.createTable (ej2.min.js:10:3710011)

    at aG.resizeColumn (ej2.min.js:10:3707426)

    at aG.findColumn (ej2.min.js:10:3709168)

    at aG.autoFitColumns (ej2.min.js:10:3705023)

    at aG.autoFit (ej2.min.js:10:3705272)

    at Le.notify (ej2.min.js:10:35422)

    at Ui.notify (ej2.min.js:10:153141)

    at ej2.min.js:10:1233627

    at ej2.min.js:10:1662828


1 Reply

PS Pavithra Subramaniyam Syncfusion Team December 13, 2024 01:40 PM UTC

Hi Edmund Herbert,


The reported issue arises when the Grid contains only one row, and the frozen rows property is enabled. Since setting the frozen rows property in this scenario is not valid, we recommend dynamically adding or removing frozen rows based on the number of rows in the Grid to resolve the issue. For further details, please refer to the code example below.


var frozenRows = 1;

function dataBound(args) {

  grid.frozenRows = grid.currentViewData.length == 1 ? null : frozenRows;

}


Sample: Tqtdqtue (forked) - StackBlitz


Please get back to us if you need further assistance.


Regards,

Pavithra S


Loader.
Up arrow icon