Create the Customer Rewards Wizard page object

Completed

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:

  1. Create a new page.

  2. Add steps.

  3. Add navigation.

  4. Add image headers.

  5. 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.

Screenshot of the layout section of the page.

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.

Screenshot of the group FirstPage code.

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.