Client Scripts vs UI Policies: Choosing the Right Tool for Salesforce UI Customization






Client Scripts vs UI Policies: Mastering ServiceNow Form Interactions


Client Scripts vs UI Policies: Mastering ServiceNow Form Interactions

In the dynamic world of ServiceNow development, crafting intuitive and efficient user experiences on forms is paramount. Two of the primary tools at our disposal for achieving this are Client Scripts and UI Policies. While both aim to control how forms behave on the client-side, they differ significantly in their approach, complexity, and use cases. Understanding these differences is crucial for any ServiceNow developer looking to build robust and user-friendly applications.

This article delves deep into the nuances of Client Scripts and UI Policies, demystifying their functionalities, providing practical examples, and highlighting when to use each. We’ll also touch upon related concepts like Data Policies and explore troubleshooting common scenarios. So, buckle up, and let’s master ServiceNow form interactions!

Understanding the Core: What are UI Policies?

At their heart, UI Policies are a declarative way to apply client-side logic to forms. Think of them as pre-configured actions that you can trigger based on certain conditions. The ServiceNow documentation succinctly puts it: “UI policies are used to make a field mandatory, read only, display and to show the related lists at certain condition in the client side.” This covers the most common scenarios where you want to dynamically alter form behavior without writing code.

Key Features and Configurations of UI Policies

UI Policies offer a set of configurable options that allow for precise control over form elements. Let’s break down some of the most important ones:

The ‘Global’ Checkbox: Wider Reach for Your Policies

The Global checkbox dictates the scope of your UI Policy.
When this box is checked, your UI Policy will work on all views of a form. This is the default and often desired behavior for core form logic. However, if you need a UI Policy to apply only to a specific view (e.g., a custom view for a particular role), you can uncheck ‘Global’. When unchecked, it will prompt you to specify the view name(s) where the policy should be active.

‘Reverse if False’: Reverting Actions Gracefully

This is a wonderfully practical feature. If the Reverse if false checkbox is selected, the actions applied by the UI Policy will be automatically reversed when the condition evaluates to false. For example, if a field was made mandatory when a certain condition was true, checking this box means it will become optional again when that condition is no longer met. This prevents fields from remaining mandatory or read-only indefinitely if the criteria change.

The ‘On Load’ Checkbox: Initial Form Load vs. Dynamic Changes

The On Load checkbox is critical for how and when your UI Policy executes.
When selected, the UI Policy’s conditions and actions are evaluated and applied immediately when the form is loaded. This is perfect for setting initial states. If the ‘On Load’ checkbox is not selected, the UI Policy actions won’t be applied when the form initially loads. Instead, they will only be triggered dynamically when a specific field’s value changes or another relevant condition is met on the form.

The ‘Inherit’ Checkbox: Extending Logic to Child Tables

In ServiceNow’s hierarchical table structure, the Inherit checkbox offers a powerful way to reuse logic. When checked, the same UI Policy will be applied to child tables that extend the table on which the UI Policy was initially applied. This means if you have a UI Policy on the ‘Task’ table that makes ‘Assignment group’ visible under certain conditions, and tables like ‘Incident’ or ‘Problem’ extend ‘Task’, that UI Policy logic will automatically extend to those child tables.

Can You Write Scripts in UI Policies?

Yes, you absolutely can! While UI Policies are primarily declarative, they offer the flexibility to incorporate scripting. For adding a script, you’ll need to enable the Run scripts checkbox within the UI Policy Action. Once enabled, you can enter a script that will execute when the UI Policy’s conditions are met. This bridges the gap between simple declarative actions and more complex custom logic, allowing you to perform actions like setting field values, making specific calculations, or interacting with other form elements in more sophisticated ways.

UI Policies vs. Data Policies: A Quick Comparison

It’s common to confuse UI Policies with Data Policies, as they both control field states. However, they operate at different levels and serve distinct purposes.

What are Data Policies?

Data Policies are used to enforce data integrity across all data sources. Like UI Policies, they can make fields mandatory, read-only, or control their display. The key difference is that Data Policies work on both the client-side AND server-side. This means they enforce rules regardless of how the data is entered – whether through a form, an integration, or a direct database update.

