ServiceNow g_form API: What It Is & How to Use It

Unleashing the Power of `g_form`: Your Client-Side Maestro in ServiceNow

Ever found yourself staring at a ServiceNow form, wishing you could make a field magically appear or disappear based on a user’s choice? Or perhaps you’ve wanted to give instant feedback to a user without them having to save the record first? If so, then you’ve probably been looking for a way to bend the form to your will right there in the user’s browser.

Enter the star of our show: the g_form API. In the world of ServiceNow development, particularly when dealing with the user interface, g_form is your best friend. It’s the primary gateway for client-side scripting, allowing you to manipulate forms dynamically, enhance user experience, and enforce business logic in real-time without ever touching the server – well, not directly, anyway.

This article will take you on a deep dive into the g_form API. We’ll explore its fundamental purpose, walk through essential methods, discuss practical use cases, touch on critical best practices, and even clarify some common misunderstandings. Whether you’re a seasoned ServiceNow developer or just starting, understanding g_form is absolutely crucial for building robust and user-friendly applications.

The Heart of Client-Side Scripting: Understanding `g_form`

What Exactly is `g_form`?

Imagine you’re building a house. You have a detailed blueprint (the server-side data model and business rules), but you also need to interact with the people living in it – showing them what’s relevant, guiding them, or perhaps hiding a messy room until it’s clean. In ServiceNow, the form itself is like the interface to that house, and g_form is your toolkit for making real-time adjustments on the spot, directly within the user’s web browser.

As per the straightforward definition, g_form is an object used to change or make modifications on a form at the client side. You access all its wonderful capabilities simply by typing g_form. followed by the method you want to use.

This “client-side” distinction is key. When we say client-side, we mean code that runs in the user’s browser (e.g., Chrome, Firefox, Edge). This is different from “server-side” code, which runs on the ServiceNow instance itself. The beauty of client-side scripting with g_form is that it provides immediate feedback and interactivity, leading to a much smoother and more intuitive user experience. Think instant validation, dynamic field visibility, or auto-populating fields as a user types – all without a page reload.

You’ll primarily encounter g_form within Client Scripts (onLoad, onChange, onSubmit) and occasionally within the “Execute if true” or “Execute if false” script sections of UI Policies when the “Run scripts” checkbox is selected. It’s the core component for almost any interactive form customization.

Your Daily Toolkit: Essential `g_form` Methods

Let’s roll up our sleeves and dive into some of the most frequently used g_form methods. These are the workhorses you’ll be calling upon time and again to bring your forms to life.

Giving Feedback: `addInfoMessage()` and `addErrorMessage()`

Communication is key, right? When a user interacts with your form, they need to know what’s happening. Did they do something wrong? Was their action successful? This is where messages come in handy.

  • g_form.addInfoMessage("Your request has been submitted successfully!");
  • g_form.addErrorMessage("Please fill in the 'Short Description' field before saving.");

These methods allow you to display non-intrusive messages at the top of the form. `addInfoMessage` is perfect for success notifications or general guidance, while `addErrorMessage` is designed to highlight issues that prevent form submission or require user attention. They’re far superior to old-school JavaScript `alert()` boxes, as they don’t halt user interaction and blend better with the ServiceNow UI.

Practical Scenario: Imagine a complex approval form. When a user changes the “Approval Status” to “Rejected”, you might add an info message reminding them to provide a rejection reason in a separate field. If they try to submit without it, an error message can guide them back.

Interview Relevance: Interviewers often ask about the best ways to communicate with users on a form. Knowing `addInfoMessage` and `addErrorMessage` demonstrates a solid understanding of user experience best practices over using `alert()`.

Dynamic Field Control: `setMandatory()`, `setReadOnly()`

Forms often need to adapt based on context. A field might be optional initially, but become mandatory once a certain condition is met. Or perhaps you want to lock down fields after a record reaches a specific state. These methods are your go-to for such dynamic control.

  • g_form.setMandatory("u_reason_for_change", true);
  • g_form.setReadOnly("description", false); (Making it editable again)

setMandatory() takes two parameters: the field name (backend name, not the label!) and a boolean value (`true` or `false`). Setting it to `true` will mark the field with the familiar red asterisk and prevent form submission if it’s empty. Similarly, `setReadOnly()` makes a field non-editable, preventing users from changing its value.

