Implementing GC Web (government of Canada) theme. Part 4: web template component for GC Web tables

By | August 8, 2024

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.

Leave a Reply

Your email address will not be published. Required fields are marked *