In this post, I am explaining how to query data from a CDS entity and use Knockout to bind it in a model-driven app web resource. It has the following advantages:

  1. It is easy don’t require a lot of efforts (less coding)
  2. We have the flexibility to do further customisation

About demo:

Since it is demo, I have included script and link references from CDN. The focus of this post is to explain and share sample code for data binding. I m loading my web resource as a popup and have used AlertJS‘s free version for this. To keep this post short, I m not explaining how to add a button in Model-Driven App. But to summarise steps I have added JS file in my form, customised ribbon and added a button with the following code.

"use strict";
///<reference path="../mag_/js/alert.js">
var Account = (function ()
{
	return {
		LoadAccountsPopup: function (executionContext)
		{   
            Alert.showWebResource("webresource_accounts");			 
		}
	}
})();

In my web resource, I m getting data using Web API query. Data binding is done of course using Knockout and have used Bootstrap for styling. Here is code:

<!DOCTYPE html>
<html>
<head>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" type="text/javascript"></script>
    <script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <script>
        $(document).ready(function () {
            var query = "/api/data/v9.1/accounts?$top=22&$select=name,telephone1,address1_city";
            var oDataUrl = parent.Xrm.Page.context.getClientUrl() + query;          

            $.getJSON(oDataUrl)
                .done(function (data) {
                    if (data != undefined && data.value.length > 0) {
                        ko.applyBindings(new AppViewModel(data));

                        debugger;
                    }
                })
                .fail(function (error) {
                    debugger;
                });

        });
        function AppViewModel(data) {
            var self = this;
            self.pingResults = ko.observableArray([]);
            ko.utils.arrayForEach(data.value, function (d) {
            self.pingResults.push(d);
            });
        }
    </script>
</head>
<body>

    <div style="overflow-x:auto;">
        <h4 class="text-center">List of Accounts</h4>
        <table id="tblContainer" class="table table-sm table-striped table-hover table-borderless">
            <thead>
            <th>Account Name</th>
            <th>Telephone</th>
            <th>City</th>

            </thead>

            <tbody data-bind="foreach: pingResults">
                <tr>
                    <td><span id="fileName" data-bind="text:name"></span></td>
                    <td><span id="fileType" data-bind="text:telephone1"></span></td>
                    <td><span id="fileType" data-bind="text:address1_city"></span></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

I hope you find this helpful. If you have a question please leave me a comment on my blog and I will try to assist.

Enjoy your day.

Let’s Connect

 twIcon lnIcon fbicon