SUBHAM_SHAW_SN
Tera Guru
Tera Guru

ServiceNow provides a powerful filtering framework known as sn-filter-widget, commonly used in list views. Many developers want the same filtering experience inside Service Portal instead of building a custom filtering UI. However, Service Portal does not load the filtering engine automatically. To use it, the widget must explicitly enable the snFilter dependency.

This article explains what the snFilter dependency is, why it is required, how to configure it, and how to correctly implement sn-filter-widget in a Service Portal widget, along with a complete working example.


What Is the snFilter Dependency?

snFilter is an Angular dependency provided by ServiceNow that loads the filter engine required for sn-filter-widget.
Without enabling this dependency:

  • The filter UI will not render

  • The widget may appear blank

  • Console errors may appear

  • Events such as snfilter:update_query will not be available


Why Service Portal Requires Dependencies

Service Portal widgets operate in a controlled Angular environment. They do not automatically include every ServiceNow script library. Dependencies must be explicitly added so widgets know which Angular modules to load.

The snFilter dependency:

  • Registers the sn-filter directive

  • Loads internal filter JavaScript logic

  • Enables condition builder UI

  • Provides filter events

This makes it mandatory when using sn-filter-widget.


Adding the snFilter Dependency

Open your widget and navigate to:

Widget → Dependencies → Add:

snFilter

Save the widget.
Once added, Service Portal will be able to render and handle the filter widget correctly.


Rendering sn-filter-widget in Service Portal

After enabling the dependency, the filter widget can be placed inside the widget template:

<sn-filter-widget
  uid="c.data.table"
  table="{{c.data.table}}"
  table-label="c.data.table"
  filter-config="c.config">
</sn-filter-widget>

Parameters:

  • table: defines which table the filter should reference.

  • uid: unique identifier (typically table name).

  • filter-config: controls behavior such as output format.


Configuring sn-filter-widget

A configuration object controls how the filter behaves. Define it in the client controller.

c.config = {
  outputType: "encoded_query",
  closeFilter: false,
  saveFilter: false,
  loadFilter: false,
  sortFilter:false,
  watchConfig:true,
  testFilter:true,
  encodedQuery: ""
};

Important behaviors:

  • outputType: "encoded_query" ensures filter generates encoded queries.

  • Save/Load options are disabled because Service Portal does not typically store filters.

  • watchConfig allows dynamic refresh.


Working with Filter Events

Once the dependency is enabled, the widget can communicate with the filter using platform events.


Capturing Encoded Query

Whenever the filter updates, ServiceNow fires:

snfilter:update_query

Example:

$scope.$on("snfilter:update_query", function(e, query){
  if(query){
    $scope.selectedQuery = query;
  }
});

Use cases:

  • Running GlideRecord queries

  • Passing query to backend

  • Debugging and validation


Detecting Clear Filter Action

When a user clears the filter:

snfilter:clear_filter

Use it to reset UI and values:

$scope.$on("snfilter:clear_filter", function() {
  $scope.selectedQuery = "";
});

Dynamically Updating Table

If table selection changes dynamically, notify the filter:

$scope.$broadcast("snfilter:update_table", {table: tableName});

The filter automatically refreshes its fields.


Complete Working Example

The following widget demonstrates correct dependency usage, rendering, and event handling.


Client Script

api.controller = function($scope, $timeout) {
  var c = this;

  $scope.selectedTableName = "";
  $scope.selectedTableLabel = "";
  $scope.selectedQuery = "";
  $scope.showResult = false;

  c.data.initialQuery = "";

  c.config = {
    outputType: "encoded_query",
    closeFilter: false,
    saveFilter: false,
    loadFilter: false,
    sortFilter:false,
    watchConfig:true,
    testFilter:true,
    encodedQuery: ""
  };

  // When table changes
  $scope.$on("field.change", function(evt, data){
    var table = data.field.value;

    if(!table){
      c.data.table = "";
      $scope.showResult = false;
      return;
    }

    c.data.table = table;
    $scope.selectedTableName = table;
    $scope.selectedTableLabel = data.field.displayValue || table;

    $scope.$broadcast("snfilter:update_table",{table:table});
  });

  // Capture query
  $scope.$on("snfilter:update_query", function(e, query){
    if(query){
      $scope.selectedQuery = query;
    }
  });

  // Show output
  $scope.showOutput = function(){
    $scope.showResult = true;
  };

  // Handle clear filter
  $scope.$on("snfilter:clear_filter", function() {
    $timeout(function(){
      $scope.showResult = false;
      $scope.selectedQuery = "";
    });
  });

};

HTML

<div class="panel panel-default p-3">

  <h3>Using sn-filter-widget in Service Portal</h3>

  <div class="form-group">
    <label>Select Table</label>

    <sn-record-picker field="c.table"
                      table="'sys_db_object'"
                      display-field="'label'"
                      display-fields="'label,name'"
                      value-field="'name'"
                      search-fields="'label,name'"
                      page-size="100">
    </sn-record-picker>
  </div>

  <div ng-if="c.data.table">
    <sn-filter-widget
      uid="c.data.table"
      table="{{c.data.table}}"
      table-label="c.data.table"
      filter-config="c.config">
    </sn-filter-widget>
  </div>

  <br>

  <button class="btn btn-primary"
          ng-disabled="!selectedQuery"
          ng-click="showOutput()">
    Show Output
  </button>

  <br><br>

  <div class="well" ng-if="showResult">
    <h4>Filter Output</h4>
    <p><b>Table Label:</b> {{selectedTableLabel}}</p>
    <p><b>Table Name:</b> {{selectedTableName}}</p>
    <p><b>Encoded Query:</b> {{selectedQuery}}</p>
  </div>

</div>

CSS

.panel {
  border-radius: 6px;
  border: 1px solid #d1d8e0;
  padding: 20px;
  background: #ffffff;
}

h3 {
  font-size: 20px;
  font-weight: 600;
  color: #003087;
  margin-bottom: 15px;
}

.sn-filter {
  border: 1px solid #ddd;
  padding: 10px;
  background: #fafafa;
}

image (24).png

Summary

The snFilter dependency is mandatory when using sn-filter-widget in Service Portal.
It loads the filter engine, enables condition builder functionality, and unlocks filter events.

Once enabled, you can:

  • Render filters dynamically

  • Capture encoded queries

  • Detect when filters are cleared

  • Update tables on the fly

This approach is platform-aligned, upgrade-safe, and significantly reduces development effort compared to building a custom filtering framework.

 

Thanks & Regards,

Subham Kumar Shaw

ServiceNow Architect/Consultant
ServiceNow Community Rising Star ' 2022/2023/2024/2025

Version history
Last update:
2 hours ago
Updated by:
Contributors