In this post, we will look at App Side Panes in Model-Driven Apps, a useful feature that gives users a side pane on the right side of a model-driven app. Developers can utilize this pane to display information to a user, such as lists, records, and pages. Note, according to the documentation, this is still in preview and was expected to go GA last month. Keep an eye out for updates as preview code can always change.
If you prefer a video, check out my YouTube video on App Side Panes below. Don’t forget to subscribe to get all the latest videos for learning Dynamics 365 and the Power Platform.
Let’s create a solution and create 2 files, one HTML web resource, and one Custom Page. I also have 2 icons I uploaded, Account Activity and Account Icon:
The HTML web resource displays a simple Hello World:
The Custom Page displays a Hello World Custom Page:
I also added the page to the Sales Hub model-driven app:
Now, there are a couple of scenarios where side panes become interesting:
- Model-driven apps
- Multisession model-driven apps such as Customer Service Workspace and Omnichannel
Let’s look at Model-Driven Apps first. We will open the Sales Hub app and go to the developer console. Let’s open an entity list of accounts.
The code. Note, we are passing the URL of the web resource for the icon:
Xrm.App.sidePanes.createPane({ title: "Accounts", imageSrc: "WebResources/carl_accountactivity.svg", paneId: "AccountList", canClose: false }).then((pane) => { pane.navigate({ pageType: "entitylist", entityName: "account", }) });
Running this in the console, we see the side pane has opened on the right, and we have our icon and list of accounts:
If we select an account from the list, it displays the account inline in the side pane:
Note the ability to open a list of accounts, or pop the record out:
Popping the record out opens it in a new browser window:
Now let’s open a new side panel called Contacts:
Xrm.App.sidePanes.createPane({ title: "Contacts", imageSrc: "WebResources/carl_accounticon.svg", paneId: "ContactList", canClose: false }).then((pane) => { pane.navigate({ pageType: "entitylist", entityName: "contact", }) });
Running this, we see the second pane is now displayed, and we can toggle between panes:
The minimized panes look like this:
We can also open entity records directly by passing the entity name and id:
Xrm.App.sidePanes.createPane({ title: "Coffee Lab APJ", imageSrc: "WebResources/carl_accounticon.svg", hideHeader: true, canClose: true, width: 600 }).then((pane) => { pane.navigate({ pageType: "entityrecord", entityName: "account", entityId: "da59721f-02b2-ea11-a812-000d3a1b14a2", }) });
And a Custom Page:
Xrm.App.sidePanes.createPane({ title: "Custom Page", imageSrc: "WebResources/carl_accounticon.svg", hideHeader: false, canClose: true, width: 300 }).then((pane) => { pane.navigate({ pageType: "custom", name: "carl_test1_eac1d" }) });
Note this time I didn’t hide the header, and we see the X icon to close the tab:
And a Web Resource:
Xrm.App.sidePanes.createPane({ title: "Web Resource", imageSrc: "WebResources/carl_accounticon.svg", hideHeader: false, canClose: true, width: 300 }).then((pane) => { pane.navigate({ pageType: "webresource", webresourceName: "carl_Test" }) });
Dashboard:
Xrm.App.sidePanes.createPane({ title: "Sales Dashboard", imageSrc: "WebResources/carl_accountactivity.svg", paneId: "SalesDashboard", canClose: false }).then((pane) => { pane.navigate({ pageType: "dashboard", dashboardId: "233ec131-82b3-ec11-983f-0022480bfd74", }) });
Search:
Xrm.App.sidePanes.createPane({ title: "Search", imageSrc: "WebResources/carl_accountactivity.svg", paneId: "Search", canClose: false }).then((pane) => { pane.navigate({ pageType: "search", searchText: "test", }) });
This also gets interesting with multisession apps. Let’s look at Customer Service Workspace. Our tab loads as part of the productivity pane:
We can also control the state of the side panel, whether it is expanded or collapsed, through the API:
As well as set properties such as the width:
var lastPane = Xrm.App.sidePanes.getSelectedPane();
lastPane.width = 700;
Close the pane:
var AccountPane = Xrm.App.sidePanes.getPane("AccountList"); AccountPane.close();
And enable Badge on a pane:
Xrm.App.sidePanes.getSelectedPane().badge = 1;
Note you can set this to any number under 100:
Selecting the icon will clear the badge:
I AM SPENDING MORE TIME THESE DAYS CREATING YOUTUBE VIDEOS TO HELP PEOPLE LEARN THE MICROSOFT POWER PLATFORM.
IF YOU WOULD LIKE TO SEE HOW I BUILD APPS, OR FIND SOMETHING USEFUL READING MY BLOG, I WOULD REALLY APPRECIATE YOU SUBSCRIBING TO MY YOUTUBE CHANNEL.
THANK YOU, AND LET'S KEEP LEARNING TOGETHER.
CARL
Thank you Carl for this article. I wanted to know if PCF controls can be attached to the side pane?
Where we can add this code to see a side pane other than console.
Hello Carl,
about the custom page, I’d like to have to custom page set on the right side of the app screen, but without the Title and icons, because they’re already built in the custom page.
This would be like using Xrm.Navigation.navigateTo(pageInput, navigationOptions) with the following options :
1. Target :1 to get rid off Title and icon,
2. Position : 2 to be on the right side with width setup
But the API isn’t designed this way.
On the other hand, you show the sidepane component which enable title and icon being off, but then comes the Tab ….:-(
There must be something not possible by design, that I total missed.
Of course the last solution, would be to avoid adding Title and icon at canvas level.
Could you help me to understand ?
I have the same question. Can someone please help here?
How would you suggest closing a pane automatically when switching between pages in a model driven app? My app is conditionally displaying a pane when the user opens a form for a record that is in a specific state. However I don’t see a way to close the pane if the user goes back to a list view.
I avoided using sidepanes for a year because we couldn’t close them. I’ve been playing around with this and it seems like it is working.
https://linnzawwin.blogspot.com/2020/05/show-global-notification-on-load-of.html
Just have the enable command of a global button run JS to close the pane.
function closeRetailVisitSidePane() {
//Called from Enable Rule
var closePane = Xrm.App.sidePanes.getPane(“SidePaneId”);
if (closePane !== null) {
closePane.close()
}
return false;
}
HI Carl,
I want to know How we can have associated view displayed in the side pane.
Many Thanks
Suyash
Second this.
More specifically, I want to grab variables from a record and then apply a filter to the entitylist control based on those variables. I’m aware that this can be done in a subgrid, but I’m wondering if it’s possible in the side pane as well.
Oh please development gods, save us🙏🏻
Nate
Hello Carl, I want to create a pane with xrm.app.sidepanes.createpane and set pageType=entitylist. However, this list should be associated with a specific record. How can I achieve this? I can create a new view each time and display it, but that would be inefficient. Is there a way to use pane.navigate and provide a filter for this purpose?