In the previous post of these series, I’ve talked about lookup localizations, and we’ll get back to the topic of localizations a bit later, but, right now, let’s see what can be done about custom lists.
GC Web does have a component for this: https://wet-boew.github.io/GCWeb/common/tables/table-en.html
Which is using DataTables plugin
So, just to illustrate, here is what that component can do (there is more, but this should give you an idea):
You can add columns, they are sortable, they are searchable, there is pagination, it reflows to render “cards” instead of rows on the smaller screens, etc.
Of course, re-implementing it for each and every page where you’d need a table could be painful, but, luckily, we can use web templates as components in Power Pages:
https://learn.microsoft.com/en-us/power-pages/configure/web-templates-as-components
Below, there is a version of that component used for the recording:
{% comment %}
columnOutputFilters - only supports "date" filter currently. Accepts a comma-separated string. Ex:,,date~yyyy-mm-dd,,,
{% endcomment %}
{% manifest %}
{
"type": "Functional",
"displayName": "GC Web Table",
"description": "Displays a GC Web table for a fetch query",
"params": [
{
"id": "Id",
"displayName": "Table Id",
"description": "DOM Elemeng Id"
},
{
"id": "query",
"displayName": "Query",
"description": "Fetch Xml Query"
},
{
"id": "columnTitles",
"displayName": "Column Titles",
"description": "List of column Titles"
},
{
"id": "columnTitleLabelNames",
"displayName": "Column Title Label Names",
"description": "List of column title label names"
},
{
"id": "columnDataAttributes",
"displayName": "Data Data Attributes",
"description": "List of attribute names for table columns"
},
{
"id": "columnOutputFilters",
"displayName": "Column Output Filters",
"description": "Column output filters"
},
{
"id": "columnSortingSupport",
"displayName": "Column Sorting",
"description": "Column Sorting (list, true/false)"
},
{
"id": "pageLength",
"displayName": "Default Page Length",
"description": "Default Page Length"
},
{
"id": "lengthMenu",
"displayName": "Length Menu",
"description": "Length Menu"
},
{
"id": "openUrl",
"displayName": "Open Url",
"description": "Open Url"
},
{
"id": "openUrlIdColumn",
"displayName": "Open Url Id Column",
"description": "Open Url Id Column"
}
]
}
{% endmanifest %}
{% assign titleList = columnTitles | split: "," %}
{% assign titleLabelList = columnTitleLabelNames | split: "," %}
{% assign dataAttributeList = columnDataAttributes | split: "," %}
{% assign outputFilterList = columnOutputFilters | split: "," %}
{% assign columnSortingSupportList = columnSortingSupport | split: "," %}
{% fetchxml queryResult %}
{{ query }}
{% endfetchxml %}
{% if titleList.size > 1 %}
{%assign column_count = titleList.size | minus: 1 %}
{% else %}
{%assign column_count = titleLabelList.size | minus: 1 %}
{% endif %}
<table class="provisional gc-table text-left wb-tables table table-striped" id="{{Id}}" data-wb-tables='{ "order" : [[0,"desc"]], "pageLength" : {{pageLength}}, "lengthMenu" : [{{lengthMenu}}] }'>
<thead>
<tr>
{% for i in (0..column_count) %}
{% if titleList.size > 1 %}
{% assign columnTitle = titleList[i] %}
{% assign columnTitleLabel = "" %}
{% else %}
{% assign columnTitleLabel = titleLabelList[i] %}
{% assign columnTitle = "" %}
{% endif %}
<th data-orderable="{{columnSortingSupportList[i]}}" >{{columnTitle}}</th>
{% endfor %}
{% if openUrl %}
<th data-orderable="false"></th>
{% endif %}
</tr>
</thead>
<tbody>
{% for record in queryResult.results.entities %}
<tr>
{% for i in (0..column_count) %}
{% assign column_name = dataAttributeList[i] %}
{% if (outputFilterList[i] startswith "date") %}
{% assign filterPair = outputFilterList[i] | split: '~' %}
<td data-label="{{titleList[i]}}" data-label="{{titleList[i]}}">{{record[column_name] | date: filterPair[1]}} </td>
{% else %}
<td data-label="{{titleList[i]}}">{{record[column_name]}} </td>
{% endif %}
{% endfor %}
{% comment %}
<td><a class="btn btn-info btn-sm" href="{{openUrl}}{{record[openUrlIdColumn]}}" ></a></td>
{% endcomment %}
</tr>
{% endfor %}
</tbody>
</table>
Create a web template, put that code there, call it GC Web Table
Then here is how you can use it on the page:
{% capture testQuery %}
<fetch version="1.0" mapping="logical" no-lock="false" distinct="true">
<entity name="ita_itadatatable">
<attribute name="statecode"></attribute>
<attribute name="ita_itadatatableid" ></attribute>
<attribute name="createdon" ></attribute>
<attribute name="ita_name"></attribute>
<order attribute="ita_name" descending="false" />
<link-entity name="ita_italookuptable" from="ita_italookuptableid" to="ita_lookup" link-type="inner" alias="lookup" visible="false">
<attribute name="ita_name" ></attribute>
</link-entity>
<attribute name="createdon" ></attribute>
</entity>
</fetch>
{% endcapture %}
{% include 'GC Web Table' Id:'testtable' query:testQuery columnTitles:'Name,Type,CreatedOn' columnDataAttributes:'ita_name,lookup.ita_name,createdon' columnOutputFilters:' , ,date~yyyy-MM-dd' columnSortingSupport:'true,true,true' pageLength:10 lengthMenu:'10,25,50' %}
You’d need a FetchXml query, and, then, you’d need to include GC Web Table template and set all the parameters.
The parameters are self-explanatory except, maybe, for the columnOutputFilters. You can use that one to format the output – in the version of the GC Web Table template you see above, you can pass ‘date~<format>’ or empty value for each column (comma-separated), and it’ll be used to format the output:
{{record[column_name] | date: filterPair[1]}}
What’s missing is… localizations. But, first, let’s talk about adding custom forms in Part 5.