Milestone Stamp

Interface patterns give you an opportunity to explore different interface designs. Be sure to check out How to Adapt a Pattern for Your Application.

Goal

Use the milestone stamp pattern to visually guide users through sequential steps to complete tasks and show users their progress as they move through the steps. This page explains how you can use this pattern in your interface, and walks through the design structure in detail.

milestone_stamp.png

Design structure

The main components of this pattern are stamps, rich text display fields, and side by side layouts. These components are configured to display the progress of a given task. The image below displays how the pattern looks on a blank interface with callouts of the main components. You can examine the entire expression or jump down to the subsections with referenced line numbers to see a detailed breakdown of the main components.

milestone_stamp_details.png

Pattern expression

When you drag and drop the milestone (stamp) pattern onto your interface, 135 lines of expression 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
{
  a!localVariables(
    /* List of icons in milestone (stamp) */
    local!milestoneStampIcons: {"paper-plane-o", "truck", "wrench", "check"},
    local!currentMilestoneStampStep: 2,
    {
      /* Display stamps */
      a!sideBySideLayout(
        items: {
          a!sideBySideItem(),
          a!forEach(
            items: local!milestoneStampIcons,
            expression: if(
              /* If final step is completed */
              and(
                fv!index = local!currentMilestoneStampStep,
                fv!index = length(local!milestoneStampIcons)
              ),
              a!sideBySideItem(
                item: a!stampField(
                  backgroundColor: "ACCENT",
                  icon: fv!item,
                  size: "TINY"
                ),
                width: "MINIMIZE"
              ),
              if(
                /* Completed step so far */
                fv!index < local!currentMilestoneStampStep,
                {
                  a!sideBySideItem(
                    item: a!stampField(
                      backgroundColor: "ACCENT",
                      icon: fv!item,
                      size: "TINY"
                    ),
                    width: "MINIMIZE"
                  ),
                  a!sideBySideItem(
                    item: a!richTextDisplayField(
                      labelPosition: "COLLAPSED",
                      value: a!richTextItem(
                        text: if(
                          a!isNativePhone(),
                          repeat(2, char(9473)),
                          repeat(6, char(9473))
                        ),
                        color: "ACCENT",
                        size: "LARGE"
                      )
                    ),
                    width: "MINIMIZE"
                  )
                },
                if(
                  /* Current completed step */
                  fv!index = local!currentMilestoneStampStep,
                  {
                    a!sideBySideItem(
                      item: a!stampField(
                        backgroundColor: "ACCENT",
                        icon: fv!item,
                        size: "TINY"
                      ),
                      width: "MINIMIZE"
                    ),
                    a!sideBySideItem(
                      item: a!richTextDisplayField(
                        labelPosition: "COLLAPSED",
                        value: a!richTextItem(
                          text: if(
                            a!isNativePhone(),
                            repeat(2, char(9473)),
                            repeat(6, char(9473))
                          ),
                          color: "#d4d4d4",
                          size: "LARGE"
                        )
                      ),
                      width: "MINIMIZE"
                    )
                  },
                  /* Future steps to complete */
                  if(
                    fv!index < length(local!milestoneStampIcons),
                    {
                      a!sideBySideItem(
                        item: a!stampField(
                          backgroundColor: "#d4d4d4",
                          icon: fv!item,
                          contentColor: "STANDARD",
                          size: "TINY"
                        ),
                        width: "MINIMIZE"
                      ),
                      a!sideBySideItem(
                        item: a!richTextDisplayField(
                          labelPosition: "COLLAPSED",
                          value: a!richTextItem(
                            text: if(
                              a!isNativePhone(),
                              repeat(2, char(9473)),
                              repeat(6, char(9473))
                            ),
                            color: "#d4d4d4",
                            size: "LARGE"
                          )
                        ),
                        width: "MINIMIZE"
                      )
                    },
                    /* If final step is incomplete */
                    a!sideBySideItem(
                      item: a!stampField(
                        backgroundColor: "#d4d4d4",
                        icon: fv!item,
                        contentColor: "STANDARD",
                        size: "TINY"
                      ),
                      width: "MINIMIZE"
                    )
                  )
                )
              )
            )
          ),
          a!sideBySideItem()
        },
        alignVertical: "MIDDLE",
        spacing: "NONE",
        marginBelow: "NONE"
      )
    }
  )
}

[Line 1-5] Define the stamps for each milestone

At the top of the pattern, local variables set up an array of icons that will be used as stamps for each milestone in the expression.

1
2
3
4
5
{
  a!localVariables(
    /* List of icons in milestone (stamp) */
    local!milestoneStampIcons: {"paper-plane-o", "truck", "wrench", "check"},
    local!currentMilestoneStampStep: 2,

[Line 6-26] Display your stamps

The first component we set up is the a!sideBySideLayout() function. Then, we list the different items we want to display side by side. Inside the items array, we use the a!forEach() looping function. We use this to iterate over every icon listed in the local variables section of the expression. Once the looping function is set up, we use the conditional if() statement to configure which milestone has been reached by the user and to display the correct highlighted icons. This kind of styling based on the data being displayed is recommended to make it easy for the viewer to quickly see how far their progress is on a task. Once the conditional styling is set up, we then use the a!stampField function to pick out the background color, icon, and size of the stamp we want to display.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    
{
      /* Display stamps */
      a!sideBySideLayout(
        items: {
          a!sideBySideItem(),
          a!forEach(
            items: local!milestoneStampIcons,
            expression: if(
              /* If final step is completed */
              and(
                fv!index = local!currentMilestoneStampStep,
                fv!index = length(local!milestoneStampIcons)
              ),
              a!sideBySideItem(
                item: a!stampField(
                  backgroundColor: "ACCENT",
                  icon: fv!item,
                  size: "TINY"
                ),
                width: "MINIMIZE"
              ),

[Line 39-53] Display your milestone

This section uses a!sidebySideItem() and a!richTextDisplayField() to display the milestone in the pattern. We also use a!isNativePhone to determine how to display the milestone on Appian for Mobile.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
!a!sideBySideItem(
!                    item: a!richTextDisplayField(
                      labelPosition: "COLLAPSED",
                      value: a!richTextItem(
                        text: if(
!                          a!isNativePhone(),
                          repeat(2, char(9473)),
                          repeat(6, char(9473))
                        ),
                        color: "ACCENT",
                        size: "LARGE"
                      )
                    ),
                    width: "MINIMIZE"
                  )

The rest of the pattern follows the same set up as the above sections to configure future milestone steps to complete and if the final milestone step is complete.

Open in Github

On This Page

FEEDBACK