Model-Driven App

Using Kendo React in code components (aka PCF)


Code components (also referred as PCF Controls) are a great way to enhanced the user experience of Model-Driven Apps and Canvas Apps while developing in a “sandbox” that guarantees the support of your customizations by Microsoft.

Unfortunately the development of web controls can be very tedious and can require a lot of effort. The return on investment can be difficult to get in companies that are not ISV and are therefore not selling their controls.

That is why I usually prefer using a framework and/or a library to accelerate the development of such controls. Kendo UI for React is one of those component libraries that I appreciate and that I use in conjunction with PCF to quickly create complex code components for Model-Driven Apps.

In this post I will demonstrate how to create a code component that displays a number field with a percentage format, something that is unfortunately not supported out of the box by Model-Driven App and Dataverse. I will demonstrate how to use Power Apps Component Framework (PCF) to create the control and Kendo UI for React to ease the development of the input itself.

The full source code can be found here: Wawawum/samples-pcf-kendo: Samples about building PCF Controls with Kendo React (

Here is the result

Disclaimer about Kendo

I am not affiliated to Kendo in any way. I genuinely enjoy working with their components and think it may give you ideas or help you starting a PCF project with Kendo React. Please note that Kendo is not free. You have to purchase a commercial license or use a trial license.

Disclaimer about Canvas App

Code components can be used in Model-Driven Apps and Canvas Apps. Although most of the code is exactly the same some minor implementation details still persist.

I won’t take into account those differences in this post. The code and explanations I provide are only tested in a Model-Driven App context for the following reason: I do not like Canvas App at all (that will certainly be discussed in another post).


If you have never developed a code component before you may have to install some tools before creating a project.

You should refer to this official documentation:

Create your first component – Prerequisites

Creating the project

First we need to create a project. Open a terminal, navigate to an empty folder where the project will be created and run the following command:

pac pcf init --namespace Wawawum --name KendoPercentageControl --template field

That should create the required files and folder structure. In the same terminal enter the following command to launch Visual Studio Code with the current directory opened:

code .

You can now either continue entering commands in your terminal or open a new terminal in Visual Studio and use it from now on.

First you have to install / restore the nodes packages:

npm install

Before starting messing around with the code I usually prefer to test if the project compiles and if the control is displayed correctly.

Here is the content of my index.ts file (in the KendoPercentageControl folder) that displays the field’s value:

I only made the following changes compared to the initial version created by the pac command:

  • A property named container has been added to the KendoPercentageControl class (line 4)
  • That property is assigned in the init method (line 24)
  • The content of the container is updated to insert the field’s value (line 35)

Then, run the following command to start the test harness:

npm start watch

You should be able to set the field’s value in the Data Inputs section of the test harness and that value should be displayed by the control:

Hello World!

That is great but you will notice the field’s type: SingleLine.Text (displayed at the bottom right corner of the test harness). That is obviously not what we want since we will deal with percentages.

To fix that we need to edit the KendoPercentageControl\ControlManifest.Input.xml file to specify that our control works with decimal, floating point and whole number fields:

You should now see this:

You can now switch between Decimal, FP and Whole Number

Once you have tested that everything is working has expected you can stop the test harness (Ctrl+C in the terminal).

Creating a React Component

That Hello World component is very limited (for now). Before adding Kendo to our recipe we will add a React Component to our project. That component will be used to render the field while the index.ts file is used to instantiate the React Component and to handle the communication with the Model-Driven App (receiving the field’s properties and value and sending back the updated value).

Create a folder named “components” in the KendoPercentageControl folder and create a PercentageControl.tsx file inside it.

The folder’s structure after adding the PercentageControl.tsx file

For now we will only reproduce the behavior of our Hello World example using a React Component. Here is the content of the PercentageControl.tsx file:

As you can see it is a very simple class component that only uses one prop to get the value to be displayed.

Here is the updated version of the index.ts file:

You will notice an error at line 3 that can easily be fixed by installing the missing types with the following command (VS Code should display a quick fix):

npm i --save-dev @types/react-dom

Besides the new imports the only thing that has changed is the updateView method that instantiates the PercentageControl component and renders it inside the container.

At that point you should be able to launch the test harness with npm start watch and the control should still display the field’s value.

Adding Kendo to the project

Adding Kendo UI React is quite straightforward and well documented by Progress (the editor of Kendo UI). The controls are bundled into different node packages. The list of packages to install is documented in the control’s documentation page. Here is the one that explains how to use the input controls that we need to display the percentage input (it is actually a number input with a percentage format applied to it):

React Inputs Library Getting Started | KendoReact Docs & Demos (

I will go through the steps so you don’t have to read the official documentation.

Run the following command to install the Kendo UI React packages into the project:

npm install --save @progress/kendo-react-inputs @progress/kendo-react-intl @progress/kendo-drawing @progress/kendo-licensing

We also need to install a theme package. You can choose between those three packages:

  • @progress/kendo-theme-default
  • @progress/kendo-theme-bootstrap
  • @progress/kendo-theme-material

A theme selector is available in the Kendo UI demos so you can easily pick the right theme for you. I will use the bootstrap theme myself and therefore run the following command:

npm install --save @progress/kendo-theme-bootstrap

Finally we have to download our license file (kendo-ui-license.txt) and put it in the project’s root directory. If you do not have a license you can sign up for a free trial.

Once the license file is copied you have to run the following commands:

npm install --save @progress/kendo-licensing
npx kendo-ui-license activate

All those required steps to activate the licence are documented here.

Using a Kendo React Component

Now we can start playing with Kendo React Components. The one we need is a NumericTextBox component that is used to display and enter numeric values. Thanks to the formatting options provided by this component we will be able to format the field as a percentage field. You can see a live example here.

Here are the changes made to the PercentageControl.tsx file:

  • The Kendo NumericTextBox and NumericTextBoxChangeEvent have been imported (line 2)
  • A callback named onChange has been added to the props to communicate the value to index.ts when a change occurs (line 6)
  • An onChange function has also been added to handle the onChange event of the NumericTextBox (lines 17-19)
  • A constructor has been added in order to bind the onChange function to the instance (lines 11-15). Don’t forget that using arrow functions or bind directly in events is not recommended in React.
  • The onChange prop of the NumericTextBox has been assigned to the onChange function of the PercentageControl (line 31)

We also need to update the index.ts file to handle a value change:

  • The notifyOutputChanged parameter is saved in a class property (line 30). That will be used to notify the framework that the field’s value has changed.
  • The onChange callback has been provided to the PercentageControl (lines 44-47). That callback is used to save the value in a class property when it is updated by the PercentageControl and to call notifyOutputChanged.
  • The getOutputs function has been updated to return the field’s value (line 60).

Finally we also neet to tell our PCF control to load the Kendo CSS theme file. That is done by updating the ControlManifest.Input.xml file and adding the CSS path in the resources section:

After building the project and starting the test harness our component should look like this:

The Kendo React Component

If you want to test it in a Dataverse environment you can use the Microsoft PowerPlatform CLI. You will have to authenticate yourself with the following command:

pac auth create --url https://{yourenvironment} 

Then, you can deploy the control with the following command:

pac pcf push --publisher-prefix <your publisher prefix>

Next steps

Of course I would not recommend using that control in a production environment. Here are some things that should be done:

  • Test the control properly
  • Customize the CSS in order to better integrate the control with the Model-Driven App look & feel (that would be a good subject for another post right?)
  • Fix the width that is currently hard-coded
  • The control should be disabled when the field is read only
  • Add some properties to the control in order to give some configuration options when adding the component to a form
  • Package the control into a managed solution (you can use the Power Platform CLI to do that)


Model-Driven App and Dataverse are obviously targeting companies and teams looking for a low-code / no-code platform but I think the Power Apps Component Framework provides a very promising way of improving the UX of the applications developed with that platform.

Companies that invest in Model-Driven App tend to avoid the development of custom components since they usually invest in such a platform to accelerate the deployment of their solutions while minimizing the costs. Nonetheless, if you really want to ensure user adoption you should not minimize the impact of the user experience and therefore invest in creating components that ease the data entry and implement logic specific to your business.

This is where libraries like Kendo can be very useful to accelerate the development of such components. It is especially true if you choose a React library since the complexity of React components is very well encapsulated.

Model-Driven App

CustomLabel v1 – A WYSIWYG way of adding HTML to your Model-Driven App Forms


The ability to insert custom HTML content in a Model-Driven App form is a feature I miss very often. Sometimes you just want to add a couple of lines of text below a field to provide contextual information.

Of course you can use the field’s description to display a tooltip but it is far from obvious for most users.

Another example would be when you want to explain an important change to your users. Let’s say a whole section has been moved to a different tab, in that case you may want to display a notification on top of the form.

What you would do would be to create custom HTML web resources and embed those in your forms. Unfortunately that can only be done by someone with HTML and CSS skills and that will also require the deployment of those web resources which defeats the purpose of a low-code / no-code platform.

That is the reason why I developed a solution called “WWW XRM Custom Labels”. This post is about its first release.

What is WWW XRM Custom Labels?

That solution provides an easy way to create and edit HTML snippets that can be inserted anywhere a web resource can be configured. This way you can display those snippets in any form, dashboard or directly as standalone pages.


  • Table to configure the snippets: configuration of the snippets is stored in a Dataverse table. This way you can easily deploy your snippets as any other table data (Excel or Content Migration Wizard).
  • Web Resource to display the snippets: an easy to configure web resource is provided to display the snippets.
  • WYSIWYG editor: no need to edit the HTML, you can use the rich text editor if you prefer.
  • Multilingual: you can specify the language of the snippet to display the right content depending of the current user’s language.
A screenshot of WWW XRM Custom Labels used in a Model-Driven App form
Customize your Model-Driven App forms with WWW XRM Custom Labels

Where to get it and how to use it?

This solution is free and you can get it here:

WWW XRM Custom Labels

That link also provides information about how to install and configure the solution.

About the name

Some of you may wonder why the solution has WWW in its name and prefix. Wawawum, the name of this blog is actually coming from the term “World Wide Web” but that is story for another day.

Model-Driven App

Why bother about Dataverse and Model-Driven App?


Recently someone on Reddit asked what are the main benefits of Dataverse and Model-Driven App compared to SharePoint. At first the question may seems strange since those two platforms serve different purposes: one is a Low-Code platform while the other is an Enterprise Document Management System.

Although that is true, SharePoint can also be considered as a No-Code development platform especially when combined with Power Automate, Canvas App and other M365 products. Apps built with those technologies are sometimes referred as “Mashup solutions” since they require the use of multiple products and technologies to support a business process.

Thus, if SharePoint is considered as a No-Code platform it is fair to compare it to Model-Driven App (I’ll use the acronym MDA for the rest of the post) and Dataverse. That user on Reddit noticed that creating a table with MDA involves a lot more work than creating a SharePoint list and he was wondering why we should invest time creating Model-Driven Apps.

I gave my thoughts on Reddit but here is a more complete version that may help you understand the benefits of MDA if you’re not familiar with that technology.

The main benefits of Model-Driven App and Dataverse over building an App with SharePoint

Dataverse is a relational database

This point is one of the most important in my opinion but is also the more abstract one especially for non IT folks.

The database used when creating a MDA is called Dataverse. It is actually a regular SQL Database with a standard model already provisioned when you create a new environment. That model is composed of tables that represent common business entities (accounts, contacts, users, etc.).

Thus, when creating a new custom table in Dataverse an actual SQL table is created. Same when adding a field to a table, a SQL column will be added to underlying SQL table. It may seem obvious but that is not the case with SharePoint. Of course SharePoint data is stored in a SQL database but the actual database schema is not paired to the lists and libraries. There is a good reason for that: SharePoint is designed to handle unstructured data (documents in that case).

At the end of the day using a relational database and model is best when developing an app. For example although you can put millions of items in a SharePoint list you should not exceed 5000 items in a single view. There is no such limitation with Dataverse. You also get way more options with Dataverse and MDA when querying data either when using the web interface of through the API (it is way closer of what you would get in SQL).

Relationship Management

Although the previous point is very technical, this one is very business oriented. MDA is made to handle complex relationships. You can easily model 1:N and N:N relationships and display those in any form.

The platform is made to allow navigation through linked records so you can drill down the relationships.

The only thing SharePoint provides is lookup columns but they are way more limited than what you can configure in MDA. In a MDA form you can for example filter items to display in a lookup either based on a view or even based on a dynamic value in the form (cascading lookup). You can even allow the user to switch between available views.

As soon as you start creating an app than contains multiple tables with relationships you start realizing that SharePoint as never been designed to handle such scenarios and you should really consider MDA and Dataverse.

Business Processes Modeling

Let’s be clear, saying that you can model a complex business process with Model-Driven App is in my opinion a bit of an overstatement. Nonetheless you can at least visually represent the stages of a business process and it is easy to follow the progression of your processes in a MDA thanks to what is called Business Process Flows. You can even add some basic branching in a BPF.

A screenshot of a Business Process Flow.

With SharePoint what you could do is create a choice column to represent the stages of the process but you would miss a lot of features or at least it would be way more complex to implement the following MDA features:

  • Branching: based on some custom conditions you can skip some stages for example.
  • Multiple processes for the same table: you can configure multiple BPFs for the same table and the right process can either be selected manually or automatically.
  • Multiple instances of a process for the same record: you can keep track of multiple process instances for a single record. It is also possible to abort and reactivate a process instance.
  • Process duration: by default a process instance duration is tracked and displayed for each instance.
  • Requiring that certain fields are filled up per stage. This is a very powerful feature that allows users to save a record without entering all the information while making sure the required information is entered when moving to a specific stage.

Form Customization

The ability to customize the layout of a form is a strong selling point of MDA. It is true you are limited in term of modifying the look and feel of the platform but you can very easily and quickly create tabs, sections and group fields to ease the data entry.

In addition to that you can also create custom components (PCF) to customize the way a field is displayed on a form.

Until recently it was impossible to customize a SharePoint form without a lot of custom development. Now two options are available:

  • JSON can be used to edit a form layout. You can create a header, footer and regroup fields in sections. Unfortunately there is no GUI (yet) to ease the configuration and the options are very limited.
  • Canvas App can replace a SharePoint form. The main drawback is the effort needed when most of the time you only need to rearrange fields and group them in sections and tabs.

Even though SharePoint starts providing features to customize the layout of a form it is way more limited than MDA while being more complex. That is especially true since Microsoft has deployed the latest version of the designer used to edit MDA forms that provides a WYSIWYG experience. You can very easily edit a form in front of the user which is useful when prototyping applications.


MDA views are a very powerful tool. You can create quite complex filters in a MDA. It is not as advanced as what you can do in pure SQL of course but you can group conditions together (and choose between OR and AND operators) and lot of conditional operators are also available including some specific to date and user field types (filtering on the current day, tomorrow, yesterday, current month, current quarter, current fiscal year, current user, current user’s team and so on).

Another big difference with SharePoint is the ability to filter on related records. You can apply all those operators to any field of a related record or even on a related record of a related record (I guess there must be a filter depth limit but I never had a case where I hit it).

Screenshot of the filtering configuration screen
Source: Create or edit filters in model-driven app views – Power Apps | Microsoft Docs

Last thing I like in MDA is the ability for users to create their private views (as they also would in SharePoint) and share those to the users of their choice (not available in SharePoint this time).

Implementing custom business logic

Dataverse and MDA offer multiple ways of adding business logic into an application:

  • Business rules can be used to add simple business logic to forms and/or tables. You can hide/show fields or sections depending of the value of a field for example. Available actions are limited but those rules are easily configurable through a GUI.
  • Even though Classic Workflows will certainly be replaced by Power Automate they are still very useful to implement server-side validation either asynchronously or synchronously. One use-case I face very often is the addition of business rules that must prevent a user of creating or updating a record if some conditions are not met. This can be implemented very quickly with Classic Workflows and will apply even if the record is modified through the API or an Excel import.
  • Power Automate is also an option to add business logic but unfortunately you are limited to asynchronous execution and that prevents adding logic to block a record from being created, updated or deleted. It is nonetheless the go to option when you need to add automation to your solution.
  • JavaScript can be injected into a form. Specific Client-Side APIs are available to implement complex business logic. This enables you to develop very complex validations while being fully supported by Microsoft.
  • Plugins can be developed to implement complex business logic. The SDK provides a lot of events that can be registered to execute your code. You can even execute code when the model of your application is modified enabling you to implement complex automation when a table or column or security role are added for example. Plugins can also be configured to run either synchronously or asynchronously and they can prevent an event from happening which is very useful to block an action depending on custom logic.

In comparison SharePoint does not offer much to implement business logic. Of course you can set some validation on the fields (as you can do in Dataverse) but even something as simple as displaying fields or sections depending on conditions will require the use of Canvas App and that costs a lot of time. You also can develop custom Event Receivers but that is as complex as developing Dataverse Plugins.

Bulk editing and deleting

Aside from the editable grid available in SharePoint there is not much you can do if you need to import or edit a high volume of data.

Fortunately Dataverse and MDA provide multiple ways of doing such things. First you can use the editable grid to make quick adjustments.

Then, a bulk edit can be used to update field values of a lot of records. Excel can also be used to import or edit existing records, there is even an option that uses Excel Online to edit the content of a Dataverse table.

Animation of the bulk edit feature in Model-Driven App
The new bulk edit user experience in Model-Driven App. Source:

Finally, if you need to curate the data of a table you can create a query that returns the records to delete and then configure a bulk delete job based on the query.

Document generation

Of course developing an app is often a way of getting rid of document based processes. Nonetheless, it can be useful to generate documents based on records. You could for example generate a memo from a record in order to approve it with an electronic signature software. In that case you could use the built-in document generation feature of MDA. You download a Word template that contains XML fields. After customizing the template and uploading it to your app any user will be able to generate the document based on a record’s values.

Same thing can be achieve to generate an Excel file based on a view.

I find this feature limited (no way to insert rich text content for example) but it works and is quick to configure.

Advanced security model

Dataverse uses a hierarchical security model that can be used to represent the different business units and teams of an organization. In addition to that the concept of ownership is very useful to restrict who can or cannot access a record. You can for example restrict the records a user can create, update or delete to the ones he/she owns or the ones owned by his/her team or even to the ones owned by a subordinate team.

Field level security is also a feature provided by Dataverse that can be very useful. See links below if you want to know more about security in Dataverse.

On the contrary, even though you can set the security at the item level in SharePoint it is not recommended and should be the exception. Also, it is quite difficult to see who has access to what when securing a SharePoint site at the list level or item level.

Mobile support

Native iOS and Android apps are available and provide offline capabilities. Very few configuration is required to make an app available on mobile.

On the other hand a SharePoint app is available but is pretty much useless at the point I always use the OneDrive app to access my documents and libraries instead of the SharePoint app.


MDA can be packaged in solutions that make your app easy to deploy from one environment to another. Even though it is almost impossible to merge changes as you would do with other development frameworks and platforms you can still extract and the content of a solution in a source control.

Microsoft is also providing tools to automate the deployment of solutions. Azure DevOps tasks are available to export, import and publish solutions. A backup task can even be used to ensure you keep a copy of the environment before making a deployment.

Diagram of the ALM process with PowerApps

Unfortunately SharePoint Online does not give you much if you want to stage your changes. In most cases lot of changes must be done manually in different environments.


Those are the main things I can think of that differentiate MDA and Dataverse from SharePoint when building an app.

Don’t get me wrong, I’m not saying SharePoint is a bad platform. I think it is actually a good Enterprise Document Management system very well integrated with the M365 ecosystem.

Nonetheless, SharePoint has never been designed to build apps. Yes you can very easily create lists and with some Power Automate and Canvas App you can create solutions to support business processes but at the end of the day you won’t match the level of robustness as you will with MDA and you will find limitations quickly.

I think SharePoint has extensively been used in a lot of organizations to build apps since users are looking for a no-code platform. Unfortunately Microsoft has not provided a viable option yet in my opinion.

So you are looking for a no-code platform integrated with M365 that can be used by any user in your organization, SharePoint is still the only option but be aware of the limitations.

On the other hand if you are looking for a low-code platform that can handle complex business processes, lot of tables and relationships but that doesn’t require UI customization and extensive corporate branding, then you may consider MDA and Dataverse.


Fresh start

I can’t even remember when I started this blog. Let’s say it was more than a decade ago. When I created it I was a SharePoint developer and I shared some technical articles about SharePoint development.

Since then I worked on a lot of projects involving different technologies but one thing is sure: I’m not a SharePoint developer anymore. I actually haven’t worked on a SharePoint project for years.

That’s the reason why I’ve decided to get rid of the old content that was obsolete. But I still want to share my thoughts about the technology I work with and also share some technical posts.

So here is the new, you’ll find posts inspired on my daily projects, the difficulties I encounter and how I try to solve business problems with technology. I’ll hope you’ll enjoy the content.