ecLearn LMS, developed by Engineered Code, is proud to sponsor Community Summit North America. Visit us at booth #1857 and get on the list for our Summitland Prize!
This month I’m continuing my series on looking at how functionality is built into the new templates available for Power Pages. In this post I am looking at the Program Registration template, which allows users to browse and sign up for classes, and is useful in scenarios such as an after school program. Specifically, I’m going to look at the functionality that allows users to search through the available classes.
The home page of the program registration page offers the user the ability to search through the available classes. You can search by keywork, or filter using dropdowns like category, season, level and type.
Each time you select new filter criteria, the page refreshes, and classes that match that criteria are shown. You can search using keywords, or using one or more dropdowns, but you can’t mix those two.
We know the search functionality exists on the home page of the site. However, this doesn’t tell us exactly where the code is – instead, it just tells us where to start looking.
Unless the code is common across the whole site, in which case it might appear in the header or footer, the first place to look is on the web page record itself. While I like to use the Portal Code Editor in the XrmToolBox, you can also look around the Portal Management App (or the new Power Pages Management app, if you’re using the enhanced data model), or in the design studio using the VS Code for Web extension in the Power Pages Design Studio.
If the code is located on the web page record itself, it will generally appear in the Copy column or the Custom JavaScript column on the language-specific version of the web page. So, in this case, I’m looking at the English version of the Home web page.
The copy attribute contains some HTML markup, but also has some Liquid include statements, which means it is bringing in additional code from Web Templates – in this case called “Portal Web API Wrapper”, “Drowdown Filters” and “Course Catalog”.
The Custom JavaScript attribute contains over 400 lines of JavaScript, which implements the search functionality.
We’ll talk about the JavaScript in a second, but first, let’s look at the Dropdown Filters web template. This includes some FetchXML that query the stringmap table – this is a technique to get the options associated with a choice column. So rather than hardcoding something, consider using this type of query to programmatically get those options.
This web template also contains the input for the keyword search. With this template on the page, the interface for filtering classes is available to users. However, we need client-side JavaScript to make it work.
As previously mentioned, this JavaScript is located in the Custom JavaScript section of the web page.
The first thing I noticed is that there is a lot of JavaScript. However, much of it seems to be not used. It looks like at some point there was a more sophisticated interface, including being able to select multiple options from a dropdown, but the version we see is just simple dropdowns. So much of the code can be ignored since it is not used.
The main chunk of code to look at is the onchange event for the filter inputs, starting at line 26.
When any of those inputs change, the buildUrl function is called. This function crafts a new URL using the selected filters, and then performs a JavaScript redirect back to the same page, with the appropriate query string parameters set.
This is what causes the page to reload each time a new filter is selected.
With the page refreshing with the new query string parameters, we can now look at the Course Catalog web template to see how they achieved the filtering itself. There, you’ll see a large FetchXML query crafted, with conditional Liquid statements including certain filters based on the query string parameters. So, if for example the Category query string is present, filters are added to the FetchXML query to only get results that match that category.
Once the FetchXML query is executed, a loop is performed to display the results.
This approach is relatively simple to implement. The number of lines of JavaScript actually in use is very low. The filtering is done server-side, so the client-side scripting is really only required to cause the page to reload when new filters are selected.
Since the page reloads each time, the browser history gets updated for each search. This allows a user to go back and forwards between their searches. I think that is a good user experience.
I consider the technique used here to be a fairly basic one. In terms of user experience, a full page refresh each time a selection is changed isn’t ideal.
Instead, an approach using AJAX calls to update search results as filters are changed would be nicer. To maintain the browser history that I mentioned earlier, you would have to implement JavaScript to keep that update to date as well, but that isn’t too complicated.
I would be interested to see what interface they had in mind with all of that extra JavaScript. The option to select multiple filters per dropdown would be great. It would also be nice to filter by keyword and by the dropdowns, instead of either or.
Overall, if you need a quick search interface, this will get the job done. But with a bit more custom code, you can achieve a more user-friendly search interface.
Did you find that the searchTxt method is broken? The code does not build the filteredIndices for keyword searches, so it cannot render the cards. It would appear that the Course Catalog web template needs a significant restructure.
Also I’m still unsure why it uses this “indices” approach when the fetchxml is built dynamically anyway. It may as well just output the cards that the query returns.
Yeah, it does seem to be an either/or, not both. It looks like to me that they had grand intentions of building out a sophisticated interface, but probably ran up against a deadline and some of the functionality wasn’t finished.
Nick