Graphical Planner
Cards
The Cards control add-in displays simple data in the form of cards, such as quantities over a week. Each card can contain two pieces of information, represented as a small label and a large label (title and subtitle). The control add-in can also render separators (vertical lines) between cards.
The Cards control can maintain an internal state of the clicked card.
Triggers
OnControlReady()
Triggers after the control is ready to be used.
OnCardSelect(cardId: Text)
Triggers after a card is clicked.
Parameters:
cardId
: The identifier of the clicked card, as provided to theRender
procedure.
Procedures
Render(Cards: JsonArray)
Renders the provided list of cards.
Parameters:
Cards
: The JSON list of cards. Each card is an object with the following keys:id
: A unique identifier for the card, passed with theOnCardSelected
event.title
: A string representing the title of the card.subtitle
: A string representing the subtitle of the card.color
: One of the strings"gray"
,"teal"
, or"red"
. Optional. Default is"gray"
.separator
: A boolean indicating whether the object should be rendered as a separator instead of a card. Optional. Default isfalse
.
For separators, other properties are not applicable and can be left out.
This method should be called only after the OnControlReady
event is triggered.
SetSelected(Id: Text)
Sets the selected card.
Parameters:
Id
: The ID of the card, as provided to theRender
method.
This method should be called only after the OnControlReady
event is triggered.
SetConfig(Config: JsonObject)
Configures the control add-in. Configuration will be applied only after the next Render
call.
Parameters:
Config
: A configuration object that can contain the following keys:height
: The height of the control add-in in pixels. Default is 100.keepSelectionState
: A boolean indicating whether the control should maintain the state of the selected card. Default istrue
.
Example
This example renders the control as shown in the screenshot above.
page 55000 Cards
{
ApplicationArea = All;
Caption = 'Cards control';
PageType = Card;
layout
{
area(Content)
{
group(CardsGroup)
{
Caption = 'Cards';
usercontrol(CardsUserControl; "Cards CCE")
{
trigger OnControlReady()
begin
RenderCards();
end;
trigger OnCardSelected(cardId: Text)
begin
Message(cardId);
end;
}
}
}
}
local procedure RenderCards()
var
Cards: JsonArray;
Json: Text;
begin
// Note: The following code is for example purposes only.
// You should always use standard BC methods for creating JSON objects,
// rather than parsing a string directly.
Json := '[';
Json += '{"id":"1", "title":"Monday", "subtitle":"5%"},';
Json += '{"id":"2", "title":"Tuesday", "subtitle":"10%"},';
Json += '{"id":"3", "title":"Thursday", "subtitle":"35%"},';
Json += '{"id":"4", "title":"Wednesday", "subtitle":"2%"},';
Json += '{"id":"5", "title":"Friday", "subtitle":"20%"},';
Json += '{"id":"", "title":"", "subtitle":"", "separator": true},';
Json += '{"id":"6", "title":"Saturday", "subtitle":"8%", "color": "red"},';
Json += '{"id":"7", "title":"Sunday", "subtitle":"20%", "color": "red"}';
Json += ']';
Cards.ReadFrom(Json);
CurrPage.CardsUserControl.Render(Cards);
end;
}
Timetable
The Timetable control add-in displays events with defined start and end times. The timetable can represent any time period with any period division, such as days over a month or 15-minute intervals over a workday. Each entry (reserved period in the timetable) can last for an arbitrary duration.
Triggers
OnControlReady()
Triggers after the control is ready to be used. All procedures should be called only after this trigger.
OnEntryClick(EntryId: Text)
Triggers when an entry is clicked.
OnRowClick(RowId: Text)
Triggers when a row title is clicked.
OnMomentClick(Timestamp: Text; GroupId: Text)
Triggers when a non-reserved moment in the timetable is clicked.
Procedures
Render(Rows: JsonArray; Moments: JsonArray)
Parameters:
Rows
: Entries should be grouped into row objects. Each row should be a JSON object with the following keys:id
: A unique identifier for the row;title
: A string representing the title of a group;entries
: A list of entry objects as described above. Each entry should be a JSON object with the following keys:id
: A string representing the unique identifier of an entry, returned with theOnEntrySelected
event;title
: A string representing the title of the entry;start
: A date string representing the start of an entry;end
: A date string representing the end of an entry;style
: One of the strings"gray"
,"teal"
, or"red"
. Optional. Default is"gray"
;enabled
: A boolean representing whether an entry is enabled. Disabled entries are not clickable. Optional. Default istrue
.
Moments
: Each moment should be a JSON object with the following keys:start
: A date string representing the start of an entry;end
: A date string representing the end of an entry;strong
: A boolean representing whether a (left) dividing line is darker. Optional. Defaultfalse
;label
: A string representing label that is shown on top of the timetable. Optional. Default""
;
All date strings should be in ISO 8601 format (e.g., 2024-01-31T10:00:00Z
).
This method should be called only after the OnControlReady
event is triggered.
Example
This example renders the control as shown in the screenshot above.
page 55001 "Timetable"
{
ApplicationArea = All;
Caption = 'Timetable';
PageType = Card;
layout
{
area(Content)
{
group(TimetableGroup)
{
Caption = 'Timetable';
usercontrol(TimeTableControl; "Timetable CCE")
{
trigger OnControlReady()
begin
RenderTimetable();
end;
trigger OnEntryClick(EntryId: Text)
begin
Message(EntryId);
end;
trigger OnRowClick(RowId: Text)
begin
Message(RowId);
end;
}
}
}
}
local procedure RenderTimetable()
var
GPU: Codeunit "GraphicPlannerUtils CCE";
Style: Enum "GraphicPlannerElementStyle CCE";
Rows, Row1Entries, Row2Entries, Row3Entries, Moments : JsonArray;
Row1, Row2, Row3 : JsonObject;
Minute: Integer;
StartOfPlanner: DateTime;
begin
Minute := 60 * 1000;
StartOfPlanner := CreateDateTime(20240809D, 170000T);
Moments := GPU.CreateIntervals(
StartOfPlanner, StartOfPlanner + 2 * 60 * Minute, 5 * Minute, 3, '<Hours24>:<Minutes,2>', 12);
Row1Entries.Add(
GPU.CreateEntry('1', 'Reservation 1', StartOfPlanner, StartOfPlanner + 20 * Minute, Style::Gray));
Row1Entries.Add(
GPU.CreateEntry('2', 'Reservation 2', StartOfPlanner + 36 * Minute, StartOfPlanner + 50 * Minute, Style::Red));
Row1.Add('id', 'row1');
Row1.Add('title', 'Location 1');
Row1.Add('entries', Row1Entries);
Rows.Add(Row1);
Row2Entries.Add(
GPU.CreateEntry('3', 'Reservation 1', StartOfPlanner + 23 * Minute, StartOfPlanner + 70 * Minute, Style::Teal));
Row2Entries.Add(
GPU.CreateEntry('4', 'Reservation 2', StartOfPlanner + 90 * Minute, StartOfPlanner + 110 * Minute, Style::Gray));
Row2.Add('id', 'row2');
Row2.Add('title', 'Location 2');
Row2.Add('entries', Row2Entries);
Rows.Add(Row2);
Row3.Add('id', 'row3');
Row3.Add('title', 'Location 3');
Row3.Add('entries', Row3Entries);
Rows.Add(Row3);
CurrPage.TimeTableControl.Render(Rows, Moments);
end;
}
Helper Codeunit GraphicPlannerUtils
Procedures
CreateCard(Id: Text; Title: Text; Subtitle: Text; Style: Enum "GraphicPlannerElementStyle CCE"): JsonObject
Creates a single card.
Parameters:
Id
: The ID of the card.Title
: The title of the card.Subtitle
: The subtitle of the card.Style
: The card’s style.
CreateCard(Id: Text; Title: Text; Subtitle: Text): JsonObject
Creates a single Teal card.
CreateWeekCards(Monday: Text; Tuesday: Text; Wednesday: Text; Thursday: Text; Friday: Text; Saturday: Text; Sunday: Text): JsonArray
Creates an array of cards with names of the weekdays from ‘Monday’ to ‘Sunday’ as titles.
Parameters: List of subtitles for each day.
CreateWeekCards(Monday: Text; Tuesday: Text; Wednesday: Text; Thursday: Text; Friday: Text): JsonArray
Creates an array of cards with names of the weekdays from ‘Monday’ to ‘Friday’ as titles.
Parameters: List of subtitles for each day.
CreateDayIntervals(StartDate: Date; EndDate: Date): JsonArray
Creates an array of days from the start date to the end date. Each interval lasts 24 hours.
CreateIntervals(StartMoment: DateTime; EndMoment: DateTime; IntervalDuration: Duration; FormatEach: Integer; FormatString: Text; StrongEach: Integer): JsonArray
Creates an array of intervals.
CreateEntry(Id: Text; Title: Text; StartMoment: DateTime; EndMoment: DateTime; Style: Enum "GraphicPlannerElementStyle CCE"): JsonObject
Creates a JSON object representing a single timetable entry.
Parameters:
Id
: The unique ID of the entry.Title
: The title of the entry.StartMoment
: The start time of the entry.EndMoment
: The end time of the entry.Style
: The entry’s style.