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 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. 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.