Saved filter on page looses record reference and filters
1. Describe the bug Code has been inserted on OnOpenPage of page 537 in order to show or hide a field (added as extension) based on setup value. See code below. This works as i should, BUT if the user creates a filter (for example only showing Blocked = false, there is no values i Rec to determine which value the page is filtered on (view set from page 536).
2. To Reproduce
- Create table extension and page extension as shown below.
- Go to Dimensions, select dimension 'PROJECT' and open Dimension Values
- You will see the field "Event Date" on the page
- Add a filter on Blocked = false and save the filter as "Only Open"
- Click on "All" to show all dimension values for projekt - "Event Date" is shown
- Click on "Only Open" (still on dimension values for 'PROJECT' - the field is not not shown.
tableextension 50101 DimensionValue extends "Dimension Value"
{
fields
{
field(50100; "Event Date"; Date)
{
Caption = 'Event date';
DataClassification = CustomerContent;
}
}
pageextension 50102 "DimensionValues" extends "Dimension Values"
{
layout
{
addafter(Name)
{
field("Event Date"; Rec."Event Date")
{
ApplicationArea = All;
Visible = ShowEventDate;
}
}
}
trigger OnOpenPage()
begin
if Rec."Dimension Code" = 'PROJECT' then
ShowEventDate := true;
end;
var
ShowEventDate: Boolean;
}
Note: Because the developers need to copy and paste the code snippet, including a code snippet as a media file (i.e. .gif) is not sufficient.
3. Expected behavior I would expect the OnOpenPage() trigger to contain values in Rec and/or GetFilters(), GetView(). GetPosition() in order to evaluate the filtering on the current page.
4. Actual behavior The REC is empty when clicking on a saved filter for a page, making it impossible to evaluate the filter on the page although it clearly is in function.
5. Versions:
- AL Language: 15.0.1410565
- Visual Studio Code: 1.101.1
- Business Central: 26.1.33404.33876
- List of Visual Studio Code extensions that you have installed:
- Operating System:
- [X] Windows
- [ ] Linux
- [ ] MacOS
Final Checklist
This is no issue of the AL Language extension. Microsoft won't accept it.
However, let's try to help anyway.
The OnOpenPage trigger is not suitable for reading Rec field values, as OnOpenPage is called before the first record has been even read. Hence, it appears empty.
Before I continue: In your description, you mentioned that the visibility would be based on a "setup value", hence a value in another table. Your sample code refers to a field on the same record. Which one is correct?
Edit: the following does NOT apply to fields within a repeater control = your example. Sorry for the confusion.
PS: Please note that dynamic visibility (controlled by a variable) does not work on page field level. You have to create a field group around your new page field, and move your Visible expression to the field group. See also the docs.
@NKarolak Thank you for helping out.
- The Setup: To simplify the code I just showed a hardcoded simplified version. In the original it's a field on General Leger Setup (if Rec."Dimension Code" = GLSetup."Project Dimension Code". But has no impact on the problem.
- About OnOpenpage: Well, when opening the page regularly Rec has a value, so that's not completely accurate to say that it is empty
- The main issue to me is that I cannot evaluate the view/filters set on the table. Rec empty or not this could help distinguishing how to set the value of the Visbible property variable.
About OnOpenpage: Well, when opening the page regularly Rec has a value, so that's not completely accurate to say that it is empty
Rec fields are filled only when OnAfterGetRecord is executed - which happens after OnOpenPage. Have you debugged Rec in the OnOpenPage trigger?
In the original it's a field on General Leger Setup (if Rec."Dimension Code" = GLSetup."Project Dimension Code".
Rec is only one of the many records that may appear on the "Dimension Values" page. The page can, in theory, display values for PROJECT and for other dimension codes - at the same time! How do you want your page to behave, then?
The main issue to me is that I cannot evaluate the view/filters set on the table.
In OnOpenPage (and beyond), you can read the page filters set on the Dimension Code by using Rec.GetFilter, likely only in combination with Rec.FilterGroup.
Another possibility (but a dirty hack) could be to change the OnOpenPage trigger as follows - which works correctly only as long as the page is filtered on the Dimension Code:
trigger OnOpenPage()
begin
if Rec.FindFirst() then; // <------- NEW CODE LINE
if Rec."Dimension Code" = 'PROJECT' then
ShowEventDate := true;
end;
But you can try this approach to verify with a debugger what I said: OnOpenPage does not set field values, it just has filters.
Our documentation on page triggers is lacking some information so I'll share it here.
Natalie is correct, it is not expected that the OnOpenPage trigger would have a populated record.
First of all, a snapshot of the trigger chain would look something like this:
OnInit <- irrelevant
|
v
OnOpenPage (the DB has not been queried yet, this is the place to put filters)
|
v
OnAfterGetRecord (just after the DB is queried)
If you pass a record to open a page, the values on the record fields are cleared. What is kept are the filters, so to do what you are trying to do, you would need to either:
- Use GetFilter on the record and check the passed in filter
- Add a method on the page which populates the ShowEventDate variable and pass in the value before running the page
var
MyPage: Page Foo;
begin
MyPage.SetEventDateVisibility(FooRecord."Dimension Code");
MyPage.Run(FooRecord);
end;
- Use Natalie's hack but keep in mind it is quite inefficient
@BazookaMusic @NKarolak:
Thank you for your input.
I still believe that there is an issue to be faced:
- The page "Dimension Values" (page 537) is called from page "Dimensions" (page 536) with the following RunObject = Page "Dimension Values"; RunPageLink = "Dimension Code" = field(Code);
- When opening the page I can, as stated, use "Rec.GetFilters" in OnOpenPage.
- If I in the same page through the user interface add a filter on f.ex. the new field I've added, then the OnOpenPage is triggered again, but now there is no value i "Rec.GetFilters()". BUT the RunPageLink is still effective.
So my believe is that there is an error in the way OnOpenPage is handled when a user activates a manual filter on a page causing "Rec.GetFilter(s)" to be empty although it in fact isn't