Create the Customer Rewards Wizard page object
The following code adds a Customer Rewards Wizard page, which enables the user to accept the terms for using and activating the extension.
The page consists of the following steps:
Welcome - The welcome step has a check box for the Terms of Use that must be enabled.
Activation - The activation step has a text box where the activation code must be entered for validation. A valid activation code for this sample extension is any 14-character alphanumeric code.
Finish - A step that finishes processing on the page.
You can use a Navigate page type to create a wizard that leads the user through a sequence of steps for completing a task.
The following example is a sample of code that you can use to create the Customer Rewards Wizard page.
page 50100 "Customer Rewards Wizard"
{
// Specifies that this page will be a navigate page.
PageType = NavigatePage;
Caption = 'Customer Rewards assisted setup guide';
layout
{
area(content)
{
group(MediaStandard)
{
Caption = '';
Editable = false;
Visible = TopBannerVisible;
field("Media Reference"; MediaResourcesStandard."Media Reference")
{
ApplicationArea = All;
Editable = false;
ShowCaption = false;
}
}
group(FirstPage)
{
Caption = '';
Visible = FirstPageVisible;
group("Welcome")
{
Caption = 'Welcome';
Visible = FirstPageVisible;
group(Introduction)
{
Caption = '';
InstructionalText = 'This Customer Rewards extension is a sample extension. It adds rewards tiers support for Customers.';
Visible = FirstPageVisible;
field(Spacer1; '')
{
ApplicationArea = All;
ShowCaption = false;
Editable = false;
MultiLine = true;
}
}
group("Terms")
{
Caption = 'Terms of Use';
Visible = FirstPageVisible;
group(Terms1)
{
Caption = '';
InstructionalText = 'By enabling the Customer Rewards extension...';
Visible = FirstPageVisible;
}
}
group(Terms2)
{
Caption = '';
field(EnableFeature; EnableCustomerRewards)
{
ApplicationArea = All;
MultiLine = true;
Editable = true;
Caption = 'I understand and accept these terms.';
ToolTip = 'Click to confirm: I understand and accept these terms.';
trigger OnValidate();
begin
ShowFirstPage();
end;
}
}
}
}
group(SecondPage)
{
Caption = '';
Visible = SecondPageVisible;
group("Activation")
{
Caption = 'Activation';
Visible = SecondPageVisible;
field(Spacer2; '')
{
ApplicationArea = All;
ShowCaption = false;
Editable = false;
MultiLine = true;
}
group(ActivationMessage)
{
Caption = '';
InstructionalText = 'Enter your 14 digit activation code to continue';
Visible = SecondPageVisible;
field(Activationcode; ActivationCode)
{
ApplicationArea = All;
ShowCaption = false;
Editable = true;
}
}
}
}
group(FinalPage)
{
Caption = '';
Visible = FinalPageVisible;
group("ActivationDone")
{
Caption = 'You''re done!';
Visible = FinalPageVisible;
group(DoneMessage)
{
Caption = '';
InstructionalText = 'Click Finish to set up your rewards level and start using Customer Rewards.';
Visible = FinalPageVisible;
}
}
}
}
}
actions
{
area(Processing)
{
action(ActionBack)
{
ApplicationArea = All;
Caption = 'Back';
Enabled = BackEnabled;
Visible = BackEnabled;
Image = PreviousRecord;
InFooterBar = true;
trigger OnAction();
begin
NextStep(true);
end;
}
action(ActionNext)
{
ApplicationArea = All;
Caption = 'Next';
Enabled = NextEnabled;
Visible = NextEnabled;
Image = NextRecord;
InFooterBar = true;
trigger OnAction();
begin
NextStep(false);
end;
}
action(ActionActivate)
{
ApplicationArea = All;
Caption = 'Activate';
Enabled = ActivateEnabled;
Visible = ActivateEnabled;
Image = NextRecord;
InFooterBar = true;
trigger OnAction();
var
CustomerRewardsExtMgt: Codeunit "Customer Rewards Ext Mgt";
begin
if ActivationCode = '' then
Error('Activation code cannot be blank.');
if Text.StrLen(ActivationCode) <> 14 then
Error('Activation code must have 14 digits.');
if CustomerRewardsExtMgt.ActivateCustomerRewards(ActivationCode) then
NextStep(false)
else
Error('Activation failed. Please check the activation code you entered.');
end;
}
action(ActionFinish)
{
ApplicationArea = All;
Caption = 'Finish';
Enabled = FinalPageVisible;
Image = Approve;
InFooterBar = true;
trigger OnAction();
begin
FinishAndEnableCustomerRewards();
end;
}
}
}
trigger OnInit();
begin
LoadTopBanners();
end;
trigger OnOpenPage();
begin
Step := Step::First;
EnableControls();
end;
local procedure EnableControls();
begin
ResetControls();
case Step of
Step::First:
ShowFirstPage();
Step::Second:
ShowSecondPage();
Step::Finish:
ShowFinalPage();
end;
end;
local procedure NextStep(Backwards: Boolean);
begin
if Backwards then
Step := Step - 1
ELSE
Step := Step + 1;
EnableControls();
end;
local procedure FinishAndEnableCustomerRewards();
var
CustomerRewardsExtMgt: Codeunit "Customer Rewards Ext Mgt";
GuidedExperience: Codeunit "Guided Experience";
Info: ModuleInfo;
begin
NavApp.GetCurrentModuleInfo(Info);
GuidedExperience.CompleteAssistedSetup(ObjectType::Page,PAGE::"Customer Rewards Wizard");
CurrPage.Close();
CustomerRewardsExtMgt.OpenRewardsLevelPage();
end;
local procedure ShowFirstPage();
begin
FirstPageVisible := true;
SecondPageVisible := false;
FinishEnabled := false;
BackEnabled := false;
ActivateEnabled := false;
NextEnabled := EnableCustomerRewards;
end;
local procedure ShowSecondPage();
begin
FirstPageVisible := false;
SecondPageVisible := true;
FinishEnabled := false;
BackEnabled := true;
NextEnabled := false;
ActivateEnabled := true;
end;
local procedure ShowFinalPage();
begin
FinalPageVisible := true;
BackEnabled := true;
NextEnabled := false;
ActivateEnabled := false;
end;
local procedure ResetControls();
begin
FinishEnabled := true;
BackEnabled := true;
NextEnabled := true;
ActivateEnabled := true;
FirstPageVisible := false;
SecondPageVisible := false;
FinalPageVisible := false;
end;
local procedure LoadTopBanners();
begin
if MediaRepositoryStandard.GET('AssistedSetup-NoText-400px.png', FORMAT(CURRENTCLIENTTYPE))
then
if MediaResourcesStandard.GET(MediaRepositoryStandard."Media Resources Ref")
then
TopBannerVisible := MediaResourcesStandard."Media Reference".HASVALUE;
end;
var
MediaRepositoryStandard: Record "Media Repository";
MediaResourcesStandard: Record "Media Resources";
Step: Option First,Second,Finish;
ActivationCode: Text;
TopBannerVisible: Boolean;
FirstPageVisible: Boolean;
SecondPageVisible: Boolean;
FinalPageVisible: Boolean;
FinishEnabled: Boolean;
BackEnabled: Boolean;
NextEnabled: Boolean;
ActivateEnabled: Boolean;
EnableCustomerRewards: Boolean;
}
The following section explains how you would typically create a wizard page for Business Central.
You can create a wizard page in five steps:
Create a new page.
Add steps.
Add navigation.
Add image headers.
Test the page.
Step 1: Create a new page
Create a new file in your extension in Visual Studio Code and name it CustomerRewardsWizard.Page.al.
Add the following code to the page that you've created:
page 50100 Customer Rewards Wizard
{
// Specifies that this page will be a navigate page.
PageType = NavigatePage;
Caption = 'Customer Rewards assisted setup guide';
}
A wizard page uses the page type of NavigatePage.
Step 2: Add steps
Create the framework for the different steps in the wizard. Add a layout section to the page that contains four groups, as displayed in the following screenshot.
The first group will contain the header images. The details of this step are explained in a later step of this procedure.
The second, third, and last groups are named as follows:
FirstPage
SecondPage
LastPage
You can use other names, but the principle is that you should create one group for every step that you want to have available in the wizard. We recommend that you avoid using too many steps; three or four steps should be enough.
Next, add the following code to the FirstPage group.
Boolean variables have been used to determine the visibility of these groups. Later, when the user goes to the wizard by using the provided buttons, you'll hide and show the appropriate pages or groups.
In the SecondPage group, use the following code:
group(SecondPage)
{
Caption = '';
Visible = SecondPageVisible;
group("Activation")
{
Caption = 'Activation';
Visible = SecondPageVisible;
field(Spacer2; '')
{
ApplicationArea = All;
ShowCaption = false;
Editable = false;
MultiLine = true;
}
group(ActivationMessage)
{
Caption = '';
InstructionalText = 'Enter your 14 digit activation code to continue';
Visible = SecondPageVisible;
field(Activationcode; ActivationCode)
{
ApplicationArea = All;
ShowCaption = false;
Editable = true;
}
}
}
}
In this group, you'll provide the user with the option to enter the activation code for the Customer Rewards extension.
Use the following code the FinalPage group:
group(FinalPage)
{
Caption = '';
Visible = FinalPageVisible;
group("ActivationDone")
{
Caption = 'You are done!';
Visible = FinalPageVisible;
group(DoneMessage)
{
Caption = '';
InstructionalText = 'Click Finish to set up your rewards level and start using Customer Rewards.';
Visible = FinalPageVisible;
}
}
}
The InstructionalText property sets the text that is used for instructions in the UI. The default is an empty string, which means that no instructions are provided. According to the user assistance model for Business Central, apps are expected to apply instructional text to setup guides and similar pages.
Step 3: Add navigation
To make the wizard page appear like a wizard, you need to add Next, Back, and Finish actions.
All pages contain navigation controls called actions. In Business Central, actions are displayed at the top of each page in the ribbon. The actions section of the page describes what the user can do on a page and must be designed with the user's needs for process support in mind.
You can use the following code to add the action section to the wizard page.
actions
{
area(Processing)
{
action(ActionBack)
{
ApplicationArea = All;
Caption = 'Back';
Enabled = BackEnabled;
Visible = BackEnabled;
Image = PreviousRecord;
InFooterBar = true;
trigger OnAction();
begin
NextStep(true);
end;
}
action(ActionNext)
{
ApplicationArea = All;
Caption = 'Next';
Enabled = NextEnabled;
Visible = NextEnabled;
Image = NextRecord;
InFooterBar = true;
trigger OnAction();
begin
NextStep(false);
end;
}
action(ActionActivate)
{
ApplicationArea = All;
Caption = 'Activate';
Enabled = ActivateEnabled;
Visible = ActivateEnabled;
Image = NextRecord;
InFooterBar = true;
trigger OnAction();
var
CustomerRewardsExtMgt: Codeunit "Customer Rewards Ext Mgt";
begin
if ActivationCode = '' then
Error('Activation code cannot be blank.');
if Text.StrLen(ActivationCode) <> 14 then
Error('Activation code must have 14 digits.');
if CustomerRewardsExtMgt.ActivateCustomerRewards(ActivationCode) then
NextStep(false)
else
Error('Activation failed. Please check the activation code you entered.');
end;
}
action(ActionFinish)
{
ApplicationArea = All;
Caption = 'Finish';
Enabled = FinalPageVisible;
Image = Approve;
InFooterBar = true;
trigger OnAction();
begin
FinishAndEnableCustomerRewards();
end;
}
}
}
The enabled and visible properties of these actions are also set to Boolean variables. The OnAction trigger on each action will call the following functions:
NextStep(True)
NextStep(False)
FinishAndEnableCustomerRewards
These functions, or procedures, are created at the bottom of the page object.
local procedure NextStep(Backwards: Boolean);
begin
if Backwards then
Step := Step - 1
ELSE
Step := Step + 1;
EnableControls();
end;
local procedure FinishAndEnableCustomerRewards();
var
CustomerRewardsExtMgt: Codeunit "Customer Rewards Ext Mgt";
GuidedExperience: Codeunit "Guided Experience";
Info: ModuleInfo;
begin
NavApp.GetCurrentModuleInfo(Info);
GuidedExperience.CompleteAssistedSetup(ObjectType::Page,PAGE::"Customer Rewards Wizard");
CurrPage.Close();
CustomerRewardsExtMgt.OpenRewardsLevelPage();
end;
local procedure EnableControls();
begin
ResetControls();
case Step of
Step::First:
ShowFirstPage();
Step::Second:
ShowSecondPage();
Step::Finish:
ShowFinalPage();
end;
end;
Next, add the following code:
trigger OnInit();
begin
LoadTopBanners();
end;
trigger OnOpenPage();
begin
Step := Step::First;
EnableControls();
end;
The addition of this code ensures that, when the page initializes and opens, the banners are loaded and the first step becomes visible.
The following procedures are also added to the page.
local procedure ShowFirstPage();
begin
FirstPageVisible := true;
SecondPageVisible := false;
FinishEnabled := false;
BackEnabled := false;
ActivateEnabled := false;
NextEnabled := EnableCustomerRewards;
end;
local procedure ShowSecondPage();
begin
FirstPageVisible := false;
SecondPageVisible := true;
FinishEnabled := false;
BackEnabled := true;
NextEnabled := false;
ActivateEnabled := true;
end;
local procedure ShowFinalPage();
begin
FinalPageVisible := true;
BackEnabled := true;
NextEnabled := false;
ActivateEnabled := false;
end;
local procedure ResetControls();
begin
FinishEnabled := true;
BackEnabled := true;
NextEnabled := true;
ActivateEnabled := true;
FirstPageVisible := false;
SecondPageVisible := false;
FinalPageVisible := false;
end;
You can use these procedures to set the Boolean variables, which determine which groups are visible and which actions should be enabled, depending on which page you're currently on in the wizard.
For these procedures, you'll also require the following var section, where you declare some global variables.
var
MediaRepositoryStandard: Record "Media Repository";
MediaResourcesStandard: Record "Media Resources";
Step: Option First,Second,Finish;
ActivationCode: Text;
TopBannerVisible: Boolean;
FirstPageVisible: Boolean;
SecondPageVisible: Boolean;
FinalPageVisible: Boolean;
FinishEnabled: Boolean;
BackEnabled: Boolean;
NextEnabled: Boolean;
ActivateEnabled: Boolean;
EnableCustomerRewards: Boolean;
The InFooterBar property sets whether an action should be viewed as an exit action in the lower part of the page. In a wizard page, this property is set to true so that the actions appear at the bottom of the wizard page.
Step 4: Add image headers
The image headers are added as the first group in the layout section of the page:
group(MediaStandard)
{
Caption = '';
Editable = false;
Visible = TopBannerVisible;
field("Media Reference"; MediaResourcesStandard."Media Reference")
{
ApplicationArea = All;
Editable = false;
ShowCaption = false;
}
}
When the page opens, the images are retrieved from the database with the following function.
local procedure LoadTopBanners();
begin
if MediaRepositoryStandard.GET('AssistedSetup-NoText-400px.png', FORMAT(CURRENTCLIENTTYPE))
then
if MediaResourcesStandard.GET(MediaRepositoryStandard."Media Resources Ref")
then
TopBannerVisible := MediaResourcesStandard."Media Reference".HASVALUE;
end;
trigger OnInit();
begin
LoadTopBanners();
end;
trigger OnOpenPage();
begin
Step := Step::First;
EnableControls();
end;
Step 5: Test the page
To test the wizard page, you can deploy your project by using the Ctrl+F5 keyboard shortcut. Most wizard pages have the same structure and are only different in the number of steps that you want to implement and the source table that is used. Accordingly, we highly recommended that you create your own snippets to speed up development. After you've become familiar with AL language and have obtained some experience in app development, it would be beneficial to create development best practices that all your developers can implement. These best practices can exist in the form of custom code snippets and templates.