Adding search functionality on the My Tasks page

Likitha Patel
Tera Expert

Adding search functionality to the HRM Todos Summary widget on the My Tasks page

 

Overview

This functionality provides a search bar for dynamic filtering of records on the "MY Tasks" page. Users can search by entering the number or short description of a record in the search.

 

Step 1: Clone the "HRM Todos Summary" widget. Add the following code to the HTML body template:

 

 

<!-- Search Bar and Button -->
<div class="search-bar">
<input 
        type="text" 
        ng-model="c.searchQuery" 
        placeholder="Search {{tab.name}} Approvals" 
        class="form-control" 
        ng-keypress="c.handleKeyPress($event, tab.name)" 
    />
<button 
        class="btn btn-default align-icon" 
        type="button" 
        ng-click="c.fetchSearchedRecords(tab.name, c.searchQuery)" 
        data-toggle="tooltip" 
        data-placement="bottom"
>
<i class="fa fa-search"></i>
</button>
</div>

 

 

Step 2: Add the following code in CSS to ensure that the search bar looks visually appealing and is aligned properly with the button.

 

.search-bar {
  display: flex;
  align-items: center;
}

.search-bar .form-control {
  flex: 1;
  margin-right: 0; /* Ensure no margin between input and button */
  border-right: 2px solid #ccc; /* Adds a line between input and button */
  height: 40px; /* Ensure the height is the same as the button */
}

.search-bar .btn {
  padding: 5px 10px; /* Adjust padding for consistent sizing */
  height: 40px; /* Set the button height to match the input */
  display: flex;
  align-items: center; /* Center the icon vertically */
  justify-content: center; /* Center the icon horizontally */
}

 

 

Step 3: Add the following code to the server-side script to fetch the records from the server with a limit set to 1000 to retrieve all records.

 

// Set query limit to fetch all records (adjust if the utility method has specific handling)
    var todoUtils = new todoPageUtils();

    // Define parameters
    var limit = 1000; // Set to 0 or a high number to fetch all records
    var excludeList = []; // No exclusions
    var includeSysId = undefined; // No specific sys_id to include
    var filters = undefined; // No filters
    var params = undefined; // No additional parameters
    var todoPageFilterConditions = undefined; // No specific filter conditions
    var applyFilter = false; // Do not apply filters
    var tab = data.tabname; // Specify the tab you want to fetch records from

    // Fetch the todos
    var todos = todoUtils.getMyTodos(limit, excludeList, includeSysId, filters, params, todoPageFilterConditions, applyFilter, tab);

    // Pass the todos to the client-side via data object
    data.todos = todos;

 

 

Step 4: Add the following code to the client-side script to handle the search functionality and dynamically filter the records based on the user's input.

 

c.todos = $scope.data.todos; // This will contain the todos fetched from the server
    c.originalTodos = c.todos;
    c.handleKeyPress = function(event, tabName) {
        if (event.keyCode === 13 || event.which === 13) { // Check if Enter key is pressed
            c.fetchSearchedRecords(tabName, c.searchQuery); // Trigger the search function
		}
    };

    c.searchQuery = ''; // Initialize the search query
    c.todosToShow = {}; // This will hold the original todos
    c.todoDisplayed = {}; // This will hold the displayed todos

    // Function to fetch and filter todos based on the search query
    c.fetchSearchedRecords = function(tabName, searchQuery) 
	{
		c.tabname = tabName;
        // Check if there is a search query
        if (searchQuery == '') {
           if (c.todosToShow[tabName]) 
		   {
            c.todoDisplayed[tabName] = angular.copy(c.todosToShow[tabName]);
		   }
        }
        var filteredTodos = [];

        // Store the original todos if not already stored
        if (!c.todosToShow[tabName]) {
            c.todosToShow[tabName] = angular.copy(c.originalTodos.recordsToShow[tabName]); // Keep a copy of the original todos
        }

        // Get the todos to search from the stored original list
        var todosToSearch = c.todosToShow[tabName];

        // Check if there are todos to search
        if (todosToSearch && todosToSearch.length > 0) {
            // Convert the search query to lowercase for case-insensitive comparison
            var searchQueryLower = searchQuery.toLowerCase();

            // Filter the todos based on the search query
            filteredTodos = todosToSearch.filter(function(todo) {
                // Check if the todo's display values contain the search query
                return todo.displayValueList && todo.displayValueList.some(function(value) {
                    return String(value).toLowerCase().includes(searchQueryLower);
                });
            });
        }

        // Update the displayed todos with the filtered results
        c.todoDisplayed[tabName] = filteredTodos;

        // Trigger UI update
        $scope.$applyAsync();
    };

 

 

Key Features:

  • Dynamic Filtering: Users can filter tasks in real time without refreshing the page.
  • Restoration of Original Data: The full list of records is restored when the search query is cleared.
  • Case-Insensitive Search: The search is case-insensitive, making it user-friendly regardless of capitalization.

Output:

 

LikithaPatel_0-1736258577287.png

 

Happy Learning,
Likitha Thangala

 

5 REPLIES 5

Hi @Vasilis Anastas ,

You can copy the entire code from the link CopyOfHRMTodosSummary and paste it into your widget. The file includes all the necessary sections—HTML, CSS, Client Script, and Server Script—each marked with appropriate headings. Simply place each section into the corresponding part of your widget configuration in ServiceNow. Once added, the widget should work as intended. 
If my response helped, please mark it correct.

 

Happy Learning,
Likitha Patel