DHTMLX Suite 9.3: Advanced Grid Export, New Date Filter, and Other Useful Configuration Options

Today, we are releasing the first update of our JavaScript UI widgets library in 2026. The new DHTMLX Suite 9.3 further extends the configuration capabilities of the Grid component with more flexible export to popular formats, a new date filter type for columns, adjustable drag-and-drop behavior in the TreeMode, and better control over footer positioning.

Other Suite widgets also received useful updates: Tree now supports customizable tooltips for items, while Window allows you to programmatically set the active state of windows.

Download DHTMLX Suite v9.3
Estimate the updated functionality for building modern data-intensive apps
Get free trial

In this blog post, we’ll take a closer look at what’s new in v9.3.

Highly Configurable Grid Export

The DHTMLX JavaScript DataGrid component offers a wide range of configuration options for presenting tabular data on a web page. With Suite 9.3, we set out to bring a similar high level of flexibility to Grid export. And now exporting Grid data has become as configurable as displaying it.

To extend the capabilities of the standard export, you’ll need the new exportConfig property, which is now available in the Grid API. This callback function receives the current Grid configuration (config) and the selected export format (exportType) and returns an export configuration object. The object includes parameters for defining changes that should be reflected in the exported file:

  • columns – column transformations
  • data – filtering or modifying row data
  • spans – cell merging manipulations
  • typeConfig – format-specific settings (filenames, delimiters, themes)
  • Grid properties – any Grid property (set as a key:value pair) that should be modified in the exported file

Now, let us consider the main scenarios of how the exportConfig property helps dynamically change the structure and content of the resulting grid table in CSV, Excel, PDF, and PNG formats using code snippets from this new sample:

  • Data filtering

In practice, it is not always necessary to export all grid data for further usage in different formats. The exportConfig property allows you to decide if specific columns, rows, or spans should not be included in the final export file.

For instance, if grid columns or rows contain confidential or excessive information, you can exclude this kind of data from export files by specifying filter conditions and returning null in the corresponding callback methods.

exportConfig: (config, exportType) => ({
    // Column transformation
    columns: column => {
        // Completely exclude the "experience_level" column from any export
        if (column.id === "experience_level") return null;

        // For spreadsheet formats (Excel/CSV), keep columns as is
        if (exportType === "xlsx" || exportType === "csv") {
            return column;
        }
        // For PDF/PNG, remove HTML templates and uppercase the headers
        column.template = null;
        column.header[0] = column.header[0].text.toUpperCase();

        return column;
    },
    // Row data filtering
    data: row => {
        // Exclude young animals (age <= 3) from the export
        if (row.animal_age <= 3) return null;

        // Business logic example: do not export Dogs to CSV and Cats to Excel
        if (exportType === "csv" && row.animal_type === "Dog") return null;
        if (exportType === "xlsx" && row.animal_type === "Cat") return null;
   
        return row;
    },
       
}),

As you can see from the code above, conditions can be applied to all export formats or to specific ones.

The same approach works for spans:

exportConfig: (config, exportType) => ({
       spans: (span) => {
           // Exclude cells' merges when exporting to CSV,
           // as the CSV format does not support merged cells
           if (exportType === "csv") return null;
           return span;
       }
})
  • Content transformation

The exportConfig property helps you define not only what to display in the exported grid file but also how to do it. That’s how easy you can remove column HTML templates and uppercase headers for PDF and PNG formats, while preserving the original columns’ appearance for Excel and CSV:

// For spreadsheet formats (Excel/CSV), keep columns as is
if (exportType === "xlsx" || exportType === "csv") {
    return column;
}

// For PDF/PNG, remove HTML templates and uppercase the headers
column.template = null;
column.header[0].text = column.header[0].text.toUpperCase();

return column;
},
  • Styling adjustments

Taking advantage of the ability to override any Grid property, you can change the way the Grid table looks in the exported file. Here is how to modify the header height specifically for the Excel file using headerRowHeight:

headerRowHeight: exportType === "xlsx" ? 60 : config.headerRowHeight,
  • Format-specific settings

Using the typeConfig property in the exportConfig configuration object, you can go much further and specify unique settings for specific formats:

const exportConfig = {
   csv: {
       name: "cat_report", // Resulting CSV filename
       rowDelimiter: "\t", // Use Tab as row delimiter
       columnDelimiter: ";" // Use Semicolon as column delimiter
   },
   xlsx: {
       name: "dog_report", // Resulting Excel filename
       tableName: "Main Report", // Sheet name in the Excel workbook
       dateFormatMask: "dd.mm.yyyy" // Excel-specific date format mask
   },
   pdf: {
       theme: "dark", // Apply the dark theme to the PDF document
       scale: 0.8,   // Content scaling (80%)
       format: "A4"  // Page format
   }
};

const grid = new dhx.Grid("grid_container", {
   columns: [
       // columns config
   ],
   data:dataset,
   exportConfig: (config, exportType) => ({
       // Pass settings from our object based on the export type
       typeConfig: exportConfig[exportType]
   })
});

As you can see, the code above adds CSV delimiters, Excel date masks, and a dark theme for PDF.

Overall, the new exportConfig property is a powerful addition to the Grid export API, offering great opportunities to create meaningful reports with only the essential insights from the data table displayed in the UI.

Concluding the topic of data export, we would like to mention that export functions in Grid and Chart components now return a promise of data export.

New Filter Type for Grid Columns

Data filtering is one of the core features for effective data management. That is why our team continues empowering this already robust functionality with valuable enhancements. In v9.3, we’ve extended the list of available filtering options with the new dateFilter type. It allows end-users to filter records by a specific date (single mode) or date ranges (range mode) via a calendar view built with the corresponding Suite widget.