Wait, how many ways to make a field mandatory or read-only? This is a classic interview question and a crucial point for real-world development! You actually have several tools in your arsenal:

  1. Dictionary Properties: The most fundamental way. You can set a field as mandatory or read-only directly in its dictionary definition. This applies globally to all forms using that field.
  2. Dictionary Overrides: If you need a field to behave differently on an extended table (e.g., ‘Incident’ vs. ‘Problem’), you can override its dictionary properties for that specific table.
  3. UI Policies: A declarative, no-code/low-code way to set field attributes (mandatory, read-only, visible) based on conditions. They’re often preferred for simpler logic.
  4. Data Policies: Enforce data integrity across all entry points (UI, imports, web services). If a field is mandatory by Data Policy, it’s mandatory regardless of how data enters the system.
  5. g_form.setMandatory() (Client Script): This is your programmatic, client-side approach. It’s ideal for complex, dynamic scenarios that require JavaScript logic, especially when conditions are intricate or involve real-time user input.

When to use g_form vs. UI Policy/Dictionary? Generally, if you can achieve the desired behavior with a UI Policy or Dictionary setting, that’s the preferred method. They are easier to maintain and troubleshoot. Reserve g_form for when you need to leverage JavaScript’s full power for very specific, dynamic, and often user-driven scenarios that UI Policies can’t handle with their conditions alone. For instance, if you need to calculate whether a field should be mandatory based on an onChange event involving multiple fields, `g_form.setMandatory()` in a Client Script is the way to go.

Troubleshooting Tip: If your `g_form.setReadOnly()` isn’t working, check for conflicting UI Policies or Dictionary Overrides. UI Policies usually override Dictionary settings, and Client Scripts (using `g_form`) often run last, potentially overriding UI Policy settings, depending on their order and execution timing.

Controlling Attachments: `enableAttachments()`

Sometimes, attachments are only relevant under certain conditions. This method lets you control whether users can add files to a record.

  • g_form.enableAttachments(); (Enables attachments)
  • g_form.enableAttachments(false); (Disables attachments)

By default, if the attachment functionality is available for a table, it’s enabled. You might use this in a scenario where, for example, a “Software Request” form only allows attachments once the “Request Type” is set to “Custom Software Development” because only then would supporting documents be relevant.

Populating Choices: `addOption()`

Dropdown fields (choice lists) are super useful, but sometimes you need to dynamically add options based on other selections. While `GlideAjax` and Script Includes are typically used for cascading choices from server-side data, `addOption` is for adding static options or building options client-side.

  • g_form.addOption("u_severity_impact", "high", "High Impact");
  • g_form.addOption("u_severity_impact", "medium", "Medium Impact");

The parameters are: field name, value (what’s stored in the database), and label (what the user sees). This is particularly useful in an `onChange` Client Script where, based on a previous selection, you might clear existing options and add new ones.

Beyond `addOption()`: For a complete dynamic choice list experience, you’ll often pair `addOption()` with `g_form.clearOptions(“field_name”)` to remove existing choices first, ensuring a clean slate before adding new ones.

Mastering Field Visibility and Layout

How your form looks and flows can significantly impact user efficiency. `g_form` provides granular control over not just a field’s state, but also its presence on the form.

The Great Debate: `setVisible()` vs. `setDisplay()`

This is a classic distinction and a frequent interview question!

  • g_form.setVisible("u_additional_details", false);
  • g_form.setDisplay("u_additional_details", false);

Both methods will hide a field from the form. However, their impact on the form’s layout is fundamentally different:

  • g_form.setVisible('u_assignment_group', false);: This will hide the field from the form, but the space that the field would normally occupy will not be removed. It will remain as an empty gap, potentially making your form look disjointed or poorly designed. Think of it like a magician making a car disappear, but the empty parking spot remains.
  • g_form.setDisplay('u_assignment_group', false);: This is generally the preferred method for truly hiding a field. It hides the field along with the space it occupies. The form layout will reflow, making it appear as if the field was never there. Using our magic analogy, it’s like the car disappeared, and the parking lot magically reconfigures itself as if there was never a spot there to begin with.

When to use which? Almost always, you’ll want to use `g_form.setDisplay()`. It creates a much cleaner and more professional user interface. `setVisible()` is rarely used for hiding fields, perhaps only in niche scenarios where maintaining the exact form layout (with empty spaces) is somehow critical, which is quite uncommon.

Troubleshooting: If you hide a field and notice an awkward empty gap on your form, your first thought should be: “Did I use `setVisible()` instead of `setDisplay()`?”

Controlling Sections and Related Lists

Beyond individual fields, `g_form` also empowers you to manage larger structural elements of your form: sections and related lists.

Dynamic Section Management

Forms can get long and overwhelming. Hiding irrelevant sections can significantly improve user experience, especially if they only become pertinent under specific conditions.

First, how do you even know what sections are on the form? Simple!

function onLoad() {
    // Get all section names
    var sections = g_form.getSectionNames();
    // You can console.log(sections) to see them in your browser's developer console
    // console.log("Sections on this form:", sections);
}

Once you have the section names, you can show or hide them dynamically:

How to hide all sections using script:

function onLoad() {
    // Get all section names
    var sections = g_form.getSectionNames();

    // Loop through each section and hide it
    for (var i = 0; i < sections.length; i++) {
        g_form.setSectionDisplay(sections[i], false);
    }
}

This script would run on form load, effectively making your form appear blank initially, which might be useful if you only want to reveal sections after certain data is entered or user roles are validated.

How to show all sections:

function onLoad() {
    var sections = g_form.getSectionNames();

    for (var i = 0; i < sections.length; i++) {
        g_form.setSectionDisplay(sections[i], true);
    }
}

This script is the counterpart, ensuring all sections are visible. You might use this after a form initially hides sections and then reveals them based on user interaction or data state.

Practical Scenario: On a “New Change Request” form, you might initially hide sections like “Planning,” “Implementation,” and “Post Implementation Review.” As the change progresses through its lifecycle (e.g., from “New” to “Assess” to “Implement”), you can use `g_form.setSectionDisplay()` within an `onChange` Client Script on the “State” field to progressively reveal relevant sections.

Hiding Related Lists

Related Lists can add a lot of context to a record, but sometimes they’re simply not needed, or they might even slow down form loading if there are many of them or they contain a huge amount of data. g_form offers a simple way to manage their visibility:

  • g_form.hideRelatedLists();

This single line of code, typically placed in an `onLoad` Client Script, will hide all related lists on the form. It’s great for simplifying the UI for specific user groups or for performance optimization on heavily loaded forms where related lists are secondary to the main record data.

Need to show them again? There’s also `g_form.showRelatedLists();`. And for more granular control, you can use `g_form.setRelatedList(‘list_name’, ‘visible_state’)` to target specific related lists by their table name.

Advanced `g_form` Techniques and Best Practices

Being proficient with `g_form` isn’t just about knowing the methods; it’s about using them effectively and efficiently. This includes understanding some more advanced patterns and adhering to crucial best practices.

Working with Editable Fields

Sometimes you need to iterate through all editable fields on a form and apply a rule. This is common when you want to “freeze” a form or ensure certain fields are not changeable once a record reaches a specific state.

function onLoad() {
    var fields = g_form.getEditableFields();

    for (var i = 0; i < fields.length; i++) {
        g_form.setReadOnly(fields[i], true);
    }
}

This script uses `g_form.getEditableFields()` to retrieve an array of all fields that are currently editable on the form. It then loops through them, setting each one to read-only. This is a powerful way to implement a “locked form” state, for instance, once an incident is closed or a change request is completed.

Client-Side Scripting Best Practices

Writing good code isn’t just about making it work; it’s about making it maintainable, performant, and future-proof. Here are some essential best practices for client-side scripting in ServiceNow:

  1. Enclose Code in Functions: Always wrap your Client Script logic within an appropriate function (e.g., `onLoad()`, `onChange(control, oldValue, newValue, isLoading, isTemplate)`, `onSubmit()`). This prevents global variable pollution and makes your code more modular and easier to debug.
  2. Avoid DOM Manipulation; Use `g_form` Object: This is paramount! Direct Document Object Model (DOM) manipulation (e.g., `document.getElementById()`, jQuery selectors like `$(#myfield)`) is highly discouraged. ServiceNow’s UI framework can change with upgrades, breaking your custom scripts. `g_form` provides an abstraction layer that ensures your scripts continue to work across upgrades. Stick to `g_form` methods whenever possible.
  3. Avoid Global Client Scripting: Don’t just dump code directly into a Client Script without a function wrapper. This can lead to conflicts, unexpected behavior, and makes troubleshooting a nightmare.
  4. Not Using `g_form.getReference()` without a Callback: The `g_form.getReference()` method, when called synchronously (without a callback), causes the UI to freeze while it fetches data from the server. This leads to a poor user experience. Always use `g_form.getReference()` with a callback function to ensure asynchronous execution, keeping the UI responsive.
    // BAD (Synchronous, UI freezes)
    var user = g_form.getReference('caller_id');
    alert(user.email);
    
    // GOOD (Asynchronous, UI remains responsive)
    g_form.getReference('caller_id', function(user) {
        g_form.addInfoMessage('Caller email: ' + user.email);
    });
  5. Not Using Too Many Alerts: As mentioned earlier, `alert()` boxes are disruptive. Use `g_form.addInfoMessage()` or `g_form.addErrorMessage()` for user feedback that is less intrusive.
  6. Using Asynchronous Calls in Client Side: Whenever your client-side script needs to fetch data from the server (e.g., querying another table, executing complex server-side logic), use `GlideAjax` for asynchronous communication. This ensures your form remains responsive and doesn’t freeze for the user.
  7. Comment Your Code: Clear, concise comments explaining your logic are invaluable for anyone (including your future self!) who needs to understand or modify the script later.

Adhering to these best practices isn’t just about being a “good developer”; it’s about building scalable, maintainable, and high-performance ServiceNow applications. Interviewers will often probe your understanding of these principles, so being able to articulate them is a huge plus.

Beyond the Form: Interacting with UI Actions

`gsftSubmit()` – Bridging Client and Server

Sometimes, a UI Action needs to do a little client-side validation or manipulation *before* it sends data to the server for processing. This is where `gsftSubmit()` comes into play, creating a powerful bridge between your client-side JavaScript and the server-side script within the same UI Action.

The syntax looks a bit cryptic at first, but it’s incredibly useful:

gsftSubmit(null, g_form.getFormElement(), "UI Action Id");

Let’s break it down:

  • null: This first parameter is typically null. It’s a legacy parameter from older versions.
  • g_form.getFormElement(): This crucial part ensures that the current form’s data is submitted. It essentially grabs the entire form object.
  • "UI Action Id": This is the magic string. It refers to the ‘Action name’ (often the ‘id’ field) of the UI Action itself.

How it works:
Imagine a “Submit for Approval” UI Action. You want to make sure all mandatory fields are filled out and perhaps some custom client-side validations pass before sending the record to a workflow. You can put your client-side validation logic in the “Client-side” script section of the UI Action. If all validations pass, you then call `gsftSubmit(null, g_form.getFormElement(), ‘your_ui_action_id’);`. This call triggers the *same* UI Action again, but this time, it bypasses the client-side script and goes directly to the “Server-side” script, allowing you to perform your database updates, workflow triggers, etc.

Practical Scenario: A “Close Incident” UI Action might have client-side code that checks if a “Closure Notes” field is populated and if a “Resolution Code” is selected. If these conditions are met, `gsftSubmit` is called to then run the server-side code that changes the incident state, calculates resolution time, and updates other fields.

Interview Relevance: This is an advanced technique often used in complex UI Actions. Knowing `gsftSubmit` demonstrates a deep understanding of how client and server scripts can cooperate within a single UI Action.

Wait, `g_form` for Creating Records? (A Small Detour and Clarification)

You might have encountered questions like “How to create a record using script?” and seen examples that seem to imply client-side creation. Let’s clarify a crucial point based on the reference content:

// Example from reference content 212:
//Create a new Incident record and populate the fields with the values below

// Inserts are performed in the same way as queries except you need to replace the ‘query()’ line with an ‘initialize()’ line as shown here.
var gr = new GlideRecord('incident');
gr.initialize();
gr.short_description = 'Network problem';
gr.category = 'software';
gr.caller_id.setDisplayValue('Joe Employee');
gr.insert();

This script snippet is indeed how you create a record in ServiceNow using a script. However, it’s absolutely vital to understand that this is a server-side script, not a client-side one that runs directly in the browser via `g_form`!

Why the confusion? While this `GlideRecord` API is used for creating, reading, updating, and deleting (CRUD) records, `g_form` operates exclusively on the client-side, interacting with the *current* form’s presentation. `g_form` itself cannot directly perform database operations like creating new records. That requires server-side execution.

So, how *do* you create a record from the client-side?

You trigger a server-side action from your client-side script. The most common and recommended ways are:

  1. Using `GlideAjax`: Your client script makes an asynchronous call to a Script Include. The Script Include, running on the server, then uses `GlideRecord` (like the example above) to create the new record. This is the best practice for client-to-server communication where you need to fetch or send data dynamically.
  2. Using `gsftSubmit()` with a UI Action: As discussed, you can use `gsftSubmit()` to submit the form and trigger a UI Action’s server-side code. This server-side code can then use `GlideRecord` to create a new record (e.g., “Create Related Problem” UI Action on an Incident).
  3. Submitting the current form: If you are on a new record form and the user clicks “Submit”, the platform’s default processing will handle the `GlideRecord.insert()` on the server-side to create the record from the data in `g_form`.

Therefore, while the `GlideRecord` example is valid for record creation, it exists in a server-side context. When you’re working with `g_form` on the client-side, remember its scope is primarily about manipulating the form itself, not directly interacting with the database. Bridging that gap requires calling upon server-side resources.

Troubleshooting Common `g_form` Issues

Even with the best practices, things can sometimes go awry. Here are a few common `g_form` pitfalls and how to troubleshoot them:

  • Script Not Running:
    • Is the Client Script / UI Policy active?
    • Is the Client Script attached to the correct table?
    • Is the “UI Type” (Desktop, Mobile, All) set correctly?
    • Is the `onLoad`, `onChange`, or `onSubmit` function misspelled or incorrect?
    • Check the browser’s developer console for JavaScript errors.
  • Field State Conflicts: If `setMandatory()` or `setReadOnly()` isn’t working as expected, remember the hierarchy: Data Policies > Dictionary > UI Policies > Client Scripts. Check for conflicting rules. Sometimes, a UI Policy might run after your Client Script, overriding its effect.
  • `setVisible()` vs. `setDisplay()`: As discussed, if you see an empty gap where a field should have disappeared, you likely used `setVisible()` when `setDisplay()` was needed.
  • `g_form.getReference()` Freezing UI: If your form lags or freezes when fetching reference data, you’re probably using `getReference()` synchronously. Rewrite it to use the asynchronous callback pattern.
  • Direct DOM Manipulation Errors: If your script suddenly breaks after a ServiceNow upgrade, and it involves `document.getElementById` or jQuery, it’s almost certainly due to direct DOM manipulation that ServiceNow’s UI changes broke. Refactor using `g_form` methods.
  • Caching Issues: Sometimes, browser caching can prevent your latest script changes from loading. Clear your browser cache and cookies, or try an incognito/private browsing window.
  • Typos in Field Names: Always double-check field names; they are case-sensitive and must match the backend name exactly (e.g., `u_my_custom_field`, not `My Custom Field`).

Conclusion

The `g_form` API is truly the cornerstone of client-side development in ServiceNow. It empowers developers to craft dynamic, responsive, and intuitive forms that significantly enhance the user experience. From displaying messages and controlling field states to managing entire sections and orchestrating interactions with server-side logic, `g_form` provides a comprehensive toolkit.

Mastering `g_form` isn’t just about memorizing methods; it’s about understanding its client-side context, knowing when to apply different techniques (UI Policy vs. Client Script), and adhering to best practices that ensure your solutions are robust, performant, and maintainable. By embracing these principles, you’ll be well-equipped to tackle almost any form-related challenge ServiceNow throws your way, making you an invaluable asset in any development team.

So go forth, experiment, and make those forms dance! The `g_form` object is waiting for you to unleash its full potential.

Scroll to Top