Alka_Chaudhary
Mega Sage
Mega Sage

Introduction

Creating dynamic and user-friendly interfaces is crucial for any platform, including ServiceNow. In this blog, we’ll explore how to build a custom feature that:

  • Allows users to select multiple values through an input-like select box with a dropdown.

  • Closes the dropdown when clicking outside of it.

  • Displays selected values and dynamically updates available options.

This feature is perfect for creating intuitive selection interfaces in ServiceNow’s Service Portal.

 

Features of the Multi-Select Input

  1. Dynamic Multi-Select Input: Allows users to select multiple values without duplicates.

  2. Dropdown Filtering: Filters out already selected options to simplify selection.

  3. Save Functionality: Displays the selected values using an alert modal.

  4. Dropdown Closes on Outside Click: Automatically hides the dropdown when clicking outside of it.

Step-by-Step Implementation

Client Script

The client script manages the feature’s behavior, including dropdown visibility, selected values, and event handling.

 

 

 

api.controller=function($scope,spModal) {
	/* widget controller */
	var c = this;
	// Initialize options
	c.options = ["Toyota Corolla", "Honda Civic", "Ford Mustang", "Chevrolet Camaro", "Tesla Model 3"];

	// Placeholder for selected values
	c.selectedTags = [];
	c.showDropdown = false;

	// Add tag
	c.addTag = function (tag) {
		if (tag && !c.selectedTags.includes(tag)) {
			c.selectedTags.push(tag);
		}
		c.showDropdown = false; // Hide dropdown after selection
	};

	// Remove tag
	c.removeTag = function (tag) {
		var index = c.selectedTags.indexOf(tag);
		if (index > -1) {
			c.selectedTags.splice(index, 1);
		}
	};

	// Filter options to exclude already selected tags
	c.filteredOptions = function () {
		return c.options.filter(function (option) {
			return !c.selectedTags.includes(option);
		});
	};

	// Save function
	c.save = function () {
		spModal.alert('Total select Item : '+ c.selectedTags.length + '<br> Selected Items : ' + JSON.stringify(c.selectedTags));			
	};

	// Close dropdown on document click
	function closeDropdown(event) {
		if (!event.target.closest('.dropdown')) {
			c.showDropdown = false;
			$scope.$apply(); // Ensure Angular updates the UI
		}
	}

	// Attach document click listener
	angular.element(document).on('click', closeDropdown);

	// Cleanup listener on scope destroy
	$scope.$on('$destroy', function () {
		angular.element(document).off('click', closeDropdown);
	});

};

 

 

 

 

HTML Structure

The HTML provides the structure for the input field, dropdown, and buttons.

 

 

 

<div class="container">
  <h3>Multi-Select Input / List Collector</h3>
  <form ng-submit="c.save()">
    <div class="form-group">
      <label for="multiInput">Select Cars</label>
      <div class="tag-container">
        <!-- Display selected tags -->
        <span class="tag" ng-repeat="tag in c.selectedTags">
          {{tag}}
          <button type="button" class="close" aria-label="Remove" ng-click="c.removeTag(tag)">
            &times;
          </button>
        </span>
        <!-- Input box with dropdown -->
        <div class="dropdown" ng-click="$event.stopPropagation()">
          <input type="text" id="multiInput" 
                 class="form-control tag-input"
                 ng-click="c.showDropdown = true"
                 placeholder="Select values..." />
          <ul class="dropdown-menu" ng-show="c.showDropdown">
            <li ng-repeat="option in c.filteredOptions()" ng-click="c.addTag(option)">
              <a href="javascript&colon;void(0)">{{option}}</a>
            </li>
          </ul>
        </div>
      </div>
    </div>    
    <button type="submit" class="btn btn-primary">Save</button>
  </form>
</div>

 

 

 

 

CSS Styling

The CSS enhances the user experience by styling the input, dropdown, and tags.

 

 

 

.container {
  margin: 20px;
}

.tag-container {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
  border: 1px solid #ccc;
  padding: 5px;
  border-radius: 5px;
  position: relative;
}

.tag {
  display: inline-flex;
  background-color: #007bff;
  color: #fff;
  padding: 5px 10px;
  border-radius: 3px;
  align-items: center;
}

.tag button.close {
  background: transparent;
  border: none;
  color: #fff;
  font-size: 14px;
  margin-left: 5px;
  cursor: pointer;
}

.tag-input {
  flex: 1;
  border: none;
  outline: none;
}

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1000;
  display: block;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 0;
  margin: 0;
  max-height: 200px;
  overflow-y: auto;
}

.dropdown-menu li {
  list-style: none;
}

.dropdown-menu li a {
  display: block;
  padding: 8px 15px;
  color: #333;
  text-decoration: none;
}

.dropdown-menu li a:hover {
  background-color: #f0f0f0;
}

 

 

 

 

Conclusion

With the techniques demonstrated, you can build a highly interactive multi-select input feature in ServiceNow Service Portal. This feature ensures a seamless user experience by dynamically filtering options, allowing for efficient value selection, and managing dropdown behavior effectively.