From 760de838fda92f8e02db19446e69f96f018b2b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Go=C5=82embiewski?= Date: Tue, 22 Sep 2026 23:04:57 +0200 Subject: [PATCH 1/3] docs(skill): name both places a filter widget can live The filter widgets section of the create-page widget reference opened with "Filter widgets are used inside GALLERY FILTER containers", so a reader building a data grid stopped at the first line -- everything under it, including the association form, applies to a grid column just as well. The lead-in now names both homes, the grid column first, with a two-line example of each. --- .../skills/mendix/create-page/reference/widgets.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.claude/skills/mendix/create-page/reference/widgets.md b/.claude/skills/mendix/create-page/reference/widgets.md index 85c584134..b8df3c17b 100644 --- a/.claude/skills/mendix/create-page/reference/widgets.md +++ b/.claude/skills/mendix/create-page/reference/widgets.md @@ -558,7 +558,19 @@ gallery productGallery (datasource: database Module.Product, selection: single) ### Filter Widgets -Filter widgets are used inside GALLERY FILTER containers to enable search/filtering: +A filter widget lives in one of two places: **inside a DATA GRID column's own braces**, +where it filters that column, or inside a **GALLERY FILTER container**, where it filters +the whole list. The widgets below are the same either way: + +```sql +datagrid dg (datasource: database Module.Entity) { + column colName (attribute: Name) { textfilter f1 } -- the grid form +} + +gallery g (datasource: database Module.Entity) { + filter flt { textfilter f1 } -- the gallery form +} +``` **TEXTFILTER** - Text search filter: ```sql From 2adda8b09a843f1c82192f015b0ef3b031134f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Go=C5=82embiewski?= Date: Tue, 22 Sep 2026 23:04:57 +0200 Subject: [PATCH 2/3] docs(skill): show the two column filters an overview list actually needs The type table in overview-pages maps each attribute type to its filter widget and stops there, so the two forms a real list reaches for first were nowhere on the page a reader building that list opens: a dropdownfilter over an association (Association + datasource + CaptionAttribute), and FilterType: between for a date range. Both verified on a blank 11.12.1 project -- check, exec, mx check 0 errors, and DESCRIBE returning the same line. The section also says now that the grid filters itself, because the alternative keeps being written: a non-persistent filter entity, inputs bound to it, an apply microflow on every change and an XPath reading that object back -- three microflows and 1,100 characters of XPath on one generated app, against five lines. 675 -> 696 lines, under the 700 the split test allows. --- .claude/skills/mendix/overview-pages/SKILL.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.claude/skills/mendix/overview-pages/SKILL.md b/.claude/skills/mendix/overview-pages/SKILL.md index d3308ef81..4fcf9f158 100644 --- a/.claude/skills/mendix/overview-pages/SKILL.md +++ b/.claude/skills/mendix/overview-pages/SKILL.md @@ -241,6 +241,27 @@ column's braces it parses as a column with **no body** followed by a separate write with no diagnostic, so `DESCRIBE PAGE` showing a filterless column was the only symptom; it is now refused at check and exec time. +**A column over an association is filtered by the associated objects.** The column +shows a value from the other side (`attribute: Order_Customer/Name`); the filter takes +the reference, the option list and what an option shows — all three, or it is refused: + +```sql +column colCustomer (attribute: Order_Customer/Name, caption: 'Customer') { + dropdownfilter fltCustomer ( + Association: Sales.Order_Customer, -- the reference on the grid's entity + datasource: database Sales.Customer, -- the option list + CaptionAttribute: Name -- what each option shows + ) +} +``` + +A `datefilter` compares one date; `FilterType: between` makes the column a range. + +**The grid filters itself — do not build a filter bar beside it.** The shape to avoid is a +non-persistent filter entity, inputs bound to it, an apply microflow on every change, and +an XPath on the grid reading that object back: measured on one generated app, three +microflows and 1,100 characters of XPath against five lines, one filter per column. + ## NewEdit Page Template Form for creating or editing a single entity. **Requires a page parameter** to receive the object. From f0db660b423a04f56cb23aa91ea10ada608b1611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Go=C5=82embiewski?= Date: Tue, 22 Sep 2026 23:04:57 +0200 Subject: [PATCH 3/3] docs: note the data grid filter documentation in the changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32dc27fa1..8889c5deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ### Changed +- **A data grid's column filters are documented where a data grid is documented** — the filter widgets section of the `create-page` widget reference opened with "Filter widgets are used inside GALLERY FILTER containers", so a reader building a grid found the widgets only by reading a gallery section to the end. It now names both homes up front, with the grid form first. The `overview-pages` skill gains the two forms its type table did not cover: a `dropdownfilter` over an association (`Association:` + `datasource:` + `CaptionAttribute:`, verified `mx check` 0 errors and round-tripped through `describe`), `FilterType: between` for a date range, and the reminder that a grid filters itself — two generated apps built a filter bar over a non-persistent helper entity instead, one of them costing three microflows and 1,100 characters of XPath where five column filters would do. + - **Microflows written without `@position` are laid out to be read, not just to be valid** (mendixlabs/mxcli#1154). Geometry and connection sides only: no MDL syntax changes, a statement carrying `@position` is never moved, and `describe` → `exec` still reports `Unchanged microflow`. Measured on a generated app of 41 microflows, none with an `@position`: the widest flow went from 6930×160 px on one row to 3220 px, with 0 overlapping elements and `mx check` at 0 errors before and after. - **A long main line wraps onto rows.** Past 2880 px (two Studio Pro canvases) the next statement starts a new row under everything the current row occupies — branch lanes, loop boxes and notes included, measured after they are built rather than estimated. The line joining two rows leaves the bottom of the last element and arrives on top of the first, so it runs through the band between the rows instead of back across the activities. A tail short enough to finish within two more activities stays on its row rather than becoming a stub underneath.