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!
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).
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”.
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.
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.
Instead of removing it, you could detach instead. If you save a reference to the detached option, you can easily add it back at the appropriate time.
https://api.jquery.com/detach/
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
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.
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
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
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.
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.
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.
Something like:
$(document).ready(function() {
$(‘#casetypecode option’).each(function() {
if($(this).val() == ‘something’) {
$(this).remove();
}
});
});
Nick