Showing and hiding sections on a form is not possible to do in a
fully supported way without hiding all components of the section.
This can be quite arduous, and
in addition someone might have created a business rule that messes that up for
you and all of a sudden, it's visible anyway.
To help with that there's a
great little function hidden in the client side library that you could use
Xrm.Page.ui.tabs. get(delegate: MatchingDelegate<T>): T[];
This little bit lets you query for a tab using a filter in form of
a function. This will let you specify criteria like section content and other
properties/attributes.
This means you loop through all tabs on the form and filter by the
criteria specified. I’m doing the following (please notice that I’m writing in
typescript):
var parentTab =
parent.Xrm.Page.ui.tabs.get(t => {
return t.sections.get("MyUniqueSectionName") !== null
});
var mySection =
parentTab[0].sections.get("MyUniqueSectionName");
mySection.setVisible(false);
For the first part, I’m creating a delegate function
of t, where t is the current tab being iterated over.
Inside the delegate there’s a short one-liner which
returns true if there is a section in the tab with the unique name. This will
generate an array of tabs as a result set. I made sure that I used a unique name
for my section so I will only get one tab in return.
Next I collect the section from the result set, and
finally set the visibility to false.
Putting this into a reusable function with two
parameters, I can now utilize it as follows:
setSectionVisibility("MyFirstUniqueSectionName",
false);
setSectionVisibility("MySecondUniqueSectionName",
true);
Now I can reuse the function and trigger it on field
changes or form load to make sure I only show the sections applicable for a
given scenario.
Quirks!
I found one quirk with this which was kind of
annoying, but luckily the fix isn’t particularly hard. If you have a business
rule which shows and hides fields in a section, and that section is hidden at
the same time (for example if you trigger on change of a field, and both the
business rule and this javascript snippet triggers on the same change), then
the following quirk happens.
The section stays visible, but if you write out console.log(mySection.getVisible())
it will say “false”. I assumed there was some race condition going on, because
if I hid a field with a business rule at the same time as I hid the section
with this javascript, then the section stayed visible but the field got hidden.
I did some testing and found out that if you put it inside a setTimeout() then
it works like a charm. What I ended up doing was this:
setTimeout(f => {
setSectionVisibility("MyFirstUniqueSectionName", false);
setSectionVisibility("MySecondUniqueSectionName", true);
}, 10);
Even though the timeout is only 10 milliseconds that’s
still enough to prevent the race condition, and everything works brilliantly.
Another thing I found is that the tab has another,
undocumented function: Xrm.Page.ui.tabs. getByFilter(delegate: MatchingDelegate<T>): T[];
This does the same thing as get(…), but has a longer,
more explicit function name. Seeing that this is undocumented I would stay away
from it as long as both do the same thing (using Daryl Labar’s DefinitelyTyped
definitions for Xrm in Typescript will only show the documented function).
Edit:
I have been notified that the xrm definitions of DefinitelyTyped is an effort made by the following:
David Berry
Matt Ngan
Markus Mauch
Daryl LaBar
Tully H
Matt Ngan
Markus Mauch
Daryl LaBar
Tully H
I would not consider the DefinitelyTyped definitions for XRM mine. Dave Berry was the original instigator, but it truly is a community effort. Currently these are the individuals that are listed as maintaining it: David Berry ,
ReplyDeleteMatt Ngan ,
Markus Mauch ,
Daryl LaBar ,
Tully H