Glide Navigation API Tutorial: Seamlessly Navigate Your Android Apps






Mastering ServiceNow Navigation: A Comprehensive GlideNavigation API Tutorial


Mastering ServiceNow Navigation: A Comprehensive GlideNavigation API Tutorial

Welcome, fellow ServiceNow enthusiasts! If you’ve been navigating the world of ServiceNow development, you’ve undoubtedly encountered the need to programmatically control user navigation. Whether you’re building custom applications, streamlining workflows, or enhancing user experience, understanding how to direct users to the right place at the right time is crucial. In this in-depth guide, we’ll dive deep into the GlideNavigation API, a powerful tool that allows you to achieve just that. We’ll cover its core functionalities, practical applications, and provide insights relevant to your daily development and even those tricky interview questions.

This tutorial is built with the latest ServiceNow versions in mind, specifically targeting the Washington DC release, and drawing from experience gained across several previous versions including Rome, San Diego, Tokyo, Utah, and Vancouver. This ensures the information is current and practical.

Understanding GlideNavigation API: The Navigator’s Toolkit

At its heart, the GlideNavigation API is a server-side API designed to manipulate the user’s navigation experience within the ServiceNow platform. Think of it as your digital GPS for guiding users to specific records, lists, pages, or even external URLs. It’s a fundamental part of creating dynamic and responsive user interfaces.

Core Functions and Their Applications

The GlideNavigation API offers a suite of methods, each serving a distinct purpose. Let’s explore some of the most commonly used ones:

1. `navto()` – The Workhorse of Navigation

This is perhaps the most versatile method. `navto()` allows you to redirect the user to a specified destination. The destination can be defined in various ways:

  • A specific record: Navigate directly to a form view of a particular record.
  • A list of records: Take the user to a list view, optionally with filters applied.
  • A UI page: Redirect to a custom UI page you’ve built.
  • An external URL: Send the user to an external website.

Syntax: `GlideNavigation.navto(target);`

Example 1: Navigating to a specific incident record

    var incidentSysId = 'your_incident_sys_id_here'; // Replace with the actual sys_id
    GlideNavigation.navto('incident.do?sys_id=' + incidentSysId);
    

In this example, we’re constructing a URL to directly open the incident form with the specified `sys_id`. This is incredibly useful after creating or updating a record to immediately show the user the result.

Example 2: Navigating to a filtered list of active incidents

    GlideNavigation.navto('incident_list.do?sysparm_query=active=true^priority=1');
    

Here, we’re directing the user to the incident list (`incident_list.do`) and applying a query to show only active incidents with a priority of 1 (critical). This is a great way to guide users to relevant data quickly.

Example 3: Navigating to a custom UI page

    GlideNavigation.navto('my_custom_ui_page.do');
    

If you have a custom UI page named `my_custom_ui_page.do`, this will smoothly transition the user to it.

2. `redirect()` – Similar to `navto()`, but with Nuances

While `navto()` is generally preferred for its flexibility, `redirect()` also exists. It’s often used in contexts where a simple redirection is needed. However, `navto()` is more powerful for constructing complex navigation targets.

Example:

    var userSysId = gs.getUserID();
    GlideNavigation.redirect('sys_user.do?sys_id=' + userSysId);
    

This would redirect the user to their own user record. In most modern development, you’ll find yourself using `navto()` more frequently.

3. `openPopup()` – For Focused User Interactions

Sometimes, you don’t want to take the user away from their current context. This is where `openPopup()` shines. It displays a specified URL in a modal pop-up window.

Syntax: `GlideNavigation.openPopup(target, width, height);`

Example: Opening a task form in a popup

    var taskSysId = 'your_task_sys_id_here';
    GlideNavigation.openPopup('sc_task.do?sys_id=' + taskSysId, 800, 600); // Width 800px, Height 600px
    

This is incredibly useful for allowing users to quickly view or edit related records without losing their current work. For instance, when working on an incident, you might want to open associated incident tasks in a popup.

4. `setLocation()` – A Client-Side Companion

While GlideNavigation is primarily server-side, it’s important to mention its client-side counterpart: `g_navigation.setLocation()`. This method is used within client scripts (like onSubmit, onLoad, onChange) to change the browser’s location.

Syntax: `g_navigation.setLocation(url);`

Example: Redirecting after form submission in a client script

    // In an onSubmit client script on the 'incident' table
    function onSubmit() {
        if (g_form.isNewRecord()) {
            // After saving a new incident, redirect to a custom page
            g_navigation.setLocation('my_custom_confirmation_page.do');
            return false; // Prevent default form submission if redirecting
        }
        return true;
    }
    

This client-side method is essential for immediate feedback or guiding users after an action they’ve just performed on the form.

Permissions, Users, and Groups: The Foundation of Access Control

Before we delve deeper into navigation, it’s crucial to touch upon how permissions are managed in ServiceNow, as navigation often depends on a user’s access rights. Based on our reference:

User and Group Management

  • User Table: `sys_user`
  • Group Table: `sys_user_group`
  • Group Membership Table: `sys_user_grmember`

Adding Permissions (Roles)

Permissions are managed through roles. You can add roles to users or groups.

  • To a User: Records are created in the `sys_user_has_role` table.
  • To a Group: Records are created in the `sys_group_has_role` table.

Best Practice for Permissions: As the reference rightly points out, assigning roles to groups is the best practice. This simplifies user management. When an employee leaves or changes roles, you simply remove them from the relevant group(s), and their permissions are automatically revoked. This is far more efficient and less error-prone than managing roles individually for each user.

Scripting User/Group Creation and Role Assignment:

    // Creating a user
    var userGr = new GlideRecord('sys_user');
    userGr.initialize();
    userGr.username = 'jdoe';
    userGr.firstname = 'John';
    userGr.lastName = 'Doe';
    userGr.email = 'jdoe@example.com';
    userGr.insert();

    // Creating a group
    var newGr = new GlideRecord('sys_user_group');
    newGr.initialize();
    newGr.name = 'IT Support Team';
    // Assuming 'manager_sys_id' is the sys_id of the manager user
    newGr.manager = 'manager_sys_id';
    newGr.email = 'itsupport@example.com';
    newGr.description = 'Handles all IT-related incidents and requests.';
    newGr.insert();

    // Adding a role to a user
    var userRole = new GlideRecord('sys_user_has_role');
    userRole.setValue('user', userGr.sys_id); // Using the sys_id of the created user
    // Assuming 'admin_role_sys_id' is the sys_id of the 'admin' role
    userRole.setValue('role', 'admin_role_sys_id');
    userRole.insert();

    // Adding a role to a group
    var grpRole = new GlideRecord('sys_group_has_role');
    grpRole.setValue('group', newGr.sys_id); // Using the sys_id of the created group
    // Assuming 'itil_role_sys_id' is the sys_id of the 'itil' role
    grpRole.setValue('role', 'itil_role_sys_id');
    grpRole.insert();

    // Adding a user to a group
    var grMem = new GlideRecord('sys_user_grmember');
    grMem.user = userGr.sys_id; // Use the sys_id of the user
    grMem.group = newGr.sys_id; // Use the sys_id of the group
    grMem.insert();

    // Removing a user from a group
    var grMemToRemove = new GlideRecord('sys_user_grmember');
    grMemToRemove.addQuery('user', userGr.sys_id);
    grMemToRemove.addQuery('group', newGr.sys_id);
    grMemToRemove.query();
    if (grMemToRemove.next()) {
        grMemToRemove.deleteRecord();
    }
    

User Delegation: Enabling Collaboration

User delegation is a powerful feature allowing one user to perform actions on behalf of another. This is particularly useful when a user is on leave or unavailable. The delegated user gains access to perform tasks, receive notifications, and even handle approvals for the original user.

How it works: The original user configures delegation settings on their profile, specifying who can act on their behalf, the duration, and the types of permissions granted (assignments, notifications, approvals).

Beyond Basic Navigation: Contextual Actions and UI Policies

GlideNavigation isn’t used in a vacuum. It often works in conjunction with other ServiceNow features to provide a seamless user experience.

UI Policies and Client Scripts: Triggering Navigation

You’ll frequently use GlideNavigation within UI Policies or Client Scripts to automate navigation based on specific conditions.

  • UI Policies: While UI Policies are primarily for manipulating form elements (mandatory, read-only, visibility), they can trigger Client Scripts, which in turn can use GlideNavigation. The “Run scripts” option in UI Policy Actions is your gateway here.
  • Client Scripts:
    • `onLoad`: Useful for setting initial navigation based on form load conditions.
    • `onChange`: Great for redirecting when a field’s value changes.
    • `onSubmit`: Ideal for guiding users after a record is saved.

Example: Redirecting to a different form after closing an incident

    // In an onSubmit client script on the 'incident' table
    function onSubmit() {
        if (g_form.getValue('state') == '7' && g_form.isChanged('state')) { // If state is changed to Closed
            // Let's say we want to navigate to a custom 'Incident Resolved' page
            g_navigation.setLocation('incident_resolved_view.do?sys_id=' + g_form.getUniqueValue());
            return false; // Prevent default behavior if redirecting
        }
        return true;
    }
    

Data Policies: Server-Side Navigation Control

Data Policies, unlike UI Policies, operate on the server-side (and can also affect the client). While they don’t directly execute `GlideNavigation`, they can enforce conditions that might lead to a developer implementing server-side navigation using `GlideNavigation.navto()` in a Business Rule triggered by the data policy’s actions.

Navigating Between Core Records: Incident, Problem, Change

The relationships between Incident, Problem, and Change Management are fundamental to IT Service Management (ITSM). GlideNavigation plays a role in linking these processes.

The ITSM Lifecycle

Incident: A sudden interruption of service. When something breaks, an incident is created.

Problem: If the same issue occurs repeatedly, it’s a problem. A problem record aims to find the root cause.

Change Request: If modifications are needed to fix a problem or implement an enhancement, a change request is created.

Scripting Record Creation and Navigation

You’ll often create one type of record from another and then navigate the user to the newly created record.

    // Example: Creating an Incident and navigating to it
    var grIncident = new GlideRecord('incident');
    grIncident.initialize();
    grIncident.caller_id = gs.getUserID(); // Set caller to current user
    grIncident.short_description = 'User reporting slow system performance';
    grIncident.description = 'The system is experiencing significant slowdowns, impacting productivity.';
    grIncident.assignment_group = 'your_assignment_group_sys_id'; // Example assignment group
    var newIncidentSysId = grIncident.insert();

    if (newIncidentSysId) {
        // Navigate to the newly created incident
        GlideNavigation.navto('incident.do?sys_id=' + newIncidentSysId);
        gs.addInfoMessage('Incident created successfully: ' + grIncident.number);
    } else {
        gs.addErrorMessage('Failed to create incident.');
    }

    // Example: Creating a Problem from an Incident (typical in a Business Rule)
    // Assuming 'current' is the incident record being processed
    var grProblem = new GlideRecord('problem');
    grProblem.initialize();
    grProblem.caller_id = current.caller_id;
    grProblem.short_description = 'Recurring issue: ' + current.short_description;
    grProblem.description = 'Root cause analysis needed for repeated incidents related to: ' + current.short_description;
    grProblem.work_notes = 'Created from incident ' + current.number;
    grProblem.insert();

    // Update the incident to link it to the problem
    current.problem_id = grProblem.sys_id;
    current.update();

    // Optionally, navigate to the new problem record
    // GlideNavigation.navto('problem.do?sys_id=' + grProblem.sys_id);
    

Business Rule Logic for Related Records

You’ll often find GlideNavigation usage in Business Rules, especially ‘after’ insert/update rules:

  • Closing Parent Incident: As per the provided Q&A (Q26), an ‘after update’ Business Rule can be written to close child incidents when a parent incident is closed. While it doesn’t directly use `navto`, it demonstrates controlling related record states.
  • Closing Related Incidents from Problem: Similarly (Q28), when a problem is closed, associated incidents can be updated.
  • Preventing Closure with Open Tasks: (Q27) An ‘before update’ Business Rule is perfect for checking open incident tasks before allowing an incident closure. If tasks are open, an error message is shown, and `current.setAbortAction(true)` prevents the closure. This logic is crucial for maintaining data integrity.

Essential Field Types and Dictionary Concepts

Understanding field types and their configurations is key to effective navigation and form design.

Common Field Types

  • Reference: Links to another record (e.g., User, Assignment Group).
  • String: Text field.
  • List: Allows selection of multiple records from a referenced table.
  • Choice: Dropdown with predefined options.
  • Email: For email addresses.
  • Date/Time: For date and time values.
  • Date: For date values only.
  • Boolean: True/False.
  • Integer: Whole numbers.
  • Journal: For comments and work notes.
  • Attachment: For file uploads.

Attributes: Modifying Field Behavior

Attributes are powerful modifiers applied at the field’s dictionary entry level. They alter how a field behaves on the form.

  • `no_email`: Prevents email notifications for changes to this field.
  • `no_attachment`: Disables attachments for this field (useful on tables where attachments aren’t needed).
  • `tree_picker`: Displays a hierarchical tree view for selection in reference fields.

Enabling/Disabling Attachments: To disable attachments on a form, you can add the `no_attachment` attribute to the ‘attachment’ field in the dictionary entry of the table. For example, on the `incident` table, you’d find the dictionary entry for the `sys_attachment` field and add `no_attachment` to its attributes.

Dictionary Overrides

When a table extends another (e.g., `incident` extends `task`), fields from the parent table can have their properties modified in the child table using Dictionary Overrides. This is essential for tailoring fields like `priority` or `state` to the specific needs of a table.

Dependent Values

This feature creates cascading dropdowns. For instance, selecting a ‘Category’ (parent) dynamically filters the available ‘Subcategory’ (dependent) options. This significantly improves user experience by presenting only relevant choices.

Calculated Fields

When a field’s value needs to be computed based on other fields, you can use a calculated field. The calculation is defined in the dictionary entry, often using the `current` object.

    // Example: A 'Full Name' field calculated from 'First Name' and 'Last Name'
    // In the dictionary entry for 'Full Name':
    // Type: Calculated
    // Script: current.first_name + ' ' + current.last_name;
    

Controlling Field Behavior: UI Policies vs. Data Policies

Both UI Policies and Data Policies are used to enforce business rules and control field behavior, but they operate at different levels:

UI Policies

  • Client-side: Primarily impact the user interface in real-time.
  • Actions: Make fields mandatory, read-only, visible/hidden, set default values, execute client scripts.
  • Global checkbox: If checked, applies to all views; otherwise, specific views can be targeted.
  • Reverse if false: Reverts changes when the condition becomes false.
  • On Load: Scripts execute when the form loads.
  • Inherit: UI Policies can be inherited by child tables.
  • Scripting: Can be enabled via the “Run scripts” checkbox in UI Policy Actions.

Data Policies

  • Client & Server-side: Enforce data integrity regardless of how the data is entered (form, import, API).
  • Actions: Similar to UI Policies (mandatory, read-only, visible/hidden, set default values).
  • Works universally: More robust for ensuring data consistency.

Conversion and Limitations

You can convert UI Policies to Data Policies (and vice versa, with limitations). However, Data Policies cannot replicate UI Policies that control:

  • Data visibility (client-side hiding/showing based on UI context).
  • View control.
  • Related list visibility.
  • Client-side scripting execution specific to UI interactions.

Troubleshooting Common Navigation Issues

Even with powerful APIs, things can go wrong. Here are some common pitfalls and how to address them:

Troubleshooting Navigation Problems

  • Incorrect Sys_ID: Always double-check that you’re using the correct `sys_id` for records when constructing navigation URLs. Use `gs.log()` or `gs.addInfoMessage()` to print the `sys_id` you’re trying to use.
  • Permissions Denied: If a user can’t navigate to a record or page, it’s likely a permission issue. Ensure the user has the necessary roles. Remember the best practice of assigning roles to groups! Check the `sys_user_has_role` and `sys_group_has_role` tables.
  • Script Errors: Syntax errors in your GlideNavigation scripts (especially in Business Rules or Client Scripts) will prevent navigation. Review your code for typos, incorrect method calls, or missing semicolons.
  • UI Policy/Data Policy Conflicts: Sometimes UI Policies and Data Policies can conflict, leading to unexpected behavior. Temporarily disable them to isolate the issue.
  • Caching Issues: In rare cases, browser or server-side caching might cause issues. Try clearing your browser cache or performing an `impersonation` as the affected user.
  • External URL Failures: If navigating to an external URL, ensure the URL is correct and that ServiceNow’s outbound security rules allow access.

Interview Relevance

Understanding the GlideNavigation API and related concepts is crucial for ServiceNow developer interviews. Here’s why:

Key Interview Takeaways

  • GlideNavigation API: Be prepared to explain `navto()`, `openPopup()`, and their use cases.
  • Client vs. Server-Side: Differentiate between `GlideNavigation` (server) and `g_navigation` (client).
  • Business Rules & Client Scripts: Know how to trigger navigation from these scripts.
  • Permissions & Best Practices: Discuss user/group management and the importance of group-based role assignment.
  • ITSM Relationships: Explain the flow between Incident, Problem, and Change, and how navigation facilitates this.
  • UI Policies vs. Data Policies: Understand their differences, use cases, and conversion.
  • Field Types & Attributes: Be familiar with common field types and how attributes modify behavior.
  • `current` Object: Understand its role in server-side scripting for setting field values and calculations.

Conclusion

The GlideNavigation API is an indispensable tool in the ServiceNow developer’s arsenal. By mastering its capabilities, you can create intuitive user journeys, streamline complex workflows, and build truly dynamic applications. Remember to always consider the user’s context, permissions, and the overall flow of your application. Practice implementing these techniques in your development instances, and you’ll soon find yourself navigating the platform with newfound confidence and efficiency. Happy coding!


Scroll to Top