Is it possible to dynamically create a list page in Business Central using AL where you define the columns on page load?
Example is I have a data table defined where there are Fields 1 - 5:
table 50102 MyDataTable
{
DataClassification = ToBeClassified;
fields
{
field(1; "F1"; Text[150])
{
DataClassification = ToBeClassified;
}
field(2; "F2"; Text[150])
{
DataClassification = ToBeClassified;
}
field(3; "F3"; Text[150])
{
DataClassification = ToBeClassified;
}
field(4; "F4"; Text[150])
{
DataClassification = ToBeClassified;
}
field(5; "F5"; Text[150])
{
DataClassification = ToBeClassified;
}
}
}
This is intended to store data in different fields depending on an import type. This import has a mapping stored in another table which says that if we import an excel file of X type then column 1 goes to field F1, column 2 goes to field F3, column 3 goes to field F5. A different import type of Y will store values in different columns in the data table.
Problem is when we need to display the values in this data table according to the import type. If we're viewing the data I only want to see the columns associated with it.
examples: For type X I only want to show a list page with fields F1, F3, F5. For Y type I would like to show a list page with fields F1, F2, F4, F5
Is this possible in AL? Can you call out to a codeunit in the list page per field to determine if its to be shown?
In other words, is something like this possible?
page 50102 MyImportedDataList
{
ApplicationArea = All;
Caption = 'Import File';
PageType = List;
SourceTable = MyDataTable;
UsageCategory = Administration;
Editable = false;
layout
{
area(Content)
{
repeater(Group)
{
field(Column1; rec.F1)
{
ApplicationArea = All;
visible = myCodeunit.IsThisColumnVisible(Rec.F1); // <<---- IS THIS POSSIBLE
}
// Other columns omitted
}
}
}
}
You are on the right track however you cannot call a procedure
in the expression of the Visible
property.
This will cause a compiler error:
Procedure calls is not valid for client expressions
However there is a workaround for this.
First you must create a global variable and use it in the expression for the Visible
property:
field(Column1; rec.F1)
{
Visible = IsF1Visible;
}
...
var
IsF1Visible: Boolean;
Then you create a procedure to update the value of your new global variable:
local procedure UpdateControls()
begin
IsF1Visible := MyCodeunit.IsThisColumnVisible(Rec.F1);
...
end;
Lastly you need to call the procedure at the right moments. There are two possibilities here:
Scenario 1
You call the procedure in OnOpenPage
:
trigger OnOpenPage()
begin
UpdateControls();
end;
Because no data is loaded yet, you might need to supply some context before opening the page or use the filters on the page to determine which import type it is.
Scenario 2
You call the procedure in OnAfterGetRecord
and OnAfterGetCurrRecord
:
trigger OnAfterGetRecord()
begin
UpdateControls();
end;
trigger OnAfterGetCurrRecord()
begin
UpdateControls();
end;