How to do it...

  1. Open your AL project in Visual Studio Code.
  2. In Explorer, create a new file named Setup Television Shows Wizard.al and use Editor to create a new empty page object as follows:
page 50107 "Load Television Shows Wizard"
{
Caption = 'Load Television Shows';
PageType = NavigatePage;

layout
{
area(content)
{

}
}

actions
{
area(processing)
{

}
}
}
Wizard pages are defined using the NavigatePage page type.
  1. Following the standards from Microsoft for Assisted Setup wizards, we need to add a couple of sections to show the banners on the page. This will give our wizard the same look and feel as the rest of the wizards in Business Central.

Add the following code to the area(content) section:

group(StandardBanner)
{
Caption = '';
Editable = false;
Visible = TopBannerVisible and not FinishActionEnabled;
field(MediaResourcesStandard; MediaResourcesStandard."Media
Reference")
{
ApplicationArea = All;
Editable = false;
ShowCaption = false;
}
}
group(FinishedBanner)
{
Caption = '';
Editable = false;
Visible = TopBannerVisible and FinishActionEnabled;
field(MediaResourcesDone; MediaResourcesDone."Media
Reference")
{
ApplicationArea = All;
Editable = false;
ShowCaption = false;
}
}
  1. The first page of the wizard is the one that the users will see when they launch the wizard, so let's provide a welcoming message and some instructions as to what they are about to do and why they are doing it.

Add the following code to the area(content) section, after the group(FinishedBanner) section:

group(Step1)
{
Visible = Step1Visible;
group(Welcome)
{
Caption = 'Welcome to the Television Shows
application!';
Visible = Step1Visible;
group(Welcome1)
{
Caption = '';
InstructionalText = 'This wizard will let you
select which genre of television shows we
should load for sample data.';
}
}
group(LetsGo)
{
Caption = 'Let''s go!';
group(LetsGo1)
{
Caption = '';
InstructionalText = 'Press Next to continue.';
}
}
}
  1. The second page in the wizard is where the user should start making decisions that will drive the setup that we're building. In our case, we want them to select what genres of television shows we will load into the system.

Add the following code to the area(content) section, after the group(step1) section:

group(step2)
{
Caption = '';
InstructionalText = 'Select the genre(s) of television
shows you want to load.';
Visible = Step2Visible;

field(Genre1Selected; Genre1Selected)
{
Caption = 'Comedy';
ApplicationArea = All;
}
field(Genre2Selected; Genre2Selected)
{
Caption = 'Drama';
ApplicationArea = All;
}
field(Genre3Selected; Genre3Selected)
{
Caption = 'Family';
ApplicationArea = All;
}
}
  1. Now that we've laid out the different screens within the wizard, we need to add the navigation button logic. There are three buttons that need to be defined for a wizard: Back, Next, and Finish.

Add the following code to the area(processing) section:

action(ActionBack)
{
ApplicationArea = All;
Caption = 'Back';
Enabled = BackActionEnabled;
Image = PreviousRecord;
InFooterBar = true;
trigger OnAction();
begin
NextStep(true);
end;
}
action(ActionNext)
{
ApplicationArea = All;
Caption = 'Next';
Enabled = NextActionEnabled;
Image = NextRecord;
InFooterBar = true;
trigger OnAction();
begin
NextStep(false);
end;
}
action(ActionFinish)
{
ApplicationArea = All;
Caption = 'Finish';
Enabled = FinishActionEnabled;
Image = Approve;
InFooterBar = true;
trigger OnAction();
begin
FinishAction();
end;
}
  1. The screens are done. The buttons are done. Now... the logic.

Add the following trigger code after the actions section:

trigger OnInit();
begin
LoadTopBanners();
end;

trigger OnOpenPage();
begin
Step := Step::Start;
EnableControls();
end;
  1. We need to make use of a lot of variables in order to manage the logic within the page. Add the following variables after the trigger code:
var
MediaRepositoryDone: Record "Media Repository";
MediaRepositoryStandard: Record "Media Repository";
MediaResourcesDone: Record "Media Resources";
MediaResourcesStandard: Record "Media Resources";
Step: Option Start,Finish;
BackActionEnabled: Boolean;
FinishActionEnabled: Boolean;
NextActionEnabled: Boolean;
Step1Visible: Boolean;
Step2Visible: Boolean;
TopBannerVisible: Boolean;
Genre1Selected: Boolean;
Genre2Selected: Boolean;
Genre3Selected: Boolean;
  1. Now, we need to add a number of small functions to help control the navigation within the wizard page, in order to show and hide the correct elements as the user navigates forward (and backward!) through the steps. 

Add the following functions after the variables section:

local procedure EnableControls();
begin
ResetControls();

case Step of
Step::Start:
ShowStep1;
Step::Finish:
ShowStep2;
end;
end;

local procedure FinishAction();
begin
TestGenresSelected();
LoadTelevisionShows();
CurrPage.Close();
end;

local procedure NextStep(Backwards: Boolean);
begin
if Backwards then
Step := Step - 1
ELSE
Step := Step + 1;

EnableControls();
end;

local procedure ShowStep1();
begin
Step1Visible := true;

FinishActionEnabled := false;
BackActionEnabled := false;
end;

local procedure ShowStep2();
begin
Step2Visible := true;

NextActionEnabled := false;
FinishActionEnabled := true;
end;

local procedure ResetControls();
begin
FinishActionEnabled := false;
BackActionEnabled := true;
NextActionEnabled := true;

Step1Visible := false;
Step2Visible := false;
end;
  1. And now add, the function to load the banners. This pulls icon information from pre-loaded data in Business Central.

Add this code after the previous set of functions:

local procedure LoadTopBanners();
begin
if MediaRepositoryStandard.GET('AssistedSetup-NoText-
400px.png', FORMAT(CurrentClientType())) AND
MediaRepositoryDone.GET('AssistedSetupDone-NoText-
400px.png', FORMAT(CurrentClientType()))
then
if MediaResourcesStandard.GET(MediaRepositoryStandard
."Media Resources Ref") AND
MediaResourcesDone.GET(MediaRepositoryDone."Media
Resources Ref")
then
TopBannerVisible := MediaResourcesDone."Media
Reference".HasValue();
end;
  1. And finally... a function that ensures that the user has selected at least one genre, and a function to call the routine that loads the television shows. 

Add this code after the previous set of functions:

local procedure TestGenresSelected()
var
NothingSelectedConfirmLbl: Label 'You did not
select any genres so no data will be loaded.
Are you sure you want to exit?';
begin
if (not Genre1Selected) and (not Genre2Selected)
and (not Genre3Selected) then
if not Confirm(NothingSelectedConfirmLbl,
false) then
Error('');
end;

local procedure LoadTelevisionShows();
var
LoadTelevisionShows: Codeunit "Load Television Shows";
begin
LoadTelevisionShows.LoadTelevisionShows(
Genre1Selected, Genre2Selected, Genre3Selected);
end;
  1. Okay, we've now defined our Assisted Setup wizard page and implemented the logic to load the television shows based on which genres the user selects. Now, we need to make the wizard available to the user.

Similar to the Manual Setup area that we touched on in the previous recipe, there is a central place in Business Central from where we can access all the Assisted Setup wizards, and just like the Manual Setup area, we can add our new wizard simply by subscribing to an event.

In Explorer, create a new file named Register Assisted Setups.al, and in Editor, create a new codeunit object with the following subscriber code:

codeunit 50106 "Register Assisted Setups"
{
[EventSubscriber(ObjectType::Table, Database::"Aggregated
Assisted Setup", 'OnRegisterAssistedSetup', '', false,
false)]
local procedure OnRegisterAssistedSetup(var
TempAggregatedAssistedSetup: Record "Aggregated
Assisted Setup" TEMPORARY);
var
AssistedSetupRecord: Record "Television Show";
begin
TempAggregatedAssistedSetup.AddExtensionAssistedSetup(
Page::"Load Television Shows Wizard",
'Load Television Shows', True,
AssistedSetupRecord.RecordId(),
GetAssistedSetupStatus(
TempAggregatedAssistedSetup), '');
end;

When the user accesses the Assisted Setup area, our wizard will automatically be loaded into the area along with all the other wizards.

  1. One of the features of the Assisted Setup area is that it contains a status so that the user knows whether they've performed that particular configuration or not. In order to set and manage the status of our wizard, we need to add one more subscriber. Add the following function to our new codeunit object:
[EventSubscriber(ObjectType::Table, Database::"Aggregated Assisted Setup", 'OnUpdateAssistedSetupStatus', '', false, false)]
local procedure OnUpdateAssistedSetupStatus(var
TempAggregatedAssistedSetup: Record "Aggregated
Assisted Setup" TEMPORARY);
begin
TempAggregatedAssistedSetup.SetStatus(
TempAggregatedAssistedSetup, Page::"Load
Television Shows Wizard",
GetAssistedSetupStatus(TempAggregatedAssistedSetup));
end;
  1. And finally, we need to add a function that will tell the system when the Assisted Setup should be considered complete. This logic is likely to be different for each of your Assisted Setup wizards, as it depends on what the wizard is responsible for. 

In our scenario, when the television shows have been successfully loaded, we write to Television Show Setup Table that the wizard has been completed.

Add the following function to the codeunit object:

local procedure GetAssistedSetupStatus(AggregatedAssistedSetup: Record "Aggregated Assisted Setup"): Integer;
var
TelevisionShowSetup: Record "Television Show Setup";
begin
with AggregatedAssistedSetup do begin
if TelevisionShowSetup.Get() then begin
if TelevisionShowSetup."Finished Assisted Setup" then
Status := Status::Completed
else
Status := Status::"Not Completed";
end else
Status := Status::"Not Completed";
exit(Status);
end;
end;
  1. Wow, that's a lot of code, right!? Now, it's finally time to test it! Press F5 to build and publish your application:
    1. Switch to the Business Manager role center if you're not already in it. You can do that in My Settings.
    2. In the Business Manager role center, choose Assisted Setup.
    3. Our new Load Television Shows wizard is listed with a Status of Not Completed:

If you click on the name, then you can launch the wizard and walk through the steps, choosing one or more genres to load:

Once you choose the genre(s) and finish the wizard, you can go to the Television Show List to see the shows that have been loaded:

If you look back at the Assisted Setup area now, notice that the Status is now set to Complete, as in the given screenshot: