Skip to content

Commit 77d20f5

Browse files
akoclaude
andcommitted
refactor: use Visible: [xpath] and Editable: [xpath] syntax
Replace VISIBLE IF 'string' / EDITABLE IF 'string' with standard property syntax using XPath bracket expressions: Visible: [IsActive] -- conditional (XPath) Visible: false -- static Editable: [Status != 'Closed'] -- conditional (XPath) Editable: Never -- static This is consistent with XPath syntax used elsewhere in MDL (WHERE clauses, entity access rules) and avoids a new IF keyword. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 126268f commit 77d20f5

File tree

10 files changed

+3498
-3450
lines changed

10 files changed

+3498
-3450
lines changed

.claude/skills/mendix/alter-page.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ SET Title = 'New Page Title'
6565
| `Name` | Any widget | String | `SET Name = 'newName' ON oldName` |
6666
| `Title` | Page-level only | String | `SET Title = 'Edit Customer'` |
6767
| `Layout` | Page-level only | Qualified name | `SET Layout = Atlas_Core.Atlas_Default` |
68+
| `Visible` | Any widget | Boolean or `[xpath]` | `SET Visible = false ON txtHidden` |
69+
| `Editable` | Input widgets | Never/Always or `[xpath]` | `SET Editable = Never ON txtReadOnly` |
6870
| `'quotedProp'` | Pluggable widgets | String, Boolean, Number | `SET 'showLabel' = false ON cbStatus` |
6971

7072
**Pluggable widget properties** use quoted names to set values in the widget's `Object.Properties[]`. Boolean values are stored as `"yes"`/`"no"` in BSON.

.claude/skills/mendix/create-page.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -747,22 +747,24 @@ See the dedicated skill file: [ALTER PAGE/SNIPPET](./alter-page.md)
747747

748748
## Conditional Visibility and Editability
749749

750-
Any widget can have conditional visibility. Input widgets can also have conditional editability.
750+
Any widget can have conditional visibility. Input widgets can also have conditional editability. Use XPath bracket syntax `[expression]`:
751751

752752
```sql
753753
-- Conditionally visible widget
754-
TEXTBOX txtName (Label: 'Name', Attribute: Name, VISIBLE IF '$currentObject/IsActive')
754+
TEXTBOX txtName (Label: 'Name', Attribute: Name, Visible: [IsActive])
755755

756756
-- Conditionally editable input
757-
TEXTBOX txtStatus (Label: 'Status', Attribute: Status, EDITABLE IF '$currentObject/Status != ''Closed''')
757+
TEXTBOX txtStatus (Label: 'Status', Attribute: Status, Editable: [Status != 'Closed'])
758758

759759
-- Combined
760760
TEXTBOX txtEmail (Label: 'Email', Attribute: Email,
761-
VISIBLE IF '$currentObject/ShowEmail',
762-
EDITABLE IF '$currentObject/CanEdit')
763-
```
761+
Visible: [ShowEmail],
762+
Editable: [CanEdit])
764763

765-
The expression is a Mendix expression string using `$currentObject/AttributeName` syntax. Single quotes within the expression must be doubled (`''`).
764+
-- Static values still work
765+
TEXTBOX txtReadOnly (Label: 'Read Only', Attribute: Name, Editable: Never)
766+
TEXTBOX txtHidden (Label: 'Hidden', Attribute: Name, Visible: false)
767+
```
766768

767769
## Known Limitations
768770

docs-site/src/language/pages.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,24 @@ Values are 1-12 (grid units) or `AutoFill`. TabletWidth and PhoneWidth default t
9090

9191
### Conditional Visibility
9292

93-
Any widget can be conditionally visible using a Mendix expression:
93+
Any widget can be conditionally visible using an XPath expression in brackets:
9494

9595
```sql
96-
TEXTBOX txtName (Label: 'Name', Attribute: Name, VISIBLE IF '$currentObject/IsActive')
96+
TEXTBOX txtName (Label: 'Name', Attribute: Name, Visible: [IsActive])
9797
```
9898

99+
Static values also work: `Visible: false` hides the widget unconditionally.
100+
99101
### Conditional Editability
100102

101103
Input widgets can be conditionally editable:
102104

103105
```sql
104-
TEXTBOX txtStatus (Label: 'Status', Attribute: Status, EDITABLE IF '$currentObject/Status != ''Closed''')
106+
TEXTBOX txtStatus (Label: 'Status', Attribute: Status, Editable: [Status != 'Closed'])
105107
```
106108

109+
Static values: `Editable: Never`, `Editable: Always`.
110+
107111
## Layouts
108112

109113
Layouts are referenced by their qualified name (`Module.LayoutName`). Common Atlas layouts include:

docs/01-project/MDL_QUICK_REFERENCE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,8 @@ CREATE PAGE MyModule.Customer_Edit
430430
| DesktopWidth | `COLUMN col (DesktopWidth: 8)` | 1-12 or AutoFill |
431431
| TabletWidth | `COLUMN col (TabletWidth: 6)` | 1-12 or AutoFill (default: auto) |
432432
| PhoneWidth | `COLUMN col (PhoneWidth: 12)` | 1-12 or AutoFill (default: auto) |
433-
| VISIBLE IF | `TEXTBOX txt (VISIBLE IF '$obj/IsActive')` | Conditional visibility expression |
434-
| EDITABLE IF | `TEXTBOX txt (EDITABLE IF '$obj/Status != ''Closed''')` | Conditional editability expression |
433+
| Visible | `TEXTBOX txt (Visible: [IsActive])` | Conditional visibility (XPath expression) |
434+
| Editable | `TEXTBOX txt (Editable: [Status != 'Closed'])` | Conditional editability (XPath expression) |
435435

436436
**Supported Widgets:**
437437
- Layout: `LAYOUTGRID`, `ROW`, `COLUMN`, `CONTAINER`, `CUSTOMCONTAINER`

mdl-examples/doctype-tests/03-page-examples.mdl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,8 +2277,8 @@ CREATE PAGE PgTest.P040_ConditionalProps
22772277
ROW row1 {
22782278
COLUMN col1 (DesktopWidth: 8, TabletWidth: 6, PhoneWidth: 12) {
22792279
DATAVIEW dv1 (DataSource: MICROFLOW PgTest.DS_GetFirst) {
2280-
TEXTBOX txtName (Label: 'Name', Attribute: Name, VISIBLE IF '$currentObject/Name != empty')
2281-
TEXTBOX txtCountry (Label: 'Country', Attribute: Country, EDITABLE IF 'true')
2280+
TEXTBOX txtName (Label: 'Name', Attribute: Name, Visible: [Name != empty])
2281+
TEXTBOX txtCountry (Label: 'Country', Attribute: Country, Editable: [true])
22822282
}
22832283
}
22842284
COLUMN col2 (DesktopWidth: 4, TabletWidth: 6, PhoneWidth: 12) {

mdl/executor/cmd_pages_describe_output.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ func appendDataGridPagingProps(props []string, w rawWidget) []string {
3939
// appendConditionalProps appends VISIBLE IF and EDITABLE IF if present.
4040
func appendConditionalProps(props []string, w rawWidget) []string {
4141
if w.VisibleIf != "" {
42-
props = append(props, fmt.Sprintf("VISIBLE IF %s", mdlQuote(w.VisibleIf)))
42+
props = append(props, fmt.Sprintf("Visible: [%s]", w.VisibleIf))
4343
}
4444
if w.EditableIf != "" {
45-
props = append(props, fmt.Sprintf("EDITABLE IF %s", mdlQuote(w.EditableIf)))
45+
props = append(props, fmt.Sprintf("Editable: [%s]", w.EditableIf))
4646
}
4747
return props
4848
}
@@ -59,10 +59,10 @@ func appendAppearanceProps(props []string, w rawWidget) []string {
5959
props = append(props, formatDesignPropertiesMDL(w.DesignProperties))
6060
}
6161
if w.VisibleIf != "" {
62-
props = append(props, fmt.Sprintf("VISIBLE IF %s", mdlQuote(w.VisibleIf)))
62+
props = append(props, fmt.Sprintf("Visible: [%s]", w.VisibleIf))
6363
}
6464
if w.EditableIf != "" {
65-
props = append(props, fmt.Sprintf("EDITABLE IF %s", mdlQuote(w.EditableIf)))
65+
props = append(props, fmt.Sprintf("Editable: [%s]", w.EditableIf))
6666
}
6767
return props
6868
}

mdl/grammar/MDLParser.g4

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,9 +1825,10 @@ widgetPropertyV3
18251825
| DESIGNPROPERTIES COLON designPropertyListV3 // DesignProperties: [...]
18261826
| WIDTH COLON NUMBER_LITERAL // Width: 200
18271827
| HEIGHT COLON NUMBER_LITERAL // Height: 100
1828-
| VISIBLE IF STRING_LITERAL // VISIBLE IF '$currentObject/IsActive = true'
1829-
| VISIBLE COLON propertyValueV3 // Visible: expression
1830-
| EDITABLE IF STRING_LITERAL // EDITABLE IF '$currentObject/Status = Draft'
1828+
| VISIBLE COLON xpathConstraint // Visible: [IsActive = true]
1829+
| VISIBLE COLON propertyValueV3 // Visible: false
1830+
| EDITABLE COLON xpathConstraint // Editable: [Status != 'Closed']
1831+
| EDITABLE COLON propertyValueV3 // Editable: Never | Always
18311832
| TOOLTIP COLON propertyValueV3 // Tooltip: 'text'
18321833
| IDENTIFIER COLON propertyValueV3 // Generic: any other property
18331834
;

mdl/grammar/parser/MDLParser.interp

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)