Converting UI Policies to Data Policies

ServiceNow provides a convenient feature to convert UI Policies into Data Policies. If you open a UI Policy and find the option, you can click “Convert this UI Policy into a Data Policy.” This is useful when you realize a form behavior you implemented with a UI Policy needs to be enforced universally, not just on the form.

When Conversion Isn’t Possible

Not all UI Policies can be directly converted into Data Policies. The cases where UI Policies cannot be converted as Data Policies typically involve functionalities that are purely UI-specific and don’t translate directly to data integrity rules. These include:

  • Controlling data visibility in ways that aren’t about making fields mandatory or read-only (e.g., hiding entire sections of a form for non-essential fields).
  • Controlling views – Data Policies don’t manage how a form is displayed in different views.
  • Controlling related lists – This is a UI-specific behavior.
  • Controlling scripts that perform complex client-side manipulations not directly related to data validation.

Delving into Client Scripts

While UI Policies are excellent for straightforward, declarative form manipulations, Client Scripts offer a more powerful and flexible approach when you need to implement complex business logic on the client-side. They are essentially JavaScript code that runs within the user’s browser when an event occurs on a form or list.

Client Scripts allow you to:

  • Manipulate form elements: Show/hide fields, make them mandatory/read-only, set their values, add options to choice lists, etc.
  • Perform calculations: Calculate dates, sum up numbers, derive values based on other fields.
  • Validate data: Implement custom validation rules beyond simple mandatory or read-only states.
  • Interact with GlideAjax: Fetch data from the server without a full page reload.
  • Control UI behavior: Add buttons, display messages, and much more.

Types of Client Scripts

ServiceNow categorizes Client Scripts based on when they run:

onChange Scripts: Reacting to Field Changes

These scripts execute whenever the value of a specific field on the form changes. This is incredibly useful for dynamic updates. For instance, if the ‘State’ field changes to ‘Resolved’, an onChange script could automatically set the ‘Close notes’ field to mandatory and visible.
Example:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }

    // If State changes to Resolved (value 7)
    if (newValue === '7') {
        g_form.setMandatory('close_notes', true); // Make close notes mandatory
        g_form.setVisible('close_notes', true);  // Make close notes visible
        g_form.setLabel('close_notes', 'Resolution Details'); // Change label
    } else {
        g_form.setMandatory('close_notes', false); // Make close notes optional
        g_form.setVisible('close_notes', false);  // Hide close notes
    }
}

onLoad Scripts: Initializing the Form

These scripts run once when the form is initially loaded. They are ideal for setting default values, making certain fields read-only based on the record’s state, or displaying initial messages.
Example:

function onLoad() {
    // If the record is already resolved, make close notes mandatory and visible
    if (g_form.getValue('state') === '7') {
        g_form.setMandatory('close_notes', true);
        g_form.setVisible('close_notes', true);
    } else {
        g_form.setVisible('close_notes', false); // Hide if not resolved
    }

    // Example: Disable 'Configuration Item' if User is 'System Administrator'
    if (g_user.hasRole('admin')) {
        g_form.setReadOnly('cmdb_ci', true);
    }
}

onSubmit Scripts: Final Checks Before Submission

These scripts execute just before a record is submitted to the server. They are perfect for performing final validations to ensure data integrity. If an onSubmit script returns false, the submission is canceled.
Example:

function onSubmit() {
    // If 'Urgency' is High (value 1) and 'Impact' is also High (value 1)
    if (g_form.getValue('impact') === '1' && g_form.getValue('urgency') === '1') {
        // Check if 'Approval' is not 'requested'
        if (g_form.getValue('approval') !== 'requested') {
            // Ask for confirmation before submitting
            if (!confirm('Both Impact and Urgency are High. Do you want to proceed without requesting approval?')) {
                return false; // Prevent submission
            }
        }
    }
    return true; // Allow submission
}

onCellEdit Scripts: Editing Grid Data

