From 84453a14b197623f55275fef72763e082713f4ba Mon Sep 17 00:00:00 2001 From: Masha_Rudenko Date: Wed, 16 Sep 2026 17:10:00 +0300 Subject: [PATCH 1/3] [add] HTML content in a Layout cell header - header config extended with a callback returning an HTML string or a widget - API page migrated to Usage/Example sections with the ts signature - guide section with subsections on markup, widgets, events and collapsing - v9.4 changelog entry, new snippets and readable related links --- .../api/cell/layout_cell_header_config.md | 87 +++++++++++++++++-- docs/layout/cell_configuration.md | 85 ++++++++++++++++++ docs/layout/features.md | 1 + 3 files changed, 166 insertions(+), 7 deletions(-) diff --git a/docs/layout/api/cell/layout_cell_header_config.md b/docs/layout/api/cell/layout_cell_header_config.md index ca44dd1c..9f0aaf78 100644 --- a/docs/layout/api/cell/layout_cell_header_config.md +++ b/docs/layout/api/cell/layout_cell_header_config.md @@ -6,21 +6,94 @@ description: You can explore the header config of Layout in the documentation of # header -@short: Optional. Adds a header with text for a cell +@short: Optional. Adds a header with a text or with custom content for a cell -@signature: {'header?: string;'} +#### Usage -@example: +~~~ts +type TCellHeaderTemplate = (cell: ICellConfig) => string | IView; + +header?: string | TCellHeaderTemplate; +~~~ + +The callback function takes the following parameter: + +- `cell: ICellConfig` - the configuration object of the cell the header belongs to + +The type of the value defines the way the component renders the content of a header: + +- **a string** - the header shows the text as is. The component doesn't interpret HTML tags and displays them as a part of the text +- **a callback function** - the way to render HTML content in a header. The component calls the callback while it renders the cell and places the returned value into the DOM of the header: + - *a string with HTML markup* - the component parses the markup and renders it + - *an object of a DHTMLX widget* - an initialized widget, the same object that you pass to the [`attach()`](layout/api/cell/layout_cell_attach_method.md) method of a cell. The name of a component doesn't work here, as the header treats any returned string as HTML + +#### Example + +- a header with a text + +~~~jsx +const layout = new dhx.Layout("layout_container", { + cols: [ + { header: "Cell header" } + ] +}); +~~~ + +- a header with HTML content + +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ - { header: "Cell header"} + { + id: "orders", + header: cell => `Orders 3 new` + } ] }); +~~~ + +- a header with a DHTMLX widget inside + +~~~jsx +const toolbar = new dhx.Toolbar(null, { + data: [ + { id: "add", type: "button", value: "Add", icon: "dxi dxi-plus" } + ] +}); + +const layout = new dhx.Layout("layout_container", { + cols: [ + { header: () => toolbar } + ] +}); +~~~ @descr: -**Related sample**: [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) -[comment]: # (@relatedapi: layout/api/cell/layout_cell_headerheight_config.md layout/api/cell/layout_cell_headericon_config.md layout/api/cell/layout_cell_headerimage_config.md) +A *header with custom content* has the following specifics: + +- **events**: to handle clicks and other DOM events of the markup returned by the callback, use the [`on`](layout/api/cell/layout_cell_on_config.md) property of the cell with the selector of the necessary element +- **icon and image**: the [`headerIcon`](layout/api/cell/layout_cell_headericon_config.md) and [`headerImage`](layout/api/cell/layout_cell_headerimage_config.md) options work as well. The cell renders the icon and the image before the content that the callback returns +- **height**: the height of a header adjusts to the size of the custom content. The [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) option sets a fixed height for it +- **collapsing**: a [`collapsable`](layout/api/cell/layout_cell_collapsable_config.md) cell shows the collapse/expand icon in a header of any type. A click on the custom content of a header calls no API of the cell, so controls inside the header remain operable. A user collapses and expands the cell by clicking the collapse icon or the free space of the header + +@changelog: the ability to set the property as a callback function was added in v9.4 + +**Related samples**: +- [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) +- [Layout. HTML content in a cell header](https://snippet.dhtmlx.com/lromzzkx) +- [Layout. Toolbar in a cell header](https://snippet.dhtmlx.com/iyci7xt2?mode=wide) +- [Layout. Custom cell headers in a dashboard](https://snippet.dhtmlx.com/awwc1m4u?mode=wide) + +**Related API**: +- [`attach()`](layout/api/cell/layout_cell_attach_method.md) +- [`on`](layout/api/cell/layout_cell_on_config.md) +- [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) +- [`headerIcon`](layout/api/cell/layout_cell_headericon_config.md) +- [`headerImage`](layout/api/cell/layout_cell_headerimage_config.md) -[comment]: # (@related: layout/initialization.md#initialize-layout layout/cell_configuration.md#height-of-a-header-cell) +**Related articles**: +- [Layout initialization](layout/initialization.md#initialize-layout) +- [Custom content in a cell header](layout/cell_configuration.md#custom-content-in-a-cell-header) +- [Height of a header cell](layout/cell_configuration.md#height-of-a-header-cell) diff --git a/docs/layout/cell_configuration.md b/docs/layout/cell_configuration.md index bf890d15..e0f29e3d 100644 --- a/docs/layout/cell_configuration.md +++ b/docs/layout/cell_configuration.md @@ -63,6 +63,91 @@ const layout = new dhx.Layout("layout_container", { **Related sample**: [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) +## Custom content in a cell header + +Besides a text, the header of a cell can contain HTML markup or a DHTMLX widget. For this purpose, set the [`header`](layout/api/cell/layout_cell_header_config.md) property to a callback function. The component calls the function while it renders the cell. The function takes the configuration object of the cell as a parameter and returns the content for the header. + +The type of the value that you set for the `header` property defines the expected behavior: + +- a string always goes to the header as a plain text, with HTML tags displayed as a part of it +- a callback function tells the component that the header supports HTML content + +### HTML markup in a header + +To render HTML markup in a header, return a string with the necessary tags from the callback: + +~~~jsx +const layout = new dhx.Layout("layout_container", { + cols: [ + { + id: "orders", + header: cell => `Orders 3 new` + } + ] +}); +~~~ + +### A DHTMLX widget in a header + +To render a DHTMLX component in a header, return an initialized widget, the same object that you pass to the [`attach()`](layout/api/cell/layout_cell_attach_method.md) method of a cell. The name of a component doesn't work here, as the header treats any returned string as HTML: + +~~~jsx +const toolbar = new dhx.Toolbar(null, { + data: [ + { id: "add", type: "button", value: "Add", icon: "dxi dxi-plus" }, + { id: "remove", type: "button", value: "Remove", icon: "dxi dxi-delete" } + ] +}); + +const layout = new dhx.Layout("layout_container", { + cols: [ + { header: () => toolbar } + ] +}); +~~~ + +### Events of the header content + +To handle clicks and other DOM events of the markup that the callback returns, use the [`on`](layout/api/cell/layout_cell_on_config.md) property of the cell with the selector of the necessary element. + +The example below shows how to make a control inside a custom cell header interactive. The `header` callback returns markup with a "Check now" button, and a click on that button rebuilds the content of the cell: + +~~~jsx +// builds the HTML content of the cell +function metrics() { + return `
Checked at ${new Date().toLocaleTimeString()}
`; +} + +const layout = new dhx.Layout("layout_container", { + rows: [ + { + id: "service", + html: metrics(), + header: () => `API service + `, + on: { + click: { + "button": function() { + layout.getCell("service").attachHTML(metrics()); + } + } + } + } + ] +}); +~~~ + +The [`attachHTML()`](layout/api/cell/layout_cell_attachhtml_method.md) call repaints the cell, so the component calls the `header` callback again and renders the header with the current data as well. + +### Collapsing a cell with a custom header + +A [`collapsable`](layout/api/cell/layout_cell_collapsable_config.md) cell keeps its collapse/expand icon when the header contains custom content. A click on the custom content itself calls no API of the cell, so buttons and other controls inside the header remain operable. A user collapses and expands the cell by clicking the collapse icon or the free space of the header. + +**Related samples**: +- [Layout. HTML content in a cell header](https://snippet.dhtmlx.com/lromzzkx) +- [Layout. Toolbar in a cell header](https://snippet.dhtmlx.com/iyci7xt2?mode=wide) +- [Layout. Custom cell headers in a dashboard](https://snippet.dhtmlx.com/awwc1m4u?mode=wide) + ## Height of a header cell You can specify the necessary height of the header of a cell using the [](layout/api/cell/layout_cell_headerheight_config.md) configuration option of the cell: diff --git a/docs/layout/features.md b/docs/layout/features.md index 1a6378be..67045335 100644 --- a/docs/layout/features.md +++ b/docs/layout/features.md @@ -47,6 +47,7 @@ In this section you can find out how to configure the size and visibility of cel | [Making a cell resizable](layout/cell_configuration.md#resizability) | Learn how to configure the ability to change the size of a cell by dragging its borders ([Example](https://snippet.dhtmlx.com/f1f49n35)) | | [Making cells hidden](layout/cell_configuration.md#hidden-cell) | Learn how to render a layout with some hidden cells | | [Adding the header to a cell](layout/cell_configuration.md#cell-header) | Learn how to add a header for a cell ([Example](https://snippet.dhtmlx.com/bxqnzesl)) | +| [Adding custom content to a cell header](layout/cell_configuration.md#custom-content-in-a-cell-header) | Learn how to render HTML markup or a DHTMLX widget in the header of a cell ([Example](https://snippet.dhtmlx.com/lromzzkx)) | | [Configuring content alignment](layout/api/cell/layout_cell_align_config.md) | Learn how to set the alignment of content inside a cell ([Example](https://snippet.dhtmlx.com/4w1033c9)) | | [Configuring paddings](layout/api/cell/layout_cell_padding_config.md) | Learn how to configure the distance between a cell and the Layout border ([Example](https://snippet.dhtmlx.com/tk6tpwwv)) | | [Initializing a collapsed cell](layout/cell_configuration.md#collapsibility) | Learn how to initialize a collapsed cell and provide the ability to expand it ([Example 1](https://snippet.dhtmlx.com/f1f49n35), [Example 2](https://snippet.dhtmlx.com/r2e0y6n7)) | From 27cf5187f53a5872176181bf5231942a3e3e02aa Mon Sep 17 00:00:00 2001 From: Masha_Rudenko Date: Thu, 17 Sep 2026 12:13:11 +0300 Subject: [PATCH 2/3] [update] restructure the cell configuration guide - intro paragraph, header height nested under the cell header section - sizing, visibility and collapsing sections regrouped - custom header collapsing moved to the collapsibility section - explicit backticked labels for api links, jsx fences on the page - readable related links on the headerIcon and headerImage pages, with the broken layout/api paths and the #cellheader anchor fixed - header page: callback parameter described in its own list item, examples split per case, attach() added to the related api list --- .../api/cell/layout_cell_header_config.md | 13 +- .../api/cell/layout_cell_headericon_config.md | 11 +- .../cell/layout_cell_headerimage_config.md | 9 +- docs/layout/cell_configuration.md | 172 ++++++++++-------- 4 files changed, 114 insertions(+), 91 deletions(-) diff --git a/docs/layout/api/cell/layout_cell_header_config.md b/docs/layout/api/cell/layout_cell_header_config.md index 9f0aaf78..f9711791 100644 --- a/docs/layout/api/cell/layout_cell_header_config.md +++ b/docs/layout/api/cell/layout_cell_header_config.md @@ -16,17 +16,18 @@ type TCellHeaderTemplate = (cell: ICellConfig) => string | IView; header?: string | TCellHeaderTemplate; ~~~ -The callback function takes the following parameter: +The type of the value defines the way the component renders the content of a header: -- `cell: ICellConfig` - the configuration object of the cell the header belongs to +- **a string** - defines the text the header shows. The component doesn't interpret HTML tags and displays them as a part of the text +- **a callback function** - defines the way to render HTML content in a header. It takes the following parameter: -The type of the value defines the way the component renders the content of a header: + - `cell: ICellConfig` - the configuration object of the cell the header belongs to + + The component calls the callback while it renders the cell and places the returned value into the DOM of the header: -- **a string** - the header shows the text as is. The component doesn't interpret HTML tags and displays them as a part of the text -- **a callback function** - the way to render HTML content in a header. The component calls the callback while it renders the cell and places the returned value into the DOM of the header: - *a string with HTML markup* - the component parses the markup and renders it - *an object of a DHTMLX widget* - an initialized widget, the same object that you pass to the [`attach()`](layout/api/cell/layout_cell_attach_method.md) method of a cell. The name of a component doesn't work here, as the header treats any returned string as HTML - + #### Example - a header with a text diff --git a/docs/layout/api/cell/layout_cell_headericon_config.md b/docs/layout/api/cell/layout_cell_headericon_config.md index 4e0953e8..47799ed9 100644 --- a/docs/layout/api/cell/layout_cell_headericon_config.md +++ b/docs/layout/api/cell/layout_cell_headericon_config.md @@ -21,6 +21,11 @@ const layout = new dhx.Layout("layout_container", { **Related sample**: [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) -[comment]: # (@related: layout/initialization.md#initialize-layout layout/cell_configuration.md#cellheader) - -[comment]: # (@relatedapi: layout/api/layout_header_config.md layout/api/layout_headerheight_config.md layout/api/layout_headerimage_config.md) +**Related API**: +- [`header`](layout/api/cell/layout_cell_header_config.md) +- [`headerImage`](layout/api/cell/layout_cell_headerimage_config.md) +- [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) + +**Related articles**: +- [Layout initialization](layout/initialization.md#initialize-layout) +- [Cell header](layout/cell_configuration.md#cell-header) diff --git a/docs/layout/api/cell/layout_cell_headerimage_config.md b/docs/layout/api/cell/layout_cell_headerimage_config.md index 2a57255b..49e97186 100644 --- a/docs/layout/api/cell/layout_cell_headerimage_config.md +++ b/docs/layout/api/cell/layout_cell_headerimage_config.md @@ -19,6 +19,11 @@ const layout = new dhx.Layout("layout_container", { @descr: -[comment]: # (@related: layout/initialization.md#initialize-layout layout/cell_configuration.md#cellheader) +**Related API**: +- [`header`](layout/api/cell/layout_cell_header_config.md) +- [`headerIcon`](layout/api/cell/layout_cell_headericon_config.md) +- [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) -[comment]: # (@relatedapi: layout/api/layout_header_config.md layout/api/layout_headerheight_config.md layout/api/layout_headericon_config.md) +**Related articles**: +- [Layout initialization](layout/initialization.md#initialize-layout) +- [Cell header](layout/cell_configuration.md#cell-header) diff --git a/docs/layout/cell_configuration.md b/docs/layout/cell_configuration.md index e0f29e3d..9794becb 100644 --- a/docs/layout/cell_configuration.md +++ b/docs/layout/cell_configuration.md @@ -6,11 +6,13 @@ description: You can explore the configuration of a Cell of Layout in the docume # Configuration of a Cell +Each cell of a layout takes a configuration object that defines what the cell shows and how it behaves. The properties of this object set the content and the header of a cell, its size and borders, and the ability of a user to collapse, hide or resize the cell. The sections below go through these settings one by one, while the full list of the available properties is in the [Cell API](layout/api/api_overview.md#cell-api) overview. + ## HTML content -A layout cell can have any HTML content inside it. You can set it with the [](layout/api/cell/layout_cell_html_config.md) attribute in the object of a cell. +A layout cell can have any HTML content inside it. You can set it with the [`html`](layout/api/cell/layout_cell_html_config.md) attribute in the object of a cell. -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ { header: "Cell header", html: "Hello world"} @@ -20,23 +22,11 @@ const layout = new dhx.Layout("layout_container", { **Related sample**: [Layout. HTML content](https://snippet.dhtmlx.com/6x76kgyq) -## Hidden cell - -It is possible to add the [](layout/api/cell/layout_cell_hidden_config.md) attribute into the the object of a cell(s) to render a layout with some cells hidden: - -~~~js -const layout = new dhx.Layout("layout_container", { - cols: [ - { header: "Cell header", hidden:true} - ] -}); -~~~ - ## Cell header Each layout cell can have a header with some text that describes the content of this cell. -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ { header: "Perfect cell header"} @@ -44,9 +34,9 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ -You can also add an icon or an image into the header of a cell with the help of corresponding attributes - [](layout/api/cell/layout_cell_headericon_config.md) and [](layout/api/cell/layout_cell_headerimage_config.md). +You can also add an icon or an image into the header of a cell with the help of corresponding attributes - [`headerIcon`](layout/api/cell/layout_cell_headericon_config.md) and [`headerImage`](layout/api/cell/layout_cell_headerimage_config.md). -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ { header: "Cell header", headerIcon:"/icon.png"} @@ -63,14 +53,39 @@ const layout = new dhx.Layout("layout_container", { **Related sample**: [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) +### Height of a header cell + +You can specify the necessary height of the header of a cell using the [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) configuration option of the cell: + +~~~jsx +const layout = new dhx.Layout("layout_container", { + rows: [ + { + id: "row1" + }, + { + id: "row2", + header: "Row 2", + headerHeight: 80 + } + ] +}); +~~~ + +**Related sample**: [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) + +If the [`header`](layout/api/cell/layout_cell_header_config.md) property is not set in the config of a cell, the [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) option will add a header without text for a cell. + ## Custom content in a cell header Besides a text, the header of a cell can contain HTML markup or a DHTMLX widget. For this purpose, set the [`header`](layout/api/cell/layout_cell_header_config.md) property to a callback function. The component calls the function while it renders the cell. The function takes the configuration object of the cell as a parameter and returns the content for the header. The type of the value that you set for the `header` property defines the expected behavior: -- a string always goes to the header as a plain text, with HTML tags displayed as a part of it -- a callback function tells the component that the header supports HTML content +- *a string*: the header shows it as plain text, and the component doesn't interpret HTML tags, it displays them as part of the text +- *a callback function*: tells the component that the header supports HTML content + +A cell with a custom header collapses and expands as any other cell, see the [Collapsibility](layout/cell_configuration.md#collapsibility) section. ### HTML markup in a header @@ -87,6 +102,8 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ +**Related sample**: [Layout. HTML content in a cell header](https://snippet.dhtmlx.com/lromzzkx) + ### A DHTMLX widget in a header To render a DHTMLX component in a header, return an initialized widget, the same object that you pass to the [`attach()`](layout/api/cell/layout_cell_attach_method.md) method of a cell. The name of a component doesn't work here, as the header treats any returned string as HTML: @@ -106,6 +123,16 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ +**Related samples**: +- [Layout. Toolbar in a cell header](https://snippet.dhtmlx.com/iyci7xt2?mode=wide) +- [Layout. Custom cell headers in a dashboard](https://snippet.dhtmlx.com/awwc1m4u?mode=wide) + +### Icon, image and height of a custom header + +The [`headerIcon`](layout/api/cell/layout_cell_headericon_config.md) and [`headerImage`](layout/api/cell/layout_cell_headerimage_config.md) options work with a custom header as well. The cell renders the icon and the image before the content that the callback returns. + +The height of a header adjusts to the size of the custom content. To use a fixed height, set the [`headerHeight`](layout/api/cell/layout_cell_headerheight_config.md) option. + ### Events of the header content To handle clicks and other DOM events of the markup that the callback returns, use the [`on`](layout/api/cell/layout_cell_on_config.md) property of the cell with the selector of the necessary element. @@ -139,43 +166,13 @@ const layout = new dhx.Layout("layout_container", { The [`attachHTML()`](layout/api/cell/layout_cell_attachhtml_method.md) call repaints the cell, so the component calls the `header` callback again and renders the header with the current data as well. -### Collapsing a cell with a custom header - -A [`collapsable`](layout/api/cell/layout_cell_collapsable_config.md) cell keeps its collapse/expand icon when the header contains custom content. A click on the custom content itself calls no API of the cell, so buttons and other controls inside the header remain operable. A user collapses and expands the cell by clicking the collapse icon or the free space of the header. - -**Related samples**: -- [Layout. HTML content in a cell header](https://snippet.dhtmlx.com/lromzzkx) -- [Layout. Toolbar in a cell header](https://snippet.dhtmlx.com/iyci7xt2?mode=wide) -- [Layout. Custom cell headers in a dashboard](https://snippet.dhtmlx.com/awwc1m4u?mode=wide) - -## Height of a header cell - -You can specify the necessary height of the header of a cell using the [](layout/api/cell/layout_cell_headerheight_config.md) configuration option of the cell: - -~~~js -const layout = new dhx.Layout("layout_container", { - rows: [ - { - id: "row1" - }, - { - id: "row2", - header: "Row 2", - headerHeight: 80 - } - ] -}); -~~~ - -**Related sample**: [Layout. Header](https://snippet.dhtmlx.com/bxqnzesl) - -If the [](layout/api/cell/layout_cell_header_config.md) property is not set in the config of a cell, the [](layout/api/cell/layout_cell_headerheight_config.md) option will add a header without text for a cell. +**Related sample**: [Layout. HTML content in a cell header](https://snippet.dhtmlx.com/lromzzkx) ## Cell size -You can easily control and change the size of a cell via the [](layout/api/cell/layout_cell_width_config.md) and [](layout/api/cell/layout_cell_height_config.md) attributes of the object of a cell. +You can easily control and change the size of a cell via the [`width`](layout/api/cell/layout_cell_width_config.md) and [`height`](layout/api/cell/layout_cell_height_config.md) attributes of the object of a cell. -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { rows: [ { @@ -206,9 +203,9 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ -Starting from v7.0, you can define the maximal and minimal sizes for a cell by using its corresponding configuration properties: [](layout/api/cell/layout_cell_maxheight_config.md), [](layout/api/cell/layout_cell_maxwidth_config.md), [](layout/api/cell/layout_cell_minheight_config.md), [](layout/api/cell/layout_cell_minwidth_config.md). +Starting from v7.0, you can define the maximal and minimal sizes for a cell by using its corresponding configuration properties: [`maxHeight`](layout/api/cell/layout_cell_maxheight_config.md), [`maxWidth`](layout/api/cell/layout_cell_maxwidth_config.md), [`minHeight`](layout/api/cell/layout_cell_minheight_config.md), [`minWidth`](layout/api/cell/layout_cell_minwidth_config.md). -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ { @@ -222,9 +219,9 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ -{{note Note, that [minWidth](layout/api/cell/layout_cell_minwidth_config.md)/[maxWidth](layout/api/cell/layout_cell_maxwidth_config.md) properties prevent [the width of a cell](layout/api/cell/layout_cell_width_config.md) from being less/greater than minWidth/maxWidth values accordingly. The [minHeight](layout/api/cell/layout_cell_minheight_config.md)/[maxHeight](layout/api/cell/layout_cell_maxheight_config.md) options work in the same way. }} +{{note Note, that [`minWidth`](layout/api/cell/layout_cell_minwidth_config.md)/[`maxWidth`](layout/api/cell/layout_cell_maxwidth_config.md) properties prevent [the width of a cell](layout/api/cell/layout_cell_width_config.md) from being less/greater than minWidth/maxWidth values accordingly. The [`minHeight`](layout/api/cell/layout_cell_minheight_config.md)/[`maxHeight`](layout/api/cell/layout_cell_maxheight_config.md) options work in the same way. }} -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ { @@ -240,7 +237,7 @@ As you can see from the code example above, the width of the cell occupies 50% o ### Autosize for cells -Starting with v7.0, you can configure a cell so that its width/ height would automatically adjust to the width/ height of the cell content. For this purpose, you need to set the [width](layout/api/cell/layout_cell_width_config.md)/ [height](layout/api/cell/layout_cell_height_config.md) options to *"content"*: +Starting with v7.0, you can configure a cell so that its width/ height would automatically adjust to the width/ height of the cell content. For this purpose, you need to set the [`width`](layout/api/cell/layout_cell_width_config.md)/ [`height`](layout/api/cell/layout_cell_height_config.md) options to *"content"*: ~~~js {5} const layout = new dhx.Layout("layout_container", { @@ -254,12 +251,40 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ +## Resizability + +To allow resizing of a cell, make use of the [`resizable`](layout/api/cell/layout_cell_resizable_config.md) option in the object of a cell. + +~~~jsx +const layout = new dhx.Layout("layout_container", { + cols: [ + { header: "Cell header", resizable:true} + ] +}); +~~~ + +**Related sample**: [Layout. Collapsable and resizable](https://snippet.dhtmlx.com/f1f49n35) + +{{note Starting from v7.0, you can define the resizing limits by setting necessary values to the [`minWidth`](layout/api/cell/layout_cell_minwidth_config.md)/[`maxWidth`](layout/api/cell/layout_cell_maxwidth_config.md), [`minHeight`](layout/api/cell/layout_cell_minheight_config.md)/[`maxHeight`](layout/api/cell/layout_cell_maxheight_config.md) properties in the config of a cell.}} + +## Hidden cell + +It is possible to add the [`hidden`](layout/api/cell/layout_cell_hidden_config.md) attribute into the the object of a cell(s) to render a layout with some cells hidden: + +~~~jsx +const layout = new dhx.Layout("layout_container", { + cols: [ + { header: "Cell header", hidden:true} + ] +}); +~~~ + ## Collapsibility -There are two attributes of the object of a cell: [](layout/api/cell/layout_cell_collapsable_config.md) and [](layout/api/cell/layout_cell_collapsed_config.md). The first one defines whether a cell can be collapsed and expanded, and the second one checks whether a cell is collapsed during +There are two attributes of the object of a cell: [`collapsable`](layout/api/cell/layout_cell_collapsable_config.md) and [`collapsed`](layout/api/cell/layout_cell_collapsed_config.md). The first one defines whether a cell can be collapsed and expanded, and the second one checks whether a cell is collapsed during the initialization of a layout. -~~~js +~~~jsx const layout = new dhx.Layout("layout_container", { cols: [ { header: "Cell header", collapsable:true, collapsed:false} @@ -267,13 +292,16 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ -**Related sample**: [Layout. Collapsable and resizable](https://snippet.dhtmlx.com/f1f49n35) +A [`collapsable`](layout/api/cell/layout_cell_collapsable_config.md) cell keeps its collapse/expand icon when the header contains custom content. A click on the custom content itself calls no API of the cell, so buttons and other controls inside the header remain operable. A user collapses and expands the cell by clicking the collapse icon or the free space of the header. -**Related sample**: [Layout. Accordion](https://snippet.dhtmlx.com/r2e0y6n7) +**Related samples**: +- [Layout. Collapsable and resizable](https://snippet.dhtmlx.com/f1f49n35) +- [Layout. Accordion](https://snippet.dhtmlx.com/r2e0y6n7) +- [Layout. Toolbar in a cell header](https://snippet.dhtmlx.com/iyci7xt2?mode=wide) ## Progress bar -You can configure a Layout cell so that it would render a progress bar (in other words, a loading spinner) if there is no any component or HTML content attached to the cell. To do that, enable the [progressDefault](layout/api/cell/layout_cell_progressdefault_config.md) attribute in the configuration object of the cell: +You can configure a Layout cell so that it would render a progress bar (in other words, a loading spinner) if there is no any component or HTML content attached to the cell. To do that, enable the [`progressDefault`](layout/api/cell/layout_cell_progressdefault_config.md) attribute in the configuration object of the cell: ~~~js {9,14} const layout = new dhx.Layout("layout_container", { @@ -297,27 +325,11 @@ const layout = new dhx.Layout("layout_container", { Note, as soon as you attach a component or HTML content to the cell, the progress bar will be hidden. -By default, the [progressDefault](layout/api/cell/layout_cell_progressdefault_config.md) attribute is disabled. - -## Resizability - -To allow resizing of a cell, make use of the [](layout/api/cell/layout_cell_resizable_config.md) option in the object of a cell. - -~~~js -const layout = new dhx.Layout("layout_container", { - cols: [ - { header: "Cell header", resizable:true} - ] -}); -~~~ - -**Related sample**: [Layout. Collapsable and resizable](https://snippet.dhtmlx.com/f1f49n35) - -{{note Starting from v7.0, you can define the resizing limits by setting necessary values to the [minWidth](layout/api/cell/layout_cell_minwidth_config.md)/[maxWidth](layout/api/cell/layout_cell_maxwidth_config.md), [minHeight](layout/api/cell/layout_cell_minheight_config.md)/[maxHeight](layout/api/cell/layout_cell_maxheight_config.md) properties in the config of a cell.}} +By default, the [`progressDefault`](layout/api/cell/layout_cell_progressdefault_config.md) attribute is disabled. ## Setting borders for cells -By default, there is no space and borders between cells inside a layout and the cells look like they are merged. Starting from v7.0, it is possible to split the cells by adding borders or space between them via the [](layout/api/cell/layout_cell_type_config.md) configuration property of a Layout cell: +By default, there is no space and borders between cells inside a layout and the cells look like they are merged. Starting from v7.0, it is possible to split the cells by adding borders or space between them via the [`type`](layout/api/cell/layout_cell_type_config.md) configuration property of a Layout cell: ~~~js {2} const layout = new dhx.Layout("layout_container", { From c03db97ea382ebc6bed96ec5499df539a5c395ec Mon Sep 17 00:00:00 2001 From: Masha_Rudenko Date: Tue, 29 Sep 2026 14:50:15 +0300 Subject: [PATCH 3/3] [update] correct the header callback description - the callback no longer "takes" a parameter: Layout calls it with one - the callback defines the content of a header, not the way to render HTML - a returned HTML string is rendered as markup, Layout doesn't parse it - Layout named as the acting subject instead of "the component" - screenshot of a toolbar in a cell header added to the guide section --- .../api/cell/layout_cell_header_config.md | 12 ++++++------ docs/layout/cell_configuration.md | 10 ++++++---- static/img/layout/widget_in_cell_header.png | Bin 0 -> 26288 bytes 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 static/img/layout/widget_in_cell_header.png diff --git a/docs/layout/api/cell/layout_cell_header_config.md b/docs/layout/api/cell/layout_cell_header_config.md index f9711791..ec1457c9 100644 --- a/docs/layout/api/cell/layout_cell_header_config.md +++ b/docs/layout/api/cell/layout_cell_header_config.md @@ -16,17 +16,17 @@ type TCellHeaderTemplate = (cell: ICellConfig) => string | IView; header?: string | TCellHeaderTemplate; ~~~ -The type of the value defines the way the component renders the content of a header: +The type of the value defines the way Layout renders the content of a header: -- **a string** - defines the text the header shows. The component doesn't interpret HTML tags and displays them as a part of the text -- **a callback function** - defines the way to render HTML content in a header. It takes the following parameter: +- **a string** - defines the text the header shows. Layout doesn't interpret HTML tags and displays them as a part of the text +- **a callback function** - defines the custom content the header shows. While rendering the cell, Layout calls the function with the following parameter: - `cell: ICellConfig` - the configuration object of the cell the header belongs to - The component calls the callback while it renders the cell and places the returned value into the DOM of the header: + Layout places the value that the function returns into the DOM of the header: - - *a string with HTML markup* - the component parses the markup and renders it - - *an object of a DHTMLX widget* - an initialized widget, the same object that you pass to the [`attach()`](layout/api/cell/layout_cell_attach_method.md) method of a cell. The name of a component doesn't work here, as the header treats any returned string as HTML + - *a string with HTML markup* - the header renders the tags as markup instead of showing them as text + - *an object of a DHTMLX widget* - an initialized widget, the same object that you pass to the [`attach()`](layout/api/cell/layout_cell_attach_method.md) method of a cell #### Example diff --git a/docs/layout/cell_configuration.md b/docs/layout/cell_configuration.md index 9794becb..efc5b099 100644 --- a/docs/layout/cell_configuration.md +++ b/docs/layout/cell_configuration.md @@ -78,12 +78,14 @@ If the [`header`](layout/api/cell/layout_cell_header_config.md) property is not ## Custom content in a cell header -Besides a text, the header of a cell can contain HTML markup or a DHTMLX widget. For this purpose, set the [`header`](layout/api/cell/layout_cell_header_config.md) property to a callback function. The component calls the function while it renders the cell. The function takes the configuration object of the cell as a parameter and returns the content for the header. +![Layout cell with a search toolbar in its header above a grid of names and addresses in DHTMLX Suite](/img/layout/widget_in_cell_header.png) + +Besides a text, the header of a cell can contain HTML markup or a DHTMLX widget. For this purpose, set the [`header`](layout/api/cell/layout_cell_header_config.md) property to a callback function. While rendering the cell, Layout calls the function with the configuration object of the cell and places the returned content into the header. The type of the value that you set for the `header` property defines the expected behavior: -- *a string*: the header shows it as plain text, and the component doesn't interpret HTML tags, it displays them as part of the text -- *a callback function*: tells the component that the header supports HTML content +- *a string*: the header shows it as plain text, and Layout doesn't interpret HTML tags, it displays them as part of the text +- *a callback function*: tells Layout that the header supports HTML content A cell with a custom header collapses and expands as any other cell, see the [Collapsibility](layout/cell_configuration.md#collapsibility) section. @@ -164,7 +166,7 @@ const layout = new dhx.Layout("layout_container", { }); ~~~ -The [`attachHTML()`](layout/api/cell/layout_cell_attachhtml_method.md) call repaints the cell, so the component calls the `header` callback again and renders the header with the current data as well. +The [`attachHTML()`](layout/api/cell/layout_cell_attachhtml_method.md) call repaints the cell, so Layout calls the `header` callback again and renders the header with the current data as well. **Related sample**: [Layout. HTML content in a cell header](https://snippet.dhtmlx.com/lromzzkx) diff --git a/static/img/layout/widget_in_cell_header.png b/static/img/layout/widget_in_cell_header.png new file mode 100644 index 0000000000000000000000000000000000000000..f85996a289a8f8a66ba11edac3ba359035f271dd GIT binary patch literal 26288 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