logo

NJP

Embedding a Search Widget Inside a Carousel Widget in Service Portal

New article articles in ServiceNow Community · Mar 22, 2026 · article

This implementation uses two widgets :

  1. Carousel Widget (Parent)

  2. Homepage Search Widget (Child)


1. Carousel Widget (Parent Widget)

HTML

`<div class="animated-hero-carousel">
  <uib-carousel interval="options.interval" no-wrap="false">

    <uib-slide ng-repeat="slide in data.slides" active="slide.active">
      <div class="slide-wrapper">

        <!-- Background Image -->
        <div class="slide-image"
             ng-style="{'background-image': 'url(' + slide.background + ')'}">
        </div>

      </div>
    </uib-slide>

  </uib-carousel>

  <!-- Search Widget Overlay -->
  <div class="homepage-search-overlay">
    <sp-widget widget="data.homepageSearchWidget"></sp-widget>
  </div>
</div>
`

CSS

`.animated-hero-carousel,
.animated-hero-carousel .carousel,
.animated-hero-carousel .item,
.animated-hero-carousel .slide-wrapper {
  height: 40vh !important;
  width: 100% !important;
  position: relative;
  overflow: hidden;
}

.slide-image {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  z-index: 1;
}

.homepage-search-overlay {
  position: absolute;
  top: 0;
  width: 100vw;
  height: 100%;
  backdrop-filter: drop-shadow(2px 4px 6px black);
}

@media (max-width: 768px) {
  .homepage-search-overlay {
    width: 90%;
    bottom: 2rem;
  }
}
`

Server Script

`(function () {

    // Load carousel slides from related list
    data.slides = $sp.getRelatedList('sp_carousel_slide', 'carousel');

    // Calling child (search) widget
    data.homepageSearchWidget = $sp.getWidget('demo_homepage_search');

})();
`

Data Table

  • Table: sp_instance_carousel

  • Related List: sp_carousel_slide

  • Stores:


2. Homepage Search Widget (Child Widget)

HTML

`<div id="homepage-search" class="hidden-xs wrapper-xl">
  <div class="wrapper-xl">

    <h2 class="text-center" ng-bind="options.title"></h2>

    <div ng-if="options.short_description"
         class="text-center"
         ng-bind="options.short_description">
    </div>

    <sp-widget widget="data.typeAheadSearch"></sp-widget>

  </div>
</div>
`

CSS

`#homepage-search {
  padding: 2rem !important;
}

#homepage-search .wrapper-xl {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding-left: 10vw !important;
}

#homepage-search .text-center {
  color: #FFF !important;
}

#homepage-search div[widget="widget"] {
  width: 35%;
}
`

Server Script

`var aisEnabled = $sp.isAISearchEnabled();

var title = 'Hello ';
var loggedInUser = gs.getUserDisplayName();
title += loggedInUser;

options['title'] = title;
options['short_description'] = 'Welcome to Customer Support';

// Load Typeahead Search widget
if (aisEnabled) {
    options['utterancePlacement'] = 'body';
    options['placement'] = 'dynamic-landing';
    data.typeAheadSearch = $sp.getWidget('typeahead-search', options);
} else {
    data.typeAheadSearch = $sp.getWidget('typeahead-search', options.typeahead_search);
}
`

Data Table

  • Widget Instance Table: sp_instance

  • Uses:


How the Widgets Are Connected

Step-by-Step Flow

 

1. Parent Widget Calls Child Widget

In the Carousel Server Script :

`data.homepageSearchWidget = $sp.getWidget('demo_homepage_search');
`

This:

  • Fetches the Homepage Search widget

  • Stores it in data.homepageSearchWidget


2. Parent HTML Renders Child Widget

`<sp-widget widget="data.homepageSearchWidget"></sp-widget>
`

This:

  • Embeds the child widget UI inside the carousel

  • Makes it reusable and dynamic

Result

Screenshot 2026-03-23 at 1.32.44 AM.png

View original source

https://www.servicenow.com/community/itsm-articles/embedding-a-search-widget-inside-a-carousel-widget-in-service/ta-p/3512385