These scripts are used for controlling behavior when editing records directly in a list view (grid). They allow you to validate or modify data as it’s being edited in the list.
Example: (Less common for beginners, but powerful)

function onCellEdit(sysIDs, table, oldValues, newValues, displayValue, currentCell) {
    // If editing the 'priority' field in the 'Incident' table
    if (table == 'incident' && currentCell.fieldName == 'priority') {
        var newPriority = newValues[0];
        // If priority is set to 1 (Critical)
        if (newPriority == 1) {
            // Prevent saving if State is not 'In Progress' or 'On Hold'
            var stateValue = g_form.getValue('state'); // Note: g_form is not directly available here like in form scripts. You might need GlideAjax or other methods.
            // This is a conceptual example. Actual implementation may vary.
            // For simplicity, let's assume we're checking based on a separate field for demonstration.
            // A more robust solution would involve GlideAjax to get related record data.

            // Simplified check: If the user is trying to set critical priority
            // and the record is already Resolved or Closed, alert them.
            var currentState = g_form.getValue('state'); // This might not work directly here without specific context.
            // In a real scenario, you might fetch the state via GlideAjax if needed.
            // Let's assume a simpler validation for now.
            var currentRecordSysId = sysIDs[0]; // Sys ID of the record being edited

            // A common use case is to check if a required field is empty when a certain condition is met
            if (newPriority == 1 && g_form.getValue('assigned_to') == '') {
                g_form.setMandatory('assigned_to', true);
                g_form.addErrorMessage('Assigned to is mandatory for Critical priority.');
                return false; // Prevent edit
            }
        }
    }
    return true; // Allow edit
}

Client Scripts vs. UI Policies: The Deciding Factors

Now that we’ve explored both, let’s crystallize when to choose which.

When to Use UI Policies:

  • Simplicity is key: For straightforward requirements like making a field mandatory, read-only, visible/hidden, or setting its default value.
  • Declarative approach preferred: When you want to configure behavior without writing code, making it easier for functional consultants or administrators to manage.
  • Auditing and ease of management: UI Policies are easily auditable and their logic is transparently laid out in the ServiceNow UI.
  • Broad impact across views: If the logic needs to apply consistently across all views.
  • Inheritance is beneficial: When you want the logic to automatically apply to extended tables.
  • Performance considerations (initial load): For simple visibility or read-only changes on load, UI Policies can sometimes be more performant than complex `onLoad` scripts.

Real-world example: On an “Incident” form, if the “State” is set to “Resolved”, make the “Resolution Notes” field mandatory and visible. This is a perfect candidate for a UI Policy.

When to Use Client Scripts:

  • Complex logic required: When you need to perform calculations, complex conditional logic, or interact with multiple fields in intricate ways.
  • Dynamic calculations: Calculating due dates based on other fields, summing up costs, or deriving a value based on a combination of inputs.
  • Advanced data validation: Implementing custom validation rules that go beyond simple mandatory/read-only states (e.g., checking if a date is within a specific range, or if a string matches a pattern).
  • Server interaction: Fetching data from the server using GlideAjax to populate fields or validate data without a full page refresh.
  • UI manipulation beyond basic control: Showing/hiding multiple fields based on a complex condition, adding custom buttons, or displaying dynamic messages.
  • Specific event triggers: When you need to react precisely to a field change (onChange), form submission (onSubmit), or initial load (onLoad) with custom code.

Real-world example: On a “Change Request” form, if the “Risk” is set to “High” and “Impact” is set to “High”, automatically populate the “Assignment group” to “CAB Approvals” and set the “Approval” field to “Requested”. This involves multiple field manipulations and conditional logic, making it a good fit for a Client Script.

The Interaction Between UI Policies and Client Scripts

It’s important to understand how these two powerful tools interact. Generally, UI Policies are processed before Client Scripts that run on load. However, if a UI Policy action is triggered by an onChange event on a field, and there’s also an onChange Client Script for that same field, the order can become critical.

