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!

ENGINEERED CODE BLOG

Power Apps Portals: Rich Text Editor on Entity Forms

I’ve been asked a few times about how you can add a rich text editor to Entity Forms or Web Forms on Power Apps Portals, and while I haven’t had the need to do this for a real implementation, I was curious to try it out. In the process, I found out about a setting I didn’t know existed that’s been around for at least a few years.

Before we get into the details, a shout out to Business Applications MVP Colin Vermander (@koolin_) for letting me bounce some ideas off of you to get this post done.

Not Hard, But Not As Simple As You Think

You’d think that adding a rich text editor to a Power Apps Portal Entity Form or Entity List shouldn’t be too hard. There are a lot of available What You See Is What You Get (WYSIWYG) Editors out there – in the past I’ve used both TinyMCE and CKEditor for various different types of projects. These editors generally make things pretty simple – point them at a <textarea> and they pretty much do the rest. Unfortunately, with Power Apps Portals, there is a gotcha: Request Validation.

Request Validation is an ASP.NET security feature that prevents the application from processing unencoded HTML submitted to the server. It’s designed to prevent script injection attacks. Since Power Apps Portals in an ASP.NET application where this default feature has not been turned off, if you try to submit raw HTML in one of the fields on your Entity Forms, the application will throw an error. This is what will happen if you simply apply a Rich Text Editor to a field on an Entity Form.

I’ve been aware of this issue since the Adxstudio days. However, back then since we controlled the ASP.NET application, we were able to turn this feature off when necessary. Once Microsoft moved the product to Software-as-a-Service, we no longer had that control. Or so I thought.

The Easy Fix

My intention with this blog post was to describe the solution I’ll present below. However, in putting it together, I discovered there is a way to disable Request Validation on Power Apps Portals, and it’s as easy as creating a Site Setting named DisableValidationWebTemplate with a value of true. As you’d expect, with the setting created, Request Validation will not take place and your rich text will be saved to the CDS database.

When I discovered the documentation, the first thing I did was look at the history in GitHub to see when that documentation was added. Turned out it was recently – early February 2020. I figured it was a new feature, so I didn’t feel too bad about not knowing about it. However, a bit of searching led me to find a reference to it from December 2017, so clearly it’s been around for a while. Another undocumented gem.

A Different Approach

You might be asking yourself why if there is already an easy solve for this, why would I bother providing another approach? The answer is because there is a reason why Request Validation exists, and if you can avoid turning it off for your entire site (which is what the Site Setting does), it’s something worth considering.

The alternative approach is to encode the data before it is sent to the web server for processing, then use a CDS plugin to decode the data so that it is saved as proper HTML.

In this example, I’ll use TinyMCE to demonstrate how this is possible. First, add a reference to TinyMCE in the Copy attribute of your page:

<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>

Next, add the following to the Custom JavaScript field on your Entity Form:

$(document).ready(function() {
    $('#nh_description').hide().after('<textarea id="nh_description_rich">');
    tinymce.init({
        selector: '#nh_description_rich',
        init_instance_callback: function(editor) {
            editor.on('Change', function(e) {
                $('#nh_description').val(encodeURIComponent(tinymce.get('nh_description_rich').getContent()));
            });
        }
    });
});

In the above code, replace nh_description with the name of the field you want the rich text editor on. The JavaScript hides the original input, adds another <textarea> below the hidden one for the rich text editor, initializes TinyMCE on the new field, and any time the rich text editor changes, saves the encoded HTML to the original input.

Finally, register a plugin that fires on the create (or update, if your Entity Form is for editing) of your entity:

public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

    var entity = context.InputParameters["Target"] as Entity;

    if (entity.Attributes.ContainsKey("nh_description"))
    {
        entity["nh_description"] = HttpUtility.UrlDecode(entity.GetAttributeValue<string>("nh_description")); ;
    }
}

This code simply decodes the value that was submitted so that you get back the original HTML. Again, replace nh_description with the name of the field you want the rich text editor on.

So while this technique a bit more work than disabling Request Validation, I’d argue it’s more secure. You’ll have to make the call whether the extra effort is worth it.

An Aside on Rich Text Editors for Power Apps Portals

In my example I used TinyMCE, but really you can use whichever editor you prefer. The Portal itself uses CKEditor (v4.6.2), however the references to the resources are not always included (for example, if your page template is a Web Template type, they only seem to be included when required by the platform for functionality like the legacy front-side editing). If you want to uses CKEditor, you might run into conflicts, so it something to consider when choosing a WYSIWYG editor.