The single mode is used by default, while the range mode can be enabled in the filterConfig object by setting the value of the range parameter to true. Also, there are other configuration parameters for dateFilter, such as date format and placeholder. That’s how to put it all together:

{
   id: "receivedDate",
   minWidth: 200,
   type: "date",
   dateFormat: "%d.%m.%Y",
   header: [
       { text: "Received Date" },
       {
           content: "dateFilter",
           filterConfig: {
               placeholder: "Select date",
               range: true,
           }
        }
    ],
},

Grid with date filterCheck the sample >

If custom logic is needed, it can be applied to any filter type, including dateFilter, by setting the customFilter attribute when configuring the header/footer content of the column. This sample includes custom conditional logic for dateFilter.

Fine-Tuned Drag-and-Drop Behavior in Grid’s TreeGrid Mode

DHTMLX Grid provides a TreeGrid mode that allows presenting data as hierarchical structures and reordering them with drag-and-drop. However, each use case may require different rules for reorganizing hierarchies. To help you address various requests related to the drag-and-drop behavior in TreeGrid mode, we’ve introduced a new configuration option – dropBehaviour.

Inherited from the Tree widget, this new Grid property allows specifying how a dragged item (row) is placed relative to a target item. It offers three modes for dropping dragged items, namely sibling-level reordering, child nesting, and combined (complex) behavior (default option).

const grid = new dhx.Grid("treegrid", {
    type: "tree",
    columns: [
    ...//column configuration
    ],
    data: dataset,
    autoWidth: true,
    dragItem: "both",
    dropBehaviour: "complex" // enables one of the drop modes "child" | "sibling" | "complex" (default)
});

Footer positioningCheck the sample >

With this novelty, you get more precise control over hierarchical structures in the TreeGrid mode.

New Footer Positioning Logic

The updated Grid component provides an extra layout control for footers and bottom-pinned (frozen) rows of the data table. For this purpose, the Grid API now includes the footerPosition property. It offers relative (default value) and bottom values that determine the positioning of the footer and bottom-pinned rows. By default, the footer/frozen row immediately follows the Grid content. After changing the value of footerPosition to bottom, the footer/frozen row stays fixed at the bottom of the container, like in the example below:

Footer positioningCheck the sample >

Regardless of the amount of data in the grid table, footers and frozen rows will be rendered according to the specified setting.

Customizable Tooltips for Tree Items

The Suite’s Tree widget is a reliable tool for building tree-like structures on a web page. Now, you have an opportunity to complement your Tree-based hierarchies with informative tooltips.

The new Suite 9.3 comes with the tooltip property that ensures flexible tooltip configuration for Tree items. To be more specific, this property allows enabling a standard tooltip, defining custom tooltip content with a function, and most interestingly, applying an object configuration for advanced tooltip customization.

While the standard tooltip is clear and predictably displays the value of an item, two other options require clarification with examples.

Here is a function-based approach to defining a tooltip:

const tree = new dhx.Tree("tree_container", {
   tooltip: (item) =>
       (item.value + (item.items ? ` (${item.items?.length})` : "") + "")
});

In this example, the function returns a string that will show the item value and the number of its child items, if they exist. But what if you need to specify not only the tooltip content, but also its behavior and styling?

In this case, you can resort to the object configuration in the tooltip property, providing the ability to flexibly customize the tooltip’s content, appearance, delay, and positioning:

const tree = new dhx.Tree("tree", {
    tooltip: {
        htmlEnable: true,
        // Delay 100ms before showing
        showDelay: 100,
        // The tooltip will appear to the top of the item
        position: "top", // "right" | "bottom" (default) | "center" | "left" | "top"
        // CSS class for styling
        css: "custom-tooltip-style",
        // Template function
        template: (item) => item.items
            ? `<b>${item.value}</b> (${item.items.length})`
            : `<b>${item.value}</b><br/>Size: ${item.size || "N/A"}`
    }
});

Tree with custom tooltip
Check the sample >

Active State Option for Window Widget

If your web application should include multiple overlapping windows on a single page, the Window widget from our Suite is exactly what you need, especially after a useful improvement delivered in v9.3. The novelty lies in the possibility of activating a currently overlapped window and bringing it to the foreground. It is done programmatically via the new setActive() method, the operating principle of which is shown in the basic example with two windows below:

const window1 = new dhx.Window({
   ...windowConfig,
   title: "Window 1",
});

const window2 = new dhx.Window({
   ...windowConfig,
   title: "Window 2",
});

// displaying both windows
window1.show();
window2.show(); // Window 2 is currently on top

// bringing Window 1 to the front without refreshing its content
window1.setActive();

Check the sample >

Thanks to the use of setActive(), you can update the window stacking order without rerendering the content.

That’s all about the updates included in DHTMLX Suite 9.3. The complete list of new features is also available for a quick review in the “What’s New” section of the Suite documentation.

Between the releases of DHTMLX Suite 9.2 and 9.3, our team devoted considerable attention to the question of using Suite widgets and other DHTMLX products with AI technologies. As a result, we created two demo apps – AI Review Analysis and AI Form Builder. They vividly demonstrate how AI can boost the efficiency of tools built with DHTMLX Grid and Form. Moreover, we also launched the DHTMLX MCP server designed to facilitate your experience with the DHTMLX documentation via popular AI assistants.

For those who want to see how new features prove their worth in real-case scenarios, download a free 30-day trial version and get down to testing. Existing customers can access DHTMLX Suite 9.3 from their Client’s Area.

Related Materials

Advance your web development with DHTMLX

Gantt chart
Event calendar
Diagram library
30+ other JS components