Tip: Interface patterns give you an opportunity to explore different interface designs. Be sure to check out How to Adapt a Pattern for Your Application.
Use the duration display pattern to show the amount of time in between events in a quick, easy-to-read way. This page explains how you can use this pattern in your interface, and walks through the design structure in detail.
This page will break down this expression so you can better understand how to adapt this pattern to your own data so that it works to best suit your needs.
The main components in this pattern are side-by-side layouts and rich text. The image below displays how the pattern looks on a blank interface with callouts for the main components. You can examine the entire expression or jump down to the subsections below with referenced line numbers to see a detailed breakdown of the main components.
When you drag and drop the duration display pattern onto your interface, 139 lines of expressions will be added to the section where you dragged it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
{
a!localVariables(
local!events: {
a!map(name: "Opened", date: today() - 10),
a!map(name: "Closed", date: today())
},
local!duration: tointeger(local!events[2].date - local!events[1].date),
local!targetDuration: 10,
{
a!sideBySideLayout(
items: {
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: {
a!richTextItem(
text: text(local!events[1].date, "m/d"),
size: "MEDIUM_PLUS"
),
char(10),
a!richTextItem(
text: upper(local!events[1].name),
color: "SECONDARY"
)
},
align: "CENTER"
),
width: "MINIMIZE"
),
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: a!richTextItem(
/* You can change how many characters *
* display based on the page width */
text: repeat(
if(
a!isPageWidth("PHONE"),
2,
5
),
/* horizontal bar character */
char(9472)
),
color: "#ddd",
size: "LARGE",
style: "STRONG"
)
),
width: "MINIMIZE"
),
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: {
if(
local!duration > local!targetDuration,
a!richTextIcon(
icon: "exclamation-circle",
altText: "warning",
color: "NEGATIVE",
size: "MEDIUM_PLUS"
),
a!richTextIcon(
icon: "clock-o",
altText: "clock",
color: "SECONDARY",
size: "MEDIUM_PLUS"
)
),
" ",
a!richTextItem(
text: {
a!richTextItem(
text: local!duration,
style: "STRONG"
),
" ",
upper("Days")
},
size: "MEDIUM_PLUS"
)
},
/* Consider changing the tooltip and styling of the richText *
* if the duration is greater than a target value */
tooltip: if(
local!duration > local!targetDuration,
"Number of days between events exceeds target duration",
"Number of days between events"
),
align: "CENTER"
),
width: "MINIMIZE"
),
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: a!richTextItem(
/* You can change how many characters *
* display based on the page width */
text: repeat(
if(
a!isPageWidth("PHONE"),
2,
5
),
/* horizontal bar character */
char(9472)),
color: "#ddd",
size: "LARGE"
)
),
width: "MINIMIZE"
),
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: {
a!richTextItem(
text: text(local!events[2].date, "m/d"),
size: "MEDIUM_PLUS"
),
char(10),
a!richTextItem(
text: upper(local!events[2].name),
color: "SECONDARY"
)
},
align: "CENTER"
),
width: "MINIMIZE"
)
},
alignVertical: "MIDDLE",
spacing: "DENSE"
)
}
)
}
The local variables at the top of the expression are used to define:
The local!events
variable uses the a!map()
function to link the opened and closed values to their corresponding dates.
1
2
3
4
5
6
7
8
{
a!localVariables(
local!events: {
a!map(name: "Opened", date: today() - 10),
a!map(name: "Closed", date: today())
},
local!duration: tointeger(local!events[2].date - local!events[1].date),
local!targetDuration: 10,
This section:
The rich text divider is made of char(9472)
characters that creates a gray line in between the opened date and the rich text duration display.
Lines 36-44 conditionally change the width of the rich text divider using the a!isPageWidth()
function. The page width function allows you to determine the width of the page in which the interface is being displayed. Here, the function is used with an if()
statement to conditionally change how many char(9472)
characters are shown depending on the width of the page. This ensures that display will look good at all page widths.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{
a!sideBySideLayout(
items: {
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: {
a!richTextItem(
text: text(local!events[1].date, "m/d"),
size: "MEDIUM_PLUS"
),
char(10),
a!richTextItem(
text: upper(local!events[1].name),
color: "SECONDARY"
)
},
align: "CENTER"
),
width: "MINIMIZE"
),
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: a!richTextItem(
/* You can change how many characters *
* display based on the page width */
text: repeat(
if(
a!isPageWidth("PHONE"),
2,
5
),
/* horizontal bar character */
char(9472)
),
color: "#ddd",
size: "LARGE",
style: "STRONG"
)
),
width: "MINIMIZE"
),
This section uses an if()
statement to conditionally display the amount of days between the opened and closed dates or a warning icon. The warning icon only appears if the amount of days between the opened and closed date exceeds the target duration. If the amount of days exceeds the target duration, the tooltip will also display the message Number of days between events exceeds target duration
.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: {
if(
local!duration > local!targetDuration,
a!richTextIcon(
icon: "exclamation-circle",
altText: "warning",
color: "NEGATIVE",
size: "MEDIUM_PLUS"
),
a!richTextIcon(
icon: "clock-o",
altText: "clock",
color: "SECONDARY",
size: "MEDIUM_PLUS"
)
),
" ",
a!richTextItem(
text: {
a!richTextItem(
text: local!duration,
style: "STRONG"
),
" ",
upper("Days")
},
size: "MEDIUM_PLUS"
)
},
/* Consider changing the tooltip and styling of the richText *
* if the duration is greater than a target value */
tooltip: if(
local!duration > local!targetDuration,
"Number of days between events exceeds target duration",
"Number of days between events"
),
align: "CENTER"
),
width: "MINIMIZE"
),
This section contains:
This section is similar to the first set of side-by-side layouts, but in the reverse order.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: a!richTextItem(
/* You can change how many characters *
* display based on the page width */
text: repeat(
if(
a!isPageWidth("PHONE"),
2,
5
),
/* horizontal bar character */
char(9472)),
color: "#ddd",
size: "LARGE"
)
),
width: "MINIMIZE"
),
a!sideBySideItem(
item: a!richTextDisplayField(
labelPosition: "COLLAPSED",
value: {
a!richTextItem(
text: text(local!events[2].date, "m/d"),
size: "MEDIUM_PLUS"
),
char(10),
a!richTextItem(
text: upper(local!events[2].name),
color: "SECONDARY"
)
},
align: "CENTER"
),
width: "MINIMIZE"
)
},
alignVertical: "MIDDLE",
spacing: "DENSE"
)
}
)
}
Duration Display