13 responses to “Power Apps Portals: Rich Text Editor on Entity Forms”

  1. […] post Power Apps Portals: Rich Text Editor on Entity Forms appeared first on Engineered […]

  2. Swati says:

    Hello Nicholas Hayduk,
    Currently, I am working on this requirement and doing it within edit Entity from and stuck to do it with CKEditor as TinyMCE didn’t work for me 🙁
    Could I please request for ckEditor tutorial.Basically, I am struggling what the reference to add for ckEditor and what does it mean when you say add a reference to TinyMCE in the Copy attribute of your page?
    Looking forward to listen from you.
    Regards,
    Swati

  3. Swati says:

    Hello Nicholas,
    I am unable to get the tinyMCE reference in script. My question is where to add the reference. Perhaps, you mentioned “add a reference to TinyMCE in the Copy attribute of your page” but I am unable to understand this statement.
    Sincerely looking for help.
    Regards,
    Swati

    • Nicholas Hayduk says:

      Hi Swati,

      The “Copy” attribute contains the main content for the page. If you go into the Portal Management model-driven app, then go to Web Pages, find the page that contains your Entity Form, and then open up the language-specific (localized) version of your Web Page, and on that form you’ll see an attributed called “Copy”. Add the following script tag to that attribute:

      This will add the necessary script references for TinyMCE – you’ll need to sign up for a TinyMCE account and put in your API key into the URL to finish the setup.

      Hope that helps.

      Nick

  4. Bob says:

    Hi Nick,

    Thanks for this example which truly helps moving forward.

    Just one question though: where / how to register the plugin? Is it in the Custom JavaScript field on the Entity Form?

    Thanks in advance for your feedback!
    Bob

    • Nicholas Hayduk says:

      The JavaScript can go on the Custom JavaScript field on the Entity Form. The plugin code needs to be compiled into a C# assembly and uploaded via the Plugin Registration Tool, and a step registered on the create or update of the entity that you are creating/editing.

      Nick

  5. Piyush says:

    Hi Nick,

    Thanks for creating this post. If we do not want to use CKEditor or TinyMCE then aprt from this is there any way to achieve rich text editor out of the box?

    Thanks in advance,
    Piyush

    • Nicholas Hayduk says:

      There is nothing out of the box, so it’s up to you to pick whichever rich text editor you want – it really can be anything.

      Nick

  6. Diana Fernandez says:

    Hi Nicholas, Very good post.

    I tried it but my plugin is not working.I am receiving the text in the Dataverse field with a lot of characters, as if the process of decode is not working.

    Text received in the field:
    %3Cp%3EThis%20is%20an%20objective%3C%2Fp%3E

  7. Joe Jordan says:

    Hi Nicholas, thanks for this useful guide. We managed to get this working using the CKEditor, but can’t get it working to upload / view images. It seems that the built-in Model-Driven-App rich text editor saves images to the dataverse table msdyn_richtextfile, and adds the link accordingly to the rich text editor. The url only seems to work when logged into powerapps though through the back-end UI though. When using CKEditor, the link not longer works (as it replaces the domain, plus it is through a different authentication path – i.e. from the public portal, not power apps). Is there a way, that you know of, to configure the editor to work with images in the portal?

    • Nicholas Hayduk says:

      Hi Joe,

      The only way I’ve seen it done is to not use links, but instead have the image embedded using base64 directly in the content. This makes the content bigger, but means you don’t have to save the image elsewhere.

      Nick

  8. Pierre Joubert says:

    Hi Nicholas,

    I am having an issue that I can hope you can help, as I feel like I am missing something.

    Setting up an Entity List with a Create form, the popup dialog does not work at all. I configure everything using started settings, nothing custom, and the Create button just does not work. It has a link to “#” in the HREF which simply reloads the page with no modal, if I use a webpage instead of form then it redirects fine, but I do not want to create webpages for every form that I will be setting up – and there is going to be a lot of them.

    Any thoughts would be helpful.
    Thanks

    Any thoughts?

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact

Engineered Code is a web application development firm and Microsoft Partner specializing in web portals backed by Dynamics 365 & Power Platform. Led by a professional engineer, our team of technology experts are based in Regina, Saskatchewan, Canada.