Order of Execution (Simplified):

  1. UI Policies (On Load): Process first when the form loads.
  2. Client Scripts (On Load): Process next.
  3. UI Policies (triggered by field changes): Process based on the triggering field’s change.
  4. Client Scripts (onChange): Process based on the triggering field’s change.

In cases where both a UI Policy and a Client Script manipulate the same field, the last one to execute will often have the final say. This can lead to unexpected behavior if not managed carefully.

Interview Tip: When asked about the order of execution, mention that UI Policies (on load) run before Client Scripts (on load). For `onChange` events, it’s a bit more nuanced, but generally, ServiceNow tries to execute them logically. However, if you have conflicting logic, you might need to debug the order or use scripting to control the outcome.

Troubleshooting Common Scenarios

Here are some common issues and how to address them:

UI Policy Not Running on Load

Cause: The ‘On Load’ checkbox might be unchecked. Or, the condition might not be met initially.

Solution: Ensure ‘On Load’ is checked if you want it to run immediately. Verify the condition logic. Check the browser console for JavaScript errors.

Client Script Not Triggering on Field Change

Cause: The ‘Field name’ selected for the onChange script might be incorrect, or the script might have an error preventing it from executing. Or, the condition within the script might be faulty.

Solution: Double-check the ‘Field name’ in the Client Script definition. Use gs.log() or `console.log()` within your script to debug its execution flow and check for errors. Ensure the `isLoading` and `newValue === ”` checks are handled correctly.

Conflicting Behavior Between UI Policy and Client Script

Cause: Both are trying to control the same field, and the order of execution leads to an unexpected state.

Solution: Analyze the order of execution. If possible, consolidate the logic into one or the other. If they must coexist, use scripting within the UI Policy Action (if applicable) or the Client Script to override or manage the state explicitly based on which one should “win.” Consider setting UI Policy order if they are both UI policies. For UI Policy vs. Client Script, the Client Script often has more control if it runs later.

Global UI Policy Affecting Unintended Views

Cause: The ‘Global’ checkbox was checked when it should have been specific to certain views.

Solution: Uncheck the ‘Global’ checkbox and specify the exact view names where the UI Policy should apply.

Performance Issues on Form Load

Cause: Too many UI Policies and/or Client Scripts running on load, especially with complex logic or GlideAjax calls.

Solution: Optimize your scripts and policies. Combine logic where possible. Defer non-critical operations. Use UI Policies for simpler tasks. Ensure GlideAjax calls are efficient and return only necessary data. Use the ‘Isolate script-engine’ option for Client Scripts if necessary, but be aware of its implications.

Interview Relevance: What to Expect

In a ServiceNow developer interview, expect questions that test your understanding of these core concepts. Be prepared to discuss:

  • The primary differences between UI Policies and Client Scripts.
  • When you would choose one over the other.
  • Examples of common scenarios for each.
  • The order of execution for UI Policies and Client Scripts.
  • The purpose of specific UI Policy attributes (Global, Reverse if False, On Load, Inherit).
  • How to handle complex form logic.
  • The role of Data Policies and how they differ from UI Policies.
  • How to debug client-side scripts.

Interview Tip:

When asked to compare Client Scripts and UI Policies, start with the declarative nature of UI Policies (no code needed for basic tasks) and the programmatic power of Client Scripts (JavaScript for complex logic). Emphasize that UI Policies are generally easier to manage for simple tasks and are great for widespread application via the ‘Global’ and ‘Inherit’ flags. Client Scripts are your go-to for anything beyond basic field manipulation, calculations, and server communication (GlideAjax).

Conclusion

Mastering the interplay between Client Scripts and UI Policies is fundamental to building effective and user-friendly ServiceNow applications. UI Policies offer a streamlined, declarative way to manage common form interactions, while Client Scripts provide the power and flexibility to implement complex business logic. By understanding their individual strengths, differences, and how they interact, you can make informed decisions, build more efficient forms, and ultimately enhance the user experience for your ServiceNow instance.

Remember to always consider the simplest solution first (UI Policy) and escalate to Client Scripts when the complexity demands it. Happy scripting and policy-making!


Scroll to Top