Dynamics 365 Business Central – how to use timers in AL

When still working in Dynamics NAV, you can easily add a timer to your page to allow, for instance, refreshes of the page in intervals. For that, you could use a Control Add-In called “Ping Pong”. Since we have no ability to use .Net anymore in AL, this ability went away and was not replaced with anything new yet.

While we have suggested already a different implementation to make this functionality available on all pages by default, it is not decided, if anything will be done. So, for now, we are stuck without the ability to update the page content on a periodic basis.

We can, however, create our own user control and rewrite the Ping Pong functionality. It only takes a few minutes to do:

Create a new user control in your project:

controladdin MyPingPong
{
    Scripts = 'js/MyPingPong.js';

    StartupScript = 'js/MyPingPongMain.js';

    HorizontalShrink = true;
    HorizontalStretch = true;
    MinimumHeight = 1;
    MinimumWidth = 1;
    RequestedHeight = 1;
    RequestedWidth = 1;
    VerticalShrink = true;
    VerticalStretch = true;

    procedure SetTimerInterval(milliSeconds: Integer);

    procedure StartTimer();

    procedure StopTimer();

    event ControlAddInReady();

    event PingPongError();

    event TimerElapsed();
}

Then add a new folder called “js” and place two new files in the folder.

File 1: MyPingPongMain.js:

$(document).ready(function() 
{ 
    initializeControlAddIn('controlAddIn');
});

File 2: MyPingPong.js

"use strict"

var timerInterval;
var timerObject;

function initializeControlAddIn(id) {
    var controlAddIn = document.getElementById(id);

    controlAddIn.innerHTML =
		'<div id="my-ping-pong">' +
		'</div>';
    pageLoaded();

	Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('ControlAddInReady', null);
}

function pageLoaded() {
}

function SetTimerInterval(milliSeconds) {
    timerInterval = milliSeconds;
}

function StartTimer() {
    if (timerInterval == 0 || timerInterval == null) {
        Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('PingPongError', ['No timer interval set.']);
        return;
    }

    timerObject = window.setInterval(ExecuteTimer, timerInterval);
}

function StopTimer() {
    clearInterval(timerObject);
}

function ExecuteTimer() {
    Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('TimerElapsed', null);
}

That’s it. Now you can add the user control to any page, as seen below in a page extension

pageextension 50000 "MyPingPong" extends "Customer Card"
{
    layout
    {
        addlast(General)
        {
            usercontrol(MyPingPong;MyPingPong)
            {
                ApplicationArea = Basic;

                trigger TimerElapsed()
                begin
                    CurrPage.MyPingPong.StopTimer();
                    Message('timer elapsed');
                    CurrPage.MyPingPong.StartTimer();
                end;
            }
        }
    }

    trigger OnAfterGetCurrRecord()
    begin
        CurrPage.MyPingPong.SetTimerInterval(2000);
        CurrPage.MyPingPong.StartTimer();
    end;
}

You will see that you will get a message shown every 2 seconds (the timer interval is in milliseconds). It is important to stop the timer when the timer has elapsed (trigger TimerElapsed) so that the timer is not trying to raise a new event while the message is still shown.

Obviously, you can add any code you want in the body of the TimerElapsed trigger.

 

This code does not have extensive error handling and is not quality controlled. You are going to use this code as a sample only and at your own risk. Support is not provided for this user control.

1 comment

    • Michael on September 24, 2019 at 12:36 pm
    • Reply

    The example hadn’t really worked well here with BC14. We made the following changes:

    Our MyPingPongMain.js looks this way:
    —————————-
    Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(‘ControlAddInReady’, null);
    —————————-

    Our MyPingPong.js looks like this:
    —————————-
    “use strict”

    var timerInterval;
    var timerObject;

    function SetTimerInterval(milliSeconds) {
    timerInterval = milliSeconds;
    }

    function StartTimer() {
    if (timerInterval == 0 || timerInterval == null) {
    Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(‘PingPongError’, [‘No timer interval set.’]);
    return;
    }

    timerObject = window.setInterval(ExecuteTimer, timerInterval);
    }

    function StopTimer() {
    clearInterval(timerObject);
    }

    function ExecuteTimer() {
    Microsoft.Dynamics.NAV.InvokeExtensibilityMethod(‘TimerElapsed’, null);
    }
    —————————-

    The user control is defined that way:
    —————————-
    controladdin aWFPingPong
    {
    Scripts = ‘js/MyPingPong.js’;

    StartupScript = ‘js/MyPingPongMain.js’;

    HorizontalShrink = true;
    HorizontalStretch = true;
    MinimumHeight = 1;
    MinimumWidth = 1;
    RequestedHeight = 1;
    RequestedWidth = 1;
    VerticalShrink = true;
    VerticalStretch = true;

    procedure SetTimerInterval(milliSeconds: Integer);

    procedure StartTimer();

    procedure StopTimer();

    event ControlAddInReady();

    event PingPongError(ErrorText: Text);

    event TimerElapsed();
    }
    —————————-

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.