Chapter 3: Interactive Notification Actions

Toast notifications provide information, but action buttons make them truly powerful by allowing users to respond directly. This chapter covers how to configure notification actions—clickable buttons that appear on notifications and trigger custom code in your Business Central environment.

You'll learn how action buttons work, how to configure them, best practices for designing user-friendly actions, and how to write the AL codeunits that execute when users click action buttons. By the end of this chapter, you'll be able to create notifications that not only inform users but also provide one-click access to relevant records, workflows, and operations.

3.1 Introduction to Notification Actions

What Are Notification Actions?

Notification actions are clickable buttons that appear on toast notifications. When a user clicks an action button, Business Central executes a codeunit procedure that you specify, allowing you to:

  • Navigate to the related record's card page

  • Open a list filtered to relevant records

  • Launch a report

  • Execute a business process (approve, reject, mark as complete)

  • Open external applications or websites

  • Display additional detail pages

Action Button Appearance:

Action buttons appear as text links at the bottom of the notification toast:

┌──────────────────────────────────────────────┐
│ Order SO-001 requires approval - $25,000  [X]│
│                                              │
│ [Approve]  [Reject]  [View Order]

Users can click any button to trigger the associated action, or click [X] to dismiss the notification without taking action.

Why Use Action Buttons:

Without Actions:

  1. User sees notification: "Order SO-001 requires approval"

  2. User must search for "Sales Orders"

  3. User must find SO-001 in the list

  4. User opens the order

  5. User processes the approval

With Actions:

  1. User sees notification: "Order SO-001 requires approval"

  2. User clicks [Approve] button

  3. Approval executes immediately (or opens approval page)

  4. Done

Action buttons eliminate navigation steps and reduce the time between notification and response.

📋 NOTE: Action buttons are optional. Simple informational notifications don't need actions. Reserve actions for notifications where users might want to respond immediately or need to view additional context.

How Notification Actions Work

Understanding the technical flow helps you design effective actions:

Configuration Side (Your Work):

  1. Create the notification: Configure message text, triggers, scenarios

  2. Add action rows: Define button captions and specify codeunit/procedure names

  3. Write action codeunit: Create AL code that executes when button clicked

  4. Deploy: Publish the extension containing your action codeunit

Runtime Side (What Happens):

  1. Trigger fires: Business event occurs matching your notification trigger

  2. Notification displays: Toast appears with message and action buttons

  3. User clicks button: User clicks one of the action buttons

  4. System locates codeunit: Business Central finds the codeunit ID you specified

  5. Procedure executes: The named procedure runs with notification context

  6. Action completes: Code navigates to page, processes data, or shows results

Data Flow:

When your action procedure executes, Business Central passes a notification object containing:

  • All data fields you configured (with placeholders resolved to values)

  • The notification message text

  • Metadata about the notification

Your code can extract data field values and use them to locate records, pass parameters to pages, or make business decisions.

💡 TIP: Think of action buttons as shortcuts. They should take users directly to what they need or perform the exact operation they want. Avoid actions that require multiple additional steps after clicking.

Action Design Principles

Well-designed actions enhance user productivity. Poorly designed actions frustrate users and reduce notification effectiveness.

Principle 1: Actions Should Be Obvious

Button captions should clearly communicate what will happen:

Good: [View Order], [Approve], [Open Customer Card] Poor: [Click Here], [More], [Details]

Users should know exactly what to expect before clicking.

Principle 2: Limit Action Count

Too many buttons create decision paralysis:

Recommended: 1-3 actions per notification Maximum: 4 actions (more won't fit in notification space)

Prioritize the most common or important actions.

Principle 3: Primary Action First

Place the most important or most commonly-used action first (leftmost):

[Approve]  [View Order]  [Reject]

Users naturally gravitate toward the first button.

Principle 4: Actions Should Be Non-Destructive (Usually)

Notification actions execute immediately when clicked, without confirmation dialogs in most cases. Avoid destructive operations unless the notification makes consequences absolutely clear.

Safe: View record, open page, filter list, display report Risky: Delete record, post document, modify data

If an action will modify data, make it obvious in both the notification message and the button caption:

Notification: Order SO-001 ready to post
Actions: [Post Now]  [View Order]  [Cancel]

Principle 5: Actions Should Complete Quickly

Users click action buttons and expect near-instant response. Actions that take more than a few seconds feel broken.

Fast: Open page, navigate to record Slower: Run calculations, generate reports Too Slow: Process entire batch, lengthy integrations

For long-running operations, consider having the action button queue a background job rather than executing synchronously.

✅ EXAMPLE - Well-Designed Actions:

Scenario: Purchase order approval notification

Notification Text: PO-1234 awaits approval - $50,000 from Fabrikam

Actions:

  • [Approve]: Executes approval immediately

  • [View PO]: Opens purchase order card

  • [Reject]: Opens rejection dialog to capture reason

This provides the three most likely user responses with clear, actionable buttons.

3.2 Configuring Notification Actions

Adding Actions to Notifications

Action configuration happens on the notification card in the Notification Action subpage.

Procedure: Add an Action Button

  1. Open your notification card (or create a new notification)

  2. Scroll to the Notification Action subpage

  3. Click to add a new line in the grid

  4. Configure three required fields:

    • Action Caption: The button text users see

    • Action Codeunit Id: The numeric ID of the codeunit to execute

    • Action Procedure: The procedure name within that codeunit

  5. Add additional action rows for more buttons

  6. Save the notification

Field Descriptions:

Action Caption (Text[50]):

  • The label displayed on the button

  • Maximum 50 characters

  • Should be concise (1-3 words ideal)

  • Use title case: "View Order" not "view order"

  • Active voice: "Approve" not "Approval"

Action Codeunit Id (Integer):

  • The numeric object ID of the codeunit containing your action code

  • Must be a codeunit in your environment (standard or custom)

  • Custom codeunits typically range 50000-99999

  • Verify the codeunit exists before saving

Action Procedure (Text[128]):

  • The exact name of the procedure to execute

  • Must match precisely (case-sensitive)

  • The procedure must accept a Notification parameter

  • No parentheses or parameters in this field—just the procedure name

✅ EXAMPLE - Action Configuration:

Action Caption

Action Codeunit Id

Action Procedure

View Order

50100

OpenSalesOrderCard

Approve

50100

ApproveSalesOrder

Reject

50100

RejectSalesOrder

This configuration creates three buttons. When clicked, each button calls a different procedure in codeunit 50100.

📋 NOTE: The Action Codeunit Id and Action Procedure must point to code that exists in your environment. If the codeunit or procedure doesn't exist, clicking the button will result in a runtime error.

Action Button Ordering

Action buttons appear in the notification in the same order as rows in the Notification Action subpage:

Subpage Order:


Notification Display:

[View Order]  [Approve]  [Reject]

To change button order, you must delete and re-add rows in the desired sequence. There's no drag-and-drop reordering.

💡 TIP: Plan your action order before adding rows. It's easier to add them in the correct sequence than to delete and recreate them later.

Writing Action Codeunits

Action codeunits contain the AL code that executes when users click notification buttons. You'll need basic AL programming knowledge and access to development tools (Visual Studio Code with the AL extension).

Minimum Action Procedure Structure:

codeunit 50100 "Notification Action Handler"
{
    procedure OpenSalesOrderCard(var NotificationToSend: Notification)
    var
        SalesHeader: Record "Sales Header";
        OrderNo: Text;
    begin
        // Extract data from notification
        OrderNo := NotificationToSend.GetData('OrderNo');
        
        // Locate the record
        SalesHeader.SetRange("No.", OrderNo);
        if SalesHeader.FindFirst() then begin
            // Open the card page
            Page.Run(Page::"Sales Order", SalesHeader);
        end;
    end;
}

Key Elements:

  1. Parameter: Procedure must accept var NotificationToSend: Notification

  2. GetData(): Extracts data field values by caption name

  3. Record Navigation: Locates the specific record

  4. Page.Run(): Opens the desired page

Data Field Access:

Your action code retrieves notification data fields using GetData():

OrderNo := NotificationToSend.GetData('OrderNo');
CustomerName := NotificationToSend.GetData('CustomerName');
Amount := NotificationToSend.GetData('Amount');

The string parameter must match the Data Caption exactly (case-sensitive).

This is why consistent data field naming (Chapter 2.5) matters—your action code depends on it.

Common Action Patterns:

Pattern 1: Open Record Card

procedure OpenCustomerCard(var NotificationToSend: Notification)
var
    Customer: Record Customer;
    CustomerNo: Text;
begin
    CustomerNo := NotificationToSend.GetData('CustomerNo');
    if Customer.Get(CustomerNo) then
        Page.Run(Page::"Customer Card", Customer);
end;

Pattern 2: Open Filtered List

procedure ShowOverdueInvoices(var NotificationToSend: Notification)
var
    SalesInvoiceHeader: Record "Sales Invoice Header";
    CustomerNo: Text;
begin
    CustomerNo := NotificationToSend.GetData('CustomerNo');
    SalesInvoiceHeader.SetRange("Sell-to Customer No.", CustomerNo);
    SalesInvoiceHeader.SetFilter("Due Date", '<%1', Today);
    Page.Run(Page::"Posted Sales Invoices", SalesInvoiceHeader);
end;

Pattern 3: Execute Business Logic

procedure ApprovePurchaseOrder(var NotificationToSend: Notification)
var
    PurchaseHeader: Record "Purchase Header";
    OrderNo: Text;
    ApprovalMgt: Codeunit "Approvals Mgmt.";
begin
    OrderNo := NotificationToSend.GetData('OrderNo');
    if PurchaseHeader.Get(PurchaseHeader."Document Type"::Order, OrderNo) then begin
        ApprovalMgt.ApprovePurchaseDocument(PurchaseHeader);
        Message('Purchase Order %1 approved successfully.', OrderNo);
    end;
end;

Pattern 4: Launch Report

procedure PrintSalesOrder(var NotificationToSend: Notification)
var
    SalesHeader: Record "Sales Header";
    OrderNo: Text;
begin
    OrderNo := NotificationToSend.GetData('OrderNo');
    SalesHeader.SetRange("No.", OrderNo);
    if SalesHeader.FindFirst() then
        Report.Run(Report::"Standard Sales - Order Conf.", true, false, SalesHeader);
end;

⚠️ WARNING: Action procedures execute in the user's security context with their permissions. Always validate data and check permissions within your code. Don't assume all users can perform all actions.

Error Handling in Action Code

Robust action code handles errors gracefully:

Basic Error Handling:

procedure OpenSalesOrderCard(var NotificationToSend: Notification)
var
    SalesHeader: Record "Sales Header";
    OrderNo: Text;
begin
    OrderNo := NotificationToSend.GetData('OrderNo');
    
    if OrderNo = '' then
        Error('Order number not found in notification data.');
    
    SalesHeader.SetRange("No.", OrderNo);
    if not SalesHeader.FindFirst() then
        Error('Sales Order %1 does not exist.', OrderNo);
    
    Page.Run(Page::"Sales Order", SalesHeader);
end;

User-Friendly Messages:

When errors occur, provide clear explanations:

Good: Error('Sales Order %1 no longer exists. It may have been deleted.', OrderNo); Poor: Error('Record not found.');

Users need to understand what went wrong and what (if anything) they can do about it.

💡 TIP: Consider using Message() instead of Error() for non-fatal issues. Errors stop execution and close the notification. Messages inform users but allow them to continue or try other actions.

3.3 Action Button Best Practices

Designing Effective Button Captions

Button captions are critical to user experience:

Caption Guidelines:

1. Use Action Verbs:

  • Start with a verb: View, Open, Approve, Reject, Create, Send, Print

  • Verbs communicate action clearly

2. Be Specific:

  • "View Order" is better than "View"

  • "Open Customer Card" is better than "Open"

  • Context helps when multiple notifications are visible

3. Keep It Short:

  • Target 1-2 words

  • Maximum 3-4 words

  • Long captions may truncate on small screens

4. Match Business Language:

  • Use terms your users know

  • "Approve" not "Accept Approval Request"

  • "View Invoice" not "Open Posted Sales Invoice Header"

5. Avoid Technical Jargon:

  • "View Details" not "Open Record Page"

  • "Print" not "Run Report 10074"

Caption Examples:

Notification Context

Good Captions

Poor Captions

Order approval

Approve, Reject, View Order

Yes, No, More Info

Low inventory

Reorder, View Item, Ignore

OK, Click, See Details

Payment received

Apply Payment, View Customer

Process, Open, Continue

Document ready

Print, Email, View

Report, Send, Details

Multi-Button Coordination

When providing multiple actions, ensure they work together logically:

Complementary Actions:

Buttons should offer different types of responses:

Good Set:

  • [Approve] - Takes positive action

  • [View Order] - Provides context

  • [Reject] - Takes negative action

Poor Set:

  • [View Order]

  • [Open Order]

  • [Show Order]

Three buttons that do essentially the same thing waste space.

Action Hierarchy:

Order buttons by importance and frequency:

1. Primary Action (most common response):

  • Approve, Accept, Confirm, Continue

2. Information Action (view context):

  • View Record, Open Page, Show Details

3. Alternative Action (less common response):

  • Reject, Cancel, Ignore, Dismiss

4. Destructive Action (rare, dangerous):

  • Delete, Remove, Clear

✅ EXAMPLE - Action Hierarchy in Practice:

Scenario: Approval request notification

Primary: [Approve] - Most users will approve most requests Information: [View Request] - Some users need context before deciding Alternative: [Reject] - Least common response

This ordering matches natural user workflow.

Performance Optimization

Action code should execute quickly to maintain responsive user experience:

Optimization Techniques:

1. Minimize Database Queries:

// Poor: Multiple Get() calls
Customer.Get(CustomerNo);
SalesHeader.Get(SalesHeader."Document Type"::Order, OrderNo);
SalesLine.SetRange("Document No.", OrderNo);
SalesLine.FindSet();

// Better: Retrieve only what's needed
if SalesHeader.Get(SalesHeader."Document Type"::Order, OrderNo) then
    Page.Run(Page::"Sales Order", SalesHeader);

2. Avoid Unnecessary Calculations:

// Poor: Calculate totals in action code
SalesLine.SetRange("Document No.", OrderNo);
if SalesLine.FindSet() then
    repeat
        Total += SalesLine."Line Amount";
    until SalesLine.Next() = 0;

// Better: Use FlowFields or open page (page calculates totals)
Page.Run(Page::"Sales Order", SalesHeader);

3. Use Direct Navigation:

// Fast: Direct page open
Page.Run(Page::"Customer Card", Customer);

// Slower: Multiple page opens or dialogs
Message('Opening customer card...');
Page.Run(Page::"Customer List");  // Unnecessary intermediate step
Page.Run(Page::"Customer Card", Customer);

4. Defer Long Operations:

// Poor: Long-running operation blocks UI
Report.Run(Report::"Calculate Inventory", false, false);

// Better: Queue as background job
JobQueueEntry.ScheduleReport(Report::"Calculate Inventory");
Message('Report queued for background processing.');

📋 NOTE: Users expect action buttons to respond in under 1 second. If your action requires longer processing, consider displaying a progress dialog or queuing a background job.

Testing Action Buttons

Thorough testing prevents user frustration:

Test Checklist:

1. Code Compilation:

  • Codeunit compiles without errors

  • Procedure signature matches requirements

  • All referenced objects exist

2. Configuration:

  • Codeunit ID is correct

  • Procedure name matches exactly (case-sensitive)

  • Data field captions match GetData() calls

3. Functional Testing:

  • Button appears on notification

  • Button caption is clear and properly formatted

  • Clicking button executes expected action

  • Record navigation opens correct record

  • Data values are correct

4. Error Scenarios:

  • Handles missing data fields gracefully

  • Handles deleted records (record no longer exists)

  • Handles permission errors (user lacks access)

  • Provides clear error messages

5. User Experience:

  • Action completes quickly (< 1 second ideal)

  • Result is obvious to user

  • No confusing intermediate steps

  • Works across all clients (web, desktop, mobile)

💡 TIP: Create a test user with limited permissions and test action buttons with that account. This helps identify permission-related issues before production deployment.

This completes Chapter 3. Users now understand how notification actions work, how to configure them, how to write action codeunits, and best practices for designing effective, user-friendly action buttons.

Get Your FREE Dynamics 365 Demo

Transform your business operations with Microsoft Dynamics 365 Business Central

Experience the transformative power of Microsoft Dynamics 365 Business Central for yourself! Request a free demo today and see how our solutions can streamline your operations and drive growth for your business.

Our team will guide you through a personalized demonstration tailored to your specific needs. This draft provides a structured approach to presenting Qualia Tech's offerings related to Microsoft Dynamics 365 Business Central while ensuring that potential customers understand the value proposition clearly.

Areas Of Interest

Please read and confirm the following:

*Note: Fields marked with * are mandatory for processing your request.

*Note: Fields marked with * are mandatory for processing your request.

© 2024 Qualia. All rights reserved

© 2024 Qualia. All rights reserved

© 2024 Qualia. All rights reserved

© 2024 Qualia. All rights reserved