ecLearn - Learning Management System built on top of Microsoft Dataverse for Power Platform and Dynamics 365 users

ENGINEERED CODE BLOG

Power Apps Portals: Modifying Option Set Options on an Entity Form

If you’ve come from the world of Dynamics 365 (or CRM…) and are starting to work with Portals, it can be frustrating when you discover that client-side JavaScript code that works great in your model-driven app doesn’t work on a Power Apps Portal – especially because Entity Forms and Web Forms are marketed as a technology that exposes your existing forms to the web. In this post, we look at why it doesn’t translate and provide some code that solves a common request: modifying the available options in an option set.

In January I responded to a post on the Dynamics forums from someone who was wondering why the code they had written to remove options from an option set wasn’t working on their Power Apps Portal.

In model-driven apps, we’ve got access to an entire API to enhance our forms. In fact, developers are required to use these APIs – any direct DOM manipulation is unsupported.

Unlike model-driven apps, there is no official JavaScript API for interacting with forms created using Entity Forms or Web Forms. But this doesn’t mean that it’s unsupported; instead, you need to rely on standard client-side web development techniques to meet your business requirements. Unfortunately, this means that any code you write for your model-driven forms won’t work since the API doesn’t exist on the portal. You have to create Portals-specific JavaScript (for details on all the different places you can drop this code in, see this series of posts).

As an aside, since Power Apps Portals has been developed using jQuery, most of the examples you’ll find use it as well. However, there is no requirement to use it – you can write plain old JavaScript, or even add another framework if you want (as long as it doesn’t conflict with jQuery).

More Conventions than Documentation

There are few “documented” JavaScript extension points – for example, this documentation covers the loaded event that fires when an Entity List is loaded. However, if you are going to get into writing JavaScript for your Power Apps Portal, should probably get familiar with your browser’s developer tools so that you can look underneath the hood at how things work.

Microsoft (and Adxstudio before them) has done a good job of providing markup that allows for extensibility. For example, when dealing with entity forms and web forms, the ID of the input elements will match the logical name of the attribute in CDS. For Entity Lists, the markup provides vital information in data- attributes like the ID of the record or the types of the columns. Again, you may struggle to find documentation on this, but you’ll see it when you inspect the markup in the developer tools.

So, just because you don’t see any documentation, poke around – you’ll be amazed at what you can find.

Some may be worried that because it isn’t documented, it’s not supported. The platform has been pretty stable for a while, and while that doesn’t mean things can’t change, I would say that these techniques are widely used, and are not seen as “hacks” or “work arounds”.

The JS to Remove Options

So, back to the original question – how do we remove options from an option set?

In my example, I’d like to edit the list of options available in the Case Type (casetypecode) field. So, let’s look at the markup that the Portal generates for this field:

<td colspan="1" rowspan="1" class="clearfix cell picklist-cell">
    <div class="info">
        <label for="casetypecode" id="casetypecode_label">Case Type</label>
        <div class="validators"></div>
    </div>
    <div class="control">
        <select name="ctl00$ContentContainer$EntityFormControl_21bfeab3f60ee511946100155d038c01$EntityFormControl_21bfeab3f60ee511946100155d038c01_EntityFormView$casetypecode" id="casetypecode" class="form-control picklist " onchange="setIsDirty(this.id);">
            <option selected="selected" value="" label=" "> </option>
            <option value="1">Question</option>
            <option value="2">Problem</option>
            <option value="3">Request</option>
        </select>
    </div>
</td>

As you can see, it is a standard select field type, with the ID being casetypecode. So, the JavaScript to remove options would look something like:

$(document).ready(function() {
  $('#casetypecode option[value="1"]').remove();
});

Here we are using jQuery selectors to find the option whose value is 1, and remove it.

Now, if you looked at the actual request on the forums, you may have noticed that they wanted the options to disappear only for certain people. That is possible as well, using a combination of Liquid and JavaScript (which are better together). If we wanted it based on Web Roles, for example, we could do something like:

{% if user.roles contains 'Administrators' %}
$(document).ready(function() {
  $('#casetypecode option[value="1"]').remove();
});
{% endif %}

This will only remove the options for users with the Administrators Web Role.

One thing to note: just like in a model-driven app, removing the option doesn’t mean someone can’t use browser developer tools to add it back. So this is more for convenience, as opposed to security.

10 responses to “Power Apps Portals: Modifying Option Set Options on an Entity Form”

  1. Fabian says:

    Thank you this helps me a lot.
    But how can I add the removed value back to the list? In my case I want to remove a value if a value of an other field is selected, but if a different value is selected the removed value should be usable again.

  2. Paul Chapman says:

    Hi Nicholas,

    Love your blogs, really helpful, thank you. This post in particular shows how to do exactly the thing I was trying to do 🙂

    However, for some reason I can’t get it working. I am using the simple option-value-remove code as above, I’ve only swapped in my own control id and value, but it isn’t hiding my dropdown options. Any idea where I should check? I am adding the code to Entity Form > Additional Settings > Custom Javascript, and emptying the portal cache each time, but so far nada.

    Any thoughts much appreciated

  3. Paul Chapman says:

    Hey Nicholas,

    Thought I quickly post the solution to my problem. I’m new to jQuery (and Javascript!) so this is probably obvious to most. Where your example stated: $(‘#casetypecode option[value=”1″]’).remove() I had got the ” where you had ‘ and I had ‘ where you had “. And it turns out that is not good! You live, you learn. Cheers.

  4. Suresh says:

    Hey Nicholas,

    I have requirement when item selected on picklist, means onchange event of picklist, need to do write some logic.
    But onchange event is already rendered like below, due to this, unable to call my function where I written the JS logic.
    onchange=”setIsDirty(this.id)”

    So how do I call my function on onchange event? why setIsDirty function came here, how to avoid this fn?

    Please help me! waiting for your answer.

    Thanks
    Suresh

    • Nicholas Hayduk says:

      Hi Suresh,

      You should be able to use standard jQuery to attach to the onchange event without modifying the setIsDirty. Something like:

      $(document).ready(function() {
      $(‘#new_yourfieldnamehere’).change(function() {
      //put your onchange logic here
      });
      });

      Nick

  5. shiv says:

    is there a way to change the status reason value through js on click of a custom buton?
    i tried this js
    $(“#statuscode”).val(valueofstatus) – but it is no working.

    • Nicholas Hayduk says:

      Unfortunately no, the status reason can’t be changed like that, as it requires a separate SDK message.

      One option is to create another regular field that you can update, and use a workflow/flow to set the appropriate status.

  6. Darin Johnson says:

    how about looping thru the options an removing some that meet a criterion? I have been on this for 3 days… 😀 getting a little loopy. I just need to loop thru the options of a lookup using javascript.

    • Nicholas Hayduk says:

      Something like:

      $(document).ready(function() {
      $(‘#casetypecode option’).each(function() {
      if($(this).val() == ‘something’) {
      $(this).remove();
      }
      });
      });

      Nick

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.