In the first post of this series, we got a form script loading and reacting to a status change. This post goes deeper into the four operations you'll use in almost every form script: showing/hiding, enabling/disabling, setting required levels, and setting values — plus when you should reach for a Business Rule instead of writing code at all.
The Four Core Operations
Every field-level customization comes down to some combination of these, called on an attribute or its control via formContext:
var formContext = executionContext.getFormContext();
var control = formContext.getControl("new_discountreason");
var attribute = formContext.getAttribute("new_discountreason");
// 1. Show or hide a field
control.setVisible(true);
// 2. Enable or disable a field
control.setDisabled(false);
// 3. Set the required level
attribute.setRequiredLevel("required"); // "none", "recommended", or "required"
// 4. Set a value
attribute.setValue("Loyalty discount");
Business Rule vs. JavaScript: When to Use Which
Business Rules are the right first choice for simple, single-form or cross-form logic — they're faster to build, easier for other admins to maintain, and don't need a developer to change later. Reach for JavaScript when you need:
- Logic that depends on more than the handful of conditions a Business Rule can cleanly express
- Real-time reaction to typing, not just on change/save
- Calls to the Web API, external services, or anything Business Rules simply can't do
- Custom UI behavior — tab/section visibility, notifications, ribbon interaction
A good rule of thumb: if you can describe the logic in one sentence with "if this field equals X, then that field is required," use a Business Rule. If you're combining three or four conditions across multiple fields, JavaScript will be far easier to read and maintain.
A Practical Example: Multi-Field Conditional Logic
Here's a script that shows a discount reason field only when a discount is applied above a threshold, and only for certain customer types — logic that would get unwieldy fast in a Business Rule:
function onLoad(executionContext) {
var formContext = executionContext.getFormContext();
formContext.getAttribute("new_discountpercent").addOnChange(toggleDiscountReason);
formContext.getAttribute("new_customertype").addOnChange(toggleDiscountReason);
toggleDiscountReason(executionContext);
}
function toggleDiscountReason(executionContext) {
var formContext = executionContext.getFormContext();
var discount = formContext.getAttribute("new_discountpercent").getValue() || 0;
var customerType = formContext.getAttribute("new_customertype").getValue();
var reasonControl = formContext.getControl("new_discountreason");
var reasonAttr = formContext.getAttribute("new_discountreason");
var needsReason = discount > 10 && (customerType === 1 || customerType === 2);
reasonControl.setVisible(needsReason);
reasonAttr.setRequiredLevel(needsReason ? "required" : "none");
if (!needsReason) {
reasonAttr.setValue(null);
}
}
Section and Tab Visibility
The same show/hide pattern applies to whole sections and tabs, which is handy for progressively revealing parts of a long form:
var tab = formContext.ui.tabs.get("tab_shipping");
tab.setVisible(true);
var section = tab.sections.get("section_shippingdetails");
section.setVisible(true);
Common Pitfalls
- setRequiredLevel takes a string, not a boolean. Use "none", "recommended", or "required" — not true/false.
- Disabled fields still have values. setDisabled(true) stops editing but doesn't clear the value; clear it explicitly if that's what you need.
- Hidden required fields block save. If a field is required but hidden, users get stuck. Always pair setVisible(false) with setRequiredLevel("none").
- Re-run your logic on load, not just on change. If a record is opened with values already set, onChange handlers won't fire automatically — call your function once during OnLoad too, as in the example above.
What's Next
Next up: working with lookups, option sets, and subgrids from JavaScript — including how to filter a lookup's results based on another field on the form.


