Every Dynamics project has the same conversation. “Can we hide that field unless…” “Can this tab only show when…” “Can the subgrid disappear if…” Yea. All of it. That’s what this script does.
The Field That Started It
Client project. Combo box on the form. Extra field needed to appear, but only for one of the options. Not the other two. Standard ask, standard fix, twenty minutes of JS and move on.
Except I sat there after writing it and thought, hang on. This same pattern is going to come up again next week. And the week after. And it’s not just fields. It’s tabs, sections, subgrids, the lot.
So instead of writing the same five lines every time with slightly different variable names, I made one helper. Then I made it for everything else too.
Why Not Just Use Business Rules
Fair question. Business rules cover some of this. The maker/editor config panel covers a bit more. But once you’ve got more than a couple of conditions, or you want to do something the UI doesn’t expose (like prompt before clearing a subgrid), you’re back in JS anyway.
The maker config is lacking. Not customisable as much as I’d like. I do see why it’s locked down (kinda), keeping low-code low-code and all that. But the moment a real requirement lands, you’re writing script.
So if you’re writing script, you might as well write it once.
What’s In It
CrmHelpers is a single object with five functions. Each one takes the execution context, the field that triggers the change, the value to match against, and whatever you’re hiding or showing.
toggleControl— show/hide a single fieldtoggleSection— show/hide a section in a tabtoggleTab— show/hide a whole tabtoggleSubgrid— show/hide a subgrid, with optional “make sure it’s empty first” prompttrackInitialValue— call on form load so subgrid revert works
The match logic is the bit I’m most pleased with. You can pass the option set value as a number, the value as a string, or the label itself. All three work. So you don’t have to remember whether it’s 100000001 or "Partner", just give it whatever you’ve got.
The Subgrid One
This is where it earns its keep. Hiding a subgrid is fine. Hiding a subgrid that already has records in it is a problem, because the user thinks they’re gone, but the data’s still sat there in the related table.
So toggleSubgrid has a requireEmpty flag. If it’s true, and someone tries to change the field while there are still rows in the grid, it pops an alert telling them to clear the records first, and reverts the field back to its previous value.
That’s why trackInitialValue exists. Without it there’s nothing to revert to.
How You Use It
Drop the script on the form as a web resource. Wire each function up to the OnChange of the trigger field. One line per rule.
CrmHelpers.toggleControl(executionContext, "account_type", "Partner", "new_description");
CrmHelpers.toggleTab(executionContext, "account_type", "Partner", "tab_services");
CrmHelpers.toggleSubgrid(executionContext, "account_type", "Partner", "PartnerGrid", true);
That’s it. Three rules, three lines. No copy-pasting twenty lines of getAttribute / getValue / setVisible boilerplate per form.
What It Is Now
- One script, drop on any form
- Handles fields, sections, tabs, subgrids
- Match by option value or label, doesn’t care which
- Subgrid hide with empty-check and revert
- Initial value tracking for the revert to actually work
What’s Next
Maybe nothing. I might never touch this again. But if I do, here’s what’s probably on the list:
toggleRequiredfor setting fields required or optional on the same trigger patterntoggleDisabledwhile I’m in there- Multi-select option set support, which is a known gap
We’ll see if a project ever pushes me back to it.
A Note on the Tidy-Up
Before publishing I asked Claude to review the script. It gave me a B+ (cheers) and flagged that the match logic was copy-pasted across four functions. So I let it do the dedupe pass and pull the shared bit into a _matches helper.
Original logic and the API design are mine. The “stop repeating yourself you muppet” pass was AI. Credit where it’s due.
Repo’s here: github.com/R4RD0/CrmHelpers. MIT licenced, do what you like with it.
🤷