In this post, you’ll see how to build a Bootstrap carousel (aka slider), populated with data from a Dataverse table.
We query using FetchXML (which you can build using Advanced Find) and then loop through each result, populating the background image, heading and paragraph for each slide.
Quickstart – Get a result quickly by taking my snippet and making it work for you
Let’s get you some visible results quickly. For this reason, I’ve created some boilerplate code that you can copy and reuse. This contains all the stuff that wouldn’t change from one implementation to the next; not just Bootstrap’s HTML but liquid too… things like looping and dynamic slide numbering.
So if you want to get up and running quickly, all you need to focus on is:
- Creating an advanced find to pinpoint the records you wish to display in the carousel / slider
- Adding the logical names of the columns you wish to output
To get started, copy and paste the snippet below into a web page or template
Exactly what to change is detailed after the snippet… I’m nice like that 🙂
{% fetchxml name_of_query %} Paste your Fetch XML here {% endfetchxml %} {% if name_of_query.results.entities.size > 0 %} <div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> {% for result in name_of_query.results.entities %} <li data-target="#carousel-example-generic" data-slide-to="{{ forloop.index | minus: 1 }}" {% if forloop.first %}class="active"{% endif %}></li> {% endfor %} </ol> <!-- Wrapper for slides --> <div class="carousel-inner" role="listbox"> {% for result in name_of_query.results.entities %} <div class="item {% if forloop.first %}active{% endif %}"> <img src="{{ result.logicalNameforImagecolumn_url }}&Full=true" alt="..."> <div class="carousel-caption"> <h3>{{ result.logicalNameForNameColumn }}</h3> <p>{{ result.logicalNameForDescriptionColumn }}</p> <a class="btn btn-primary" href="/Partial-URL/?id={{ result.guidForThisRecord }}">View Details</a> </div> </div> {% endfor %} </div> <!-- Controls --> <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> {% endif %}
All you’d need to do to make this fully functional is to update the naming to match your table and use case.
- Paste your Fetch XML query (copied from Advanced Find) between the opening and closing {% fetchxml %} tags
- Replace all instances of ‘carousel-example-generic‘ with a meaningful name e.g. ‘upcoming-events-carousel’.
- Replace all instances of ‘name_of_query‘ with a meaningful name e.g. ‘upcoming_events_query’
- Replace ‘logicalNameForImageColumn‘ with the logical name for the image column on your table. Leave the _url part in there
- Replace ‘logicalNameForNameColumn‘ with the logical name for the text field you wish to use as the heading for each slide
- Replace ‘logicalNameForDescriptionColumn‘ with the logical name for the text field you wish to use as the description for each slide
- If you wish to link to another page from each slide e.g. to the registration form for an event, or to a full details page, replace ‘Partial-URL‘ with the partial URL of the web page e.g. View-Event-Details, and replace ‘guidForThisRecord‘ with the logical name for your table’s GUID (this will usually be the name of your table followed by id e.g. accountid, contactid, musdyn_trackid, etc.)
If you’re interested in how I arrived at that code and would like to create your own from scratch, here’s how…
Making the carousel from scratch
Prerequisites:
- Create a table with an Image column
- Populate with some sample records
- Create table permission with at least Read privileges
Step 1 – Get a carousel up and running, cycling through placeholder content
Go to Bootstrap JavaScript documentation using the link below: https://bootstrapdocs.com/v3.3.6/docs/javascript/
This will list all the pre-made JavaScript components available to us
Select Carousel
We can see a carousel aka slider cycling through some placeholder content and, most helpfully, a HTML snippet for us to use as a starting point
Understanding the markup of Bootstrap’s carousel
Knowing what the slider is made up of will help a lot when it comes to making it dynamic. Here we go…
Analysing Bootstrap’s example HTML: Recognising patterns
What am I looking for when analysing / breaking down Bootstrap’s example markup?
Which parts are repeating – this tells us what constitutes one ‘item’ – in this example, what’s the HTML markup for one slide in the carousel. This is what we’ll place within our for loop.
I’m also looking for unique identifiers e.g. for the carousel and for each item that we’ll need to provide. Also are there any classes in the HTML for the current item only?
Here goes…
The main div for the carousel has an ID. This is important in case we were to have multiple carousels on the same page. You may notice that this is referenced elsewhere e.g. in the controls for this carousel.
Then we have the indicators. These:
- Show how many ‘slides’ there are in total
- Show which ‘slide’ we’re currently on
- Allow us to skip directly to a specific slide
The indicators live in an ordered list <ol> with a class of carousel-indicators.
Each indicator is a list item <li> and hold some key information:
- data-target specifies which carousel this indicator relates to / controls
- data-slide-to specifies the slide this indicators links to (by numeric ID. Note these numbers start from zero… we’ll need to contend with these later)
Note that the first list item has a class of active
As the carousel plays, this active class is removed from the current slide and onto the next
Next we have a wrapper for the slides. This won’t change so we’ll leave it alone
Then we have the actual ‘slides’. Each ‘slide’ is a div with a class of item
Just like the indicators, note that the first item has a class of active
As the carousel plays, this active class is removed from the current slide and onto the next
The item has some child elements; an image and a caption. This is where we’ll insert the content
Finally, we have the Previous and Next controls. We can leave these alone. This markup remains the same for every carousel so we’ll leave this alone.
Okay first thing we’ll do is copy that example markup onto a web page…
Populating the carousel with placeholder content
This step is optional but I find it to be a useful first step to help identify any errors in my HTML before I complicate things with liquid…
What’s not too helpful is that Bootstrap’s example HTML doesn’t contain the correct number of slides, nor any caption content. Within there, we’ll add a heading 3 and a paragraph.
We can specify the size we need in the URL. I’m going to use the same pixel dimensions as the bootstrap example, 900 x 500
This gets us an image at 900px x 500px:
However, we’d get the same image 3 times, so let’s amend that to get a different random image each time:
https://picsum.photos/seed/1/900/500
https://picsum.photos/seed/2/900/500
https://picsum.photos/seed/3/900/500
We add this to the source attribute of the image
…pop in an example heading and paragraph and we’re done with the first slide
We can then just copy and paste 2 more versions of this and tweak to make them unique
It’s important that we remove the active class from any except the first slide… only one can be displayed and active at any one time
Save, Sync and Preview. We now have a slider cycling through static content
Let’s level up now and make that dynamic, populating with data from Dataverse…
To make this dynamic, we’ll be using Liquid templating language…
Which liquid skills we’ll be using and what each one does / brings to the table
Fetch XML
For
- Add sequential numbering to results (we’ll use this for the navigation)
- Check whether the current item is the first or last result (we’ll use first to determine which slide gets the ‘active’ class, meaning it’s displayed when the carousel loads)
If
- Did our Fetch XML return any results?
- Is this the first item (result) in the forloop?
Query for the records we want to display, using Advanced Find
First, we’ll use Advanced Find to retrieve the information we want to show in our carousel. Not ‘classic’ advanced find but the modern advanced find experience.
I’m going to use a list of Event Sessions. I’ll start by opening that table in my model driven app.
Here, I Edit Columns to specify which columns I want to display in the slider
Next, I specify a sort order simply by clicking the column title… once for ascending order, twice for descending order. Often the requirement is to show the most recent items, so I sort descending by a date column such as Created On or Start Date (depending on the table)
Next, I create the filter. For me this is usually a date period and perhaps a status reason. You may also want to consider whether there are any columns that mark certain records as ‘featured’. We can apply basic filters using the column headings or use Edit Filters for more complex criteria like information stored on related records.
Let’s save our personal view in case we need to make changes later…
Click the view selector drop-down and choose Save as New View
Give it a meaningful name and click Save
Now, to get the fetch XML…
Open the view selector drop-down again and choose Manage and Share Views
Click the ellipsis next to your saved view and choose Download FetchXML
So what do we do with this code you might ask… We’re going to paste it into our template.
But we need to tell Power Pages that some fetch xml is coming and what to do with it.
We’ll type an opening and closing fetchxml tags and give our query a name, like so:
{% fetchxml event_sessions_query %} {% endfetchxml %}
Now we can paste our fetchxml between those tags
Here goes…
First of all, let’s check for any results. We can use an if statement for this. Let’s surround the entire carousel with this. No point showing an empty slider if we have no results.
{% if event_sessions_query.results.entities.size > 0 %}
What’s that if statement all about?
Fetch XML queries in liquid return the results in an object called results.entities
Later we’ll loop through this to access our results. For now, we just want to check its size re. how many results were returned. We do that with .size
Note: .size is a handy property for liquid in general. We can use it to check whether columns are populated and many other things too.
We’ll soon get onto dynamically populating our slider but first, let’s reduce our HTML down to just one indicator and just one ‘slide’…
Paste in our boilerplate code
Replace carousel-example-generic with something meaningful like gold-sponsors-carousel. Note – there are many instances of this… the ID of the main div, in the indicators and for the previous and next buttons. You may notice sometimes it has a # before it. That’s required. It tells our code that this text is referring to an ID.
Replace everywhere that says name_of_query with something meaningful like gold_sponsors_query
Tip- that’ll be in the fetch xml tag, the if statement and the for loop
Paste your Fetch XML between the opening and closing fetch xml tags
Now we actually populate the HTML with data from our fetch XML query
Everywhere you see code within double curly braces, that means output something
result. Means output for the current result in the for loop
e.g. swap {{ result.logicalnameforNamecolumn }} with {{ result.cflow_name }}