- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hi Team,
I am facing a doubt related to UI Policy behavior and I would like some clarification.
I have created two UI Policies on the Incident table:
UI Policy 1
Condition: Category = Hardware
Action: Subcategory = Mandatory
UI Policy 2
Condition: Category = Network
Action: Subcategory = Visible = false
Scenario I am observing:
I create a new Incident record
First, I select Category = Hardware
→ Subcategory becomes mandatory (this works as expected)Without saving the record, I change Category = Network
→ Subcategory is still visible (UI Policy 2 does not apply)If I change back to Hardware, Subcategory again becomes mandatory
Now, if I create another new Incident:
First, I select Category = Network
→ Subcategory becomes not visible (this works)Then without saving, I change Category = Hardware
→ Subcategory becomes mandatoryAfter that, if I switch back to Network, the Subcategory visibility does not change as per UI Policy
So the UI Policy seems to work correctly only the first time, based on which category is selected first, and then it does not always revert correctly when switching values without saving.
My doubt:
Is this expected behavior of UI Policies?
Do UI Policies evaluate only once per form load?
Is this because the record is not saved?
Do I need to use Reverse if false, order, or Client Scripts to handle this?
Please let me know the correct approach to handle this scenario.
Thanks in advance.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello @themadhankumar ,
I have seen this type of issue when the action is written on the same field in two different UI Policies.
So, I try to use the action in the same UI Policy and try to build conditions using OR condition.
However, I believe the requirement here cannot be build within the same UI Policy.
Can you check by using Reverse if false condition. If this does not work, try with Client Scripts.
If the above information helps you, Kindly mark this as Helpful and Accept the solution.
Regards,
Najmuddin
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
Test Case
Requirement
When the user changes the Category field on the Incident form:
If Category = network
→ Disable Subcategory and make it non-mandatoryIf Category = hardware
→ Enable Subcategory and make it mandatory
This should happen immediately when the field value changes on the form.
Correct Solution Used
Type: Client Script
Script Type: onChange
Field Name: category
Final Working Script
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
g_form.clearMessages();
g_form.addInfoMessage("Client Script triggered. Value: " + newValue);
if (newValue == 'network') {
g_form.setMandatory('subcategory', false);
g_form.setDisplay('subcategory', false);
}
if (newValue == 'hardware') {
g_form.setDisabled('subcategory', false);
g_form.setMandatory('subcategory', true);
}
}Things to Do (Step-by-Step)
Go to System Definition → Client Scripts
Create a new Client Script
Set:
Type = onChange
Table = Incident
Field name = category
Active = true
Use field names, not labels
Save the script
Perform a hard refresh (Ctrl + Shift + R)
Mistakes Made By Me(Point by Point)
Used UI Policy when the requirement needed real-time field change behavior
(UI Policies do not behave like onChange scripts)Expected alert() to work
(Blocked in new isolated client scripts)Used console.log()
(Caused “Unexpected console statement” warning)Passed multiple parameters to g_form.addInfoMessage()
(Method accepts only one string parameter)Used incident.subcategory instead of subcategory
(Client scripts accept only field names, not table.field)Case mismatch in choice values
(network is not the same as Network)Cache was not cleared after creating new scripts
(ServiceNow loads cached client logic)
Debugging Methods Used
g_form.addInfoMessage()
Used to confirm that the script was executingChecking the Info Message output
Confirmed correct newValue was receivedRemoving UI Policy conflicts
Ensured client script changes were not overriddenVerifying field names in Dictionary
Confirmed actual field names and choice valuesHard refresh and cache clear
Ensured latest client script was loaded
Key Takeaways
Use Client Scripts (onChange) for real-time field change behavior
Use UI Policies for simple UI rules without scripting
Always use field names, not labels or table.field
New client scripts run in isolated mode
g_form.addInfoMessage() is the safest debugging method
Choice values are case-sensitive
when Category = Hardware
when Category = Network
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hello @themadhankumar
The behavior you are observing is expected based on how UI Policies work in ServiceNow. Here is the explanation:
UI Policies do not always re-evaluate automatically on every field change. They trigger when the form loads and when the condition of the UI Policy is met, but if you change the field value multiple times without saving, some actions (like visibility) may not revert as expected.
Reverse if false is important. If you want a field to revert to its original state when the condition is no longer true, you must check the “Reverse if false” option on the UI Policy. Without it, the field may retain its previous state.
Order of UI Policies matters. If multiple UI Policies affect the same field, the one with higher order executes first, but overlapping actions can cause inconsistent behavior when switching values.
Client Scripts can be used if needed. For complex scenarios where fields need to dynamically change on multiple value switches without saving, a Client Script (onChange) may give more reliable control.
Saving the record is not required for UI Policies to work, but some behaviors like visibility and mandatory state may not toggle correctly unless Reverse if false is enabled and UI Policy order is considered.
Recommended approach:
Enable Reverse if false on both UI Policies.
Set the order of the UI Policies to ensure predictable execution.
If needed, use an onChange Client Script for the Category field to handle dynamic visibility or mandatory rules more reliably.
Reference: ServiceNow Docs – UI Policies
If this response proves useful, please mark it as Accept as Solution and Helpful. Doing so benefits both the community and me. 👍🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
both of the UI Policy are true with the Reverse is false, but still it is not working with my expectation or my test case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
Test Case
Requirement
When the user changes the Category field on the Incident form:
If Category = network
→ Disable Subcategory and make it non-mandatoryIf Category = hardware
→ Enable Subcategory and make it mandatory
This should happen immediately when the field value changes on the form.
Correct Solution Used
Type: Client Script
Script Type: onChange
Field Name: category
Final Working Script
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
g_form.clearMessages();
g_form.addInfoMessage("Client Script triggered. Value: " + newValue);
if (newValue == 'network') {
g_form.setMandatory('subcategory', false);
g_form.setDisplay('subcategory', false);
}
if (newValue == 'hardware') {
g_form.setDisabled('subcategory', false);
g_form.setMandatory('subcategory', true);
}
}Things to Do (Step-by-Step)
Go to System Definition → Client Scripts
Create a new Client Script
Set:
Type = onChange
Table = Incident
Field name = category
Active = true
Use field names, not labels
Save the script
Perform a hard refresh (Ctrl + Shift + R)
Mistakes Made By Me(Point by Point)
Used UI Policy when the requirement needed real-time field change behavior
(UI Policies do not behave like onChange scripts)Expected alert() to work
(Blocked in new isolated client scripts)Used console.log()
(Caused “Unexpected console statement” warning)Passed multiple parameters to g_form.addInfoMessage()
(Method accepts only one string parameter)Used incident.subcategory instead of subcategory
(Client scripts accept only field names, not table.field)Case mismatch in choice values
(network is not the same as Network)Cache was not cleared after creating new scripts
(ServiceNow loads cached client logic)
Debugging Methods Used
g_form.addInfoMessage()
Used to confirm that the script was executingChecking the Info Message output
Confirmed correct newValue was receivedRemoving UI Policy conflicts
Ensured client script changes were not overriddenVerifying field names in Dictionary
Confirmed actual field names and choice valuesHard refresh and cache clear
Ensured latest client script was loaded
Key Takeaways
Use Client Scripts (onChange) for real-time field change behavior
Use UI Policies for simple UI rules without scripting
Always use field names, not labels or table.field
New client scripts run in isolated mode
g_form.addInfoMessage() is the safest debugging method
Choice values are case-sensitive
when Category = Hardware
when Category = Network
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago
Test Case
Requirement
When the user changes the Category field on the Incident form:
If Category = network
→ Disable Subcategory and make it non-mandatoryIf Category = hardware
→ Enable Subcategory and make it mandatory
This should happen immediately when the field value changes on the form.
Correct Solution Used
Type: Client Script
Script Type: onChange
Field Name: category
Final Working Script
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
g_form.clearMessages();
g_form.addInfoMessage("Client Script triggered. Value: " + newValue);
if (newValue == 'network') {
g_form.setMandatory('subcategory', false);
g_form.setDisplay('subcategory', false);
}
if (newValue == 'hardware') {
g_form.setDisabled('subcategory', false);
g_form.setMandatory('subcategory', true);
}
}Things to Do (Step-by-Step)
Go to System Definition → Client Scripts
Create a new Client Script
Set:
Type = onChange
Table = Incident
Field name = category
Active = true
Use field names, not labels
Save the script
Perform a hard refresh (Ctrl + Shift + R)
Mistakes Made I Made (Point by Point)
Used UI Policy when the requirement needed real-time field change behavior
(UI Policies do not behave like onChange scripts)Expected alert() to work
(Blocked in new isolated client scripts)Used console.log()
(Caused “Unexpected console statement” warning)Passed multiple parameters to g_form.addInfoMessage()
(Method accepts only one string parameter)Used incident.subcategory instead of subcategory
(Client scripts accept only field names, not table.field)Case mismatch in choice values
(network is not the same as Network)Cache was not cleared after creating new scripts
(ServiceNow loads cached client logic)
Debugging Methods Used
g_form.addInfoMessage()
Used to confirm that the script was executingChecking the Info Message output
Confirmed correct newValue was receivedRemoving UI Policy conflicts
Ensured client script changes were not overriddenVerifying field names in Dictionary
Confirmed actual field names and choice valuesHard refresh and cache clear
Ensured latest client script was loaded
Key Takeaways
Use Client Scripts (onChange) for real-time field change behavior
Use UI Policies for simple UI rules without scripting
Always use field names, not labels or table.field
New client scripts run in isolated mode
g_form.addInfoMessage() is the safest debugging method
Choice values are case-sensitive
