Tag filtering, search bar and pagination in Power Pages

I am currently working on a Power Pages project, the portal is a customer self-service web site where the customer can login, create cases, check the status of their already created cases, check knowledge articles and some other new things specially built for this project.

One of the requirements I had a few weeks ago was the implementation of a few things on the knowledge articles web page. The requirement was something like this:

“As a Customer Service Manager I want that when the customer goes to the knowledge articles web page, it is displayed with a pagination of 10 articles per page, plus to have a search bar and tags to filter them.”

To begin with, all this required features are not OOB on Power Pages, so I decided to apply a bit of liquid, FetchXML, JavaScript and CSS to solve this requirement.

Without further introduction let me show you how I solved.

Knowledge articles

The customer wanted to see minified images on each article in the website, so the very first thing I did is to create a column in the Knowledge article table, this is an image column.

And as the requirement specified I need to filter using tags, so I created a second column, an option set with some values (FAQ, Release Note, Document, Blog):

Finally I added these two columns to the knowledge article form:

Create the Web Page

For the second step go the Portal management Model Driven App and create a web page.

Here you can see the fields I filled out:

In my case the parent page is the Home page and the Page template is the Full Page, in the end you can use the Page template you want.


Create the Web Template

The next step is to create a web template, it will contain the FetchXML to retrieve all the knowledge articles and it will also contain the HTML needed to create all the elements to create the base structure to show the articles, the tags, the search bar and the pagination.

Here is the code of the web template:

{% assign org_url = ‘https://’ | append: website.adx_primarydomainname %}
{% assign pageurl = page.url %}
{% if request.params[‘page’] == null %}
  {% assign page = 1 %}
{% else %}
  {% assign page = request.params[‘page’] | integer %}
{% endif %}
{% assign nextPage = page | plus: 1 | string %}
{% assign prevPage = page | minus: 1 | string %}
{% fetchxml getkbarticles %}
<fetch version=’1.0 mapping=“logical” page=“{{ request.params[‘page’] | default:1 }}” count=“15” distinct=“true”>
  <entity name=’knowledgearticle’>
    <attribute name=’knowledgearticleid’ />
    <attribute name=’title’ />
    <attribute name=’description’ />
    <attribute name=’content’ />
    <attribute name=’cr25a_articletype’ />
    <attribute name=’cr25a_recordimage_url’ />
    <filter type=’and’>
      <condition attribute=’isrootarticle’ operator=’eq’ value=’0‘ />
{% endfetchxml %}
<div id=“BtnContainer”>
  <a class=“kbbtn kbactive” onclick=“filterSelection(‘all’)”> Show all</a>
  <a class=“kbbtn” onclick=“filterSelection(‘FAQ’)”> FAQ</a>
  <a class=“kbbtn” onclick=“filterSelection(‘Release Note’)”> Release Notes</a>
  <a class=“kbbtn” onclick=“filterSelection(‘Document’)”> Documents</a>
  <a class=“kbbtn” onclick=“filterSelection(‘Blog’)”> Blogs</a>
  <div id=“SearchBar”>
    <input type=“text” id=“inputSearch” onkeyup=“Search()” placeholder=“Search for knowledge articles..” title=“Type in a subject”>
<div id=“kbarticlesContainer” class=“kbarticlesContainer”>
  {% for kbarticle in getkbarticles.results.entities %}
    <div class=“kbfilterDiv {{ kbarticle.cr25a_articletype.label }}”>
      <div class=“image”><img src=“{{ kbarticle.cr25a_recordimage_url }}” /></div>
      <h4><b>{{ kbarticle.title }}</b></h4>
      <p>{{ kbarticle.description }}</p>
      <a href=“{{ org_url | append: pageurl | append: ‘article/’ | add_query: ‘id’, kbarticle.knowledgearticleid }}”>Learn more &rarr;</a>
  {% endfor %}
  <nav role=“navigation”>
    <ol class=“pagination”>
      {% if page > 1 %}
          <a href=“{{ org_url | append: pageurl | append: ‘?page=’ | append: prevPage }}”>
            <span>&laquo;</span><span class=“visuallyhidden”>Prev</span>
      {% else %}
        <li class=“disabled”>
          <span>&raquo;</span><span class=“visuallyhidden”>Prev</span>
      {% endif %}
      {% if getkbarticles.results.more_records %}
          <a href=“{{ org_url | append: pageurl | append: ‘?page=’ | append: nextPage }}”>
            <span class=“visuallyhidden”>Next</span><span>&raquo;</span>
      {% else %}
        <li class=“disabled”>
          <span class=“visuallyhidden”>Next</span><span>&raquo;</span>
      {% endif %}

Let me explain what this template has.

As you can see the first line of the code is to retrieve the web site URL and the second line is to retrieve the partial URL of the current web page, we will use both variables to perform the pagination.

Then the tricky part is the page filter, and the value is request.params[‘page’] | default: 1 so that when it isn’t included as a query string parameter that it assumes you want the first page.

And it is worth mentioning that so far we will get all the records if we run this FetchXML, so we must include a record count so that we aren’t getting all the records at once (to a max of 5000). To do this you want to add the count attribute to the FetchXML with a integer value as to the number of records in the page of results.

I’ve put on three just for demo purposes.

The next thing is to include the new two columns created in the step before within the FetchXML, be aware that the image column is called “cr25a_recordimage” but I’ve included “cr25a_recordimage_url” because I just want to retrieve the internal URL of the image column.

After the FetchXML, we have to start with the HTML, first of all we have to add the structure for the tag filtering and the search bar, note that for the tag filtering we have to put the same text we put in the option set column:

The next part is adding the liquid to iterate the FetchXML result in order to build the HTML of each article, including the entity image column:

As you can see in the image above I am taking into account when the customer clicks on an article, so I am redirecting the customer to the article’s web page. So be aware that you need a second web page for this, in my case I’ve created it using “article” as partial URL:

And finally the last part of the web template is the HTML for the pagination in which we are using both variables: org_url and pageurl:

Applying JavaScript and CSS to the Web Page Content

Now we have to go to the web page content and in the “Content HTML” column we have to add the call to the web template we’ve just created:

Then we go to the advance tab in which we will see two sections, one for JavaScript and the second one for the CSS: