Skip to content

ALTER PAGE cannot create or populate an empty classic-grid control bar; DROP of the last button deletes the bar itself #957

Description

@MohamedGamalEzzatAli

ALTER PAGE cannot create or populate an empty classic-grid control bar — and DROP of the last button deletes the bar, making the state unrecoverable via MDL

Summary

A classic data grid's control bar is reachable by MDL only through its EXISTING buttons
(INSERT BEFORE/AFTER <barButton> and SET ... ON <barButton> both work — nice!). But there
is no way to bootstrap one: the bar itself is not addressable, the grid refuses INSERT INTO,
and DROP WIDGET of the bar's last button silently removes the bar element too — so one
scripted cleanup pass later, the grid's toolbar is permanently out of MDL's reach and only
Studio Pro can bring it back.

Since CREATE PAGE's DATAGRID authors a DataGrid2 (pluggable), classic grids only exist as
Studio-made content — which makes their bars exactly the thing migration/refactor scripts need
to edit, and exactly the thing that currently dead-ends.

Reproduction (v0.19.0, on a fresh blank app — mx create-project ships the page used here)

The stock Administration.Account_Overview has a classic grid with a control bar:

datagrid dataGrid21 ( DataSource: database from Administration.Account ... ) {
  controlbar controlBar1 {
    actionbutton actionButton1 (Caption: 'New local user', ...)
    ...
  1. Works today (for the record): SET (Caption = 'X') ON actionButton1 and
    INSERT AFTER actionButton1 { actionbutton btnNew (...) } both succeed.

  2. Drop the bar's buttons:

ALTER PAGE Administration.Account_Overview {
  DROP WIDGET actionButton1;
  DROP WIDGET actionButton2;
};

Succeeds — and DESCRIBE afterwards shows no controlbar at all: the bar element was
removed together with its last child. (If that cascade is intended, it still deserves a
mention in the DROP output, since it deletes an element the statement never named.)

  1. Every route back in is refused:
ALTER PAGE ... { INSERT INTO controlBar1 { actionbutton ... } };
Error: failed to insert: widget "controlBar1" not found. DataGrid2 columns are addressed by
a derived name (the bound attribute, or the caption), ...

(Also refused with this message BEFORE the drop, while the bar visibly existed with buttons —
the bar is not in the addressable-widget namespace at all, and the DataGrid2-columns hint is a
red herring for a classic grid.)

ALTER PAGE ... { INSERT INTO dataGrid21 { actionbutton ... } };
Error: failed to insert: cannot INSERT INTO "dataGrid21" (CustomWidgets$CustomWidget): it is
not a simple container — use INSERT BEFORE/AFTER a widget inside the target column or tab

Two oddities in that message worth a look while you're there: the classic grid is reported as
CustomWidgets$CustomWidget, and the suggested fix (anchor on a widget inside the target)
cannot apply — the grid's only insertable children live in the bar that no longer exists.

Suggested direction (any one closes the gap)

  1. Make INSERT INTO <gridName> valid for grid-family widgets with actionbutton/controlbar
    children — auto-creating the control bar when absent (mirrors what Studio Pro's UI does on
    the first button drag).
  2. Or make the bar addressable: INSERT INTO <controlBarName> { actionbutton ... }.
  3. Or at minimum keep an emptied bar in the model (or disclose its deletion in the DROP
    output), so INSERT INTO has something to target once 1/2 exist.

Environment

mxcli v0.19.0 (b313ff0), Windows amd64, Mendix 11.12.1, MPRv2; observed identically on a
fresh mx create-project app (Administration module v4.3.2) and an existing app (v4.5.0).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions