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.
Allow a user to save their preferred filter on a report and automatically load it when they revisit the report later.
This scenario demonstrates:
Tip: Since users can save filters on a record list without any additional configuration, consider using the record list instead of using this recipe when displaying a grid of records.
For this recipe, you'll want to use a report with some actual data. If you haven't already set up the Update an Entity-Backed Record from its Summary View recipe, do that now you can use that recipe's entity-backed record.
Now on to the report! Before you put in the expression, you'll first need to create a place to store user filters:
SupportRequestReportFilter
in the Name field.username
for the first field's name.status
for the second field's name.priority
for the third field's name.Now that you've created the data type, you'll need to make a data store entity so you can write the data to your database.
SupportRequestReportFilter
in the Name field.SupportRequestReportFilter
in the Type field.Now you need to create a constant pointing at the data store entity so it can be used in an expression:
CSRS_FILTER_ENTITY
in the Name field.Data Store Entity
for the Type field.Support Requests
for the Data Store field.SupportRequestReportFilter
for the Entity field.Enter CSRS Rules and Constants
in the Save In field, then select the folder from the suggestions.
Now you're ready to build the actual report.
CSRS Rules and Constants
in the Save In field, then select the folder from the suggestions.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
a!localVariables(
local!persistedFilterData: a!queryEntity(
entity: cons!CSRS_FILTER_ENTITY,
query: a!query(
filter: a!queryFilter(field: "username", operator: "=", value: loggedInUser()),
pagingInfo: a!pagingInfo(startIndex: 1, batchSize: 1)
),
fetchTotalCount: true
),
local!persistedFilter: if(
local!persistedFilterData.totalCount = 0,
/* There's no existing filter for this user, so create a new one */
'type!{urn:com:appian:types}SupportRequestReportFilter'(username: loggedInUser()),
cast('type!{urn:com:appian:types}SupportRequestReportFilter', local!persistedFilterData.data[1])
),
local!saveFilterError: false,
/* Store the current filter separate from the persisted filter so we know when they are the same */
local!filter: local!persistedFilter,
local!allPriorities: rule!CSRS_GetAllPriority().value,
local!allStatuses: rule!CSRS_GetAllStatus().value,
local!pagingInfo: a!pagingInfo(1, -1, a!sortInfo("createdOn", false)),
local!filterChanged: not(exact(local!persistedFilter, local!filter)),
/* Data that will be displayed in the grid given the *
* current search terms and applied filters */
{
a!sectionLayout(
contents:{
a!columnsLayout(
columns:{
a!columnLayout(
contents:{
a!dropdownField(
label: "Priority",
labelPosition: "ADJACENT",
placeholder: "All Priorities",
choiceLabels: local!allPriorities,
choiceValues: local!allPriorities,
value: local!filter.priority,
saveInto: local!filter.priority
),
a!dropdownField(
label: "Status",
labelPosition: "ADJACENT",
placeholder: "All Statuses",
choiceLabels: local!allStatuses,
choiceValues: local!allStatuses,
value: local!filter.status,
saveInto: local!filter.status
)
}
),
a!columnLayout(
contents:{
a!buttonLayout(
secondaryButtons: {
if(
local!saveFilterError,
a!buttonWidget(
label: "Could not save filters",
disabled: true
),
a!buttonWidget(
label: "Save Filters",
disabled: not(local!filterChanged),
saveInto: a!writeToDataStoreEntity(
dataStoreEntity: cons!CSRS_FILTER_ENTITY,
valueToStore: local!filter,
onSuccess: {
a!save(local!persistedFilter, local!filter)
},
onError: {
a!save(local!saveFilterError, true)
}
)
)
)
}
)
}
)
}
)
}
),
a!gridField(
emptyGridMessage: "No Support Requests available",
data: a!queryEntity(
entity: cons!CSRS_SUPPORT_REQUEST_DSE,
query: a!query(
selection: a!querySelection(
columns: {
a!queryColumn(field: "id"),
a!queryColumn(field: "title"),
a!queryColumn(field: "status"),
a!queryColumn(field: "priority")
}
),
logicalExpression: a!queryLogicalExpression(
operator: "AND",
filters: {
a!queryFilter(
field: "status.value",
operator: "=",
value: local!filter.status
),
a!queryFilter(
field: "priority.value",
operator: "=", value:
local!filter.priority
)
},
ignoreFiltersWithEmptyValues: true
),
pagingInfo: fv!pagingInfo
),
fetchTotalCount: true
),
columns: {
a!gridColumn(
label: "Title",
sortField: "title",
value: fv!row.title
),
a!gridColumn(
label: "Status",
sortField: "status.value",
value: index(fv!row.status, "value", {})
),
a!gridColumn(
label: "Priority",
sortField: "priority.value",
value: a!imageField(
images: rule!CSRS_GetIconForPriority(index(fv!row.priority, "value", {}))
),
width: "NARROW",
align: "CENTER"
),
/*a!gridColumn(*/
/*label: "Priority",*/
/*sortField: "priority.value",*/
/*value: a!richTextDisplayField(*/
/*value: a!richTextIcon(*/
/*icon: displayvalue(*/
/*index(fv!row.priority, "value", {}),*/
/* Priority values */
/*{"Low", "Medium", "High", "Critical"},*/
/* Corresponding icons for each priority */
/*{"arrow-circle-down", "arrow-circle-right", "arrow-circle-up", "exclamation-circle"},*/
/*"circle"*/
/*),*/
/*size: "MEDIUM",*/
/*color: if(*/
/*contains(*/
/*{"High", "Critical"},*/
/*index(fv!row.priority, "value", {}),*/
/*),*/
/*"NEGATIVE",*/
/*"SECONDARY"*/
/*)*/
/*)*/
/*),*/
/*align: "CENTER",*/
/*width: "NARROW"*/
/*)*/
},
rowHeader: 1
)
}
)
a!localVariables()
variables so that they can be compared. Not only does this mean the user knows when they have changed the filter (because the button is enabled) but also provides feedback that the filters have been saved (when it becomes disabled).onError
parameter is used to change the button label.See also: Executing Smart Services
Save a User's Report Filters to a Data Store Entity