Home > widget-integration > InstantSearchController

InstantSearchController class

Controller for instant search UI interactions.

Signature:

export declare class InstantSearchController 

Example

window.boostWidgetIntegration.extend('InstantSearchController', (InstantSearchController) => {
  return class CustomController extends InstantSearchController {
    // Add custom analytics on open
    async openSuggestion(input) {
      this.trackOpen();
      await super.openSuggestion(input);
    }
  };
});

Constructors

Constructor

Modifiers

Description

(constructor)(appService, instantSearchService, instantSearchAPI, instantSearchSelectors, positionService, recentSearchService)

Constructs a new instance of the InstantSearchController class

Properties

Property

Modifiers

Type

Description

appService

protected

AppService

boundHandlers

protected

Map<string, EventListener>

Bound event handlers for cleanup

currentBundles

protected

Array<Record<string, unknown>>

Current bundles from the latest render (for keyboard Enter handling)

defaultData

protected

DefaultSuggestionData | null

Default suggestion data

dialogObserver

protected

MutationObserver | null

MutationObserver for dialog integration cleanup

focusDelayTimer

protected

ReturnType<typeof setTimeout> | null

Delayed focus timer from openFullWidth — must be canceled on close/destroy

focusTrapHandler

protected

((e: KeyboardEvent) => void) | null

Focus-trap keydown handler stored for cleanup

initialized

protected

boolean

Whether controller is initialized

instantSearchAPI

protected

InstantSearchAPI

instantSearchSelectors

protected

InstantSearchSelectors

instantSearchService

protected

InstantSearchService

isClosing

protected

boolean

Guard flag to prevent ISW from reopening during a close cycle

isRendering

protected

boolean

Prevent concurrent renders

originalQuery

protected

string

Original query typed by the user before keyboard navigation started

positionService

protected

PositionService

previousIsMobile

protected

boolean | null

Previous mobile state for responsive breakpoint change detection

recentSearchService

protected

RecentSearchService

savedFocusElement

protected

HTMLElement | null

Saved focus element for restoration

scrollCleanup

protected

(() => void) | null

Scroll handler cleanup function from position service

searchSettings

protected

SearchSettings$1 | null

Search settings cache

state

protected

ISWState

template

protected

string

Cached ISW template

Methods

Method

Modifiers

Description

activateFocusTrap()

protected

Activate focus trap for full-width overlay mode.

Prevents Tab / Shift+Tab from leaving the overlay, keeping keyboard focus cycling through interactive elements inside the ISW wrapper.

Stores the handler in focusTrapHandler so it can be removed by deactivateFocusTrap() without leaking event listeners.

**WCAG**: SC 2.1.2 No Keyboard Trap — trap is intentional UX (modal-like overlay) and Escape always closes it, satisfying the escape-mechanism requirement.

announceResults(count)

protected

Announce search result count to screen readers via an ARIA live region.

Creates a visually-hidden role="status" live region on first call and reuses it on subsequent calls. The text is cleared then set so that repeated identical counts still trigger an announcement.

**WCAG**: SC 4.1.3 Status Messages (Level AA)

applyWidgetStyles(container)

protected

Apply widget styles to the ISW container element.

Called once during initWithContext() after the initial render so the container element exists in the DOM. Override to apply shop-specific inline CSS custom properties or extra class names.

awaitAnimationElementFinished(element, step, maxMs)

protected

Wait for an element's CSS animation to finish by polling its position.

Polls the element's getBoundingClientRect() at intervals. Once the x/y coordinates stabilize between two consecutive polls (and are >= 0), the animation is considered finished.

**Legacy**: awaitAnimationElementFinished(htmlElement, step, maxMs) **New**: Instance method with same signature and behavior

bindInputEvents(input)

protected

Bind event handlers to an input.

bindSearchInputs()

Bind event handlers to search inputs.

**Legacy**: Part of initInstantSearchWidgetEvents() **New**: Separated method for rebinding

cleanupBodyStyles()

protected

Remove inline body styles that some themes apply via a native <dialog> scroll-lock mechanism (e.g. position: fixed; top: -scrollY; width: 100%).

These styles are NOT removed by clearing CSS classes, so they must be explicitly stripped as inline properties when ISW closes.

Override to restore or preserve specific properties for a given theme.

closeDropdown()

protected

Close dropdown style.

closeFullWidth()

protected

Close full-width overlay.

Legacy onCloseSuggestion does NOT differentiate full-width vs dropdown — it always hides the same container > div element and calls restoreThemeDialog.

closeISWDialog()

protected

Close the theme <dialog> that is currently hosting the ISW element.

Override to apply a custom close strategy for a specific theme (e.g. clicking a close button instead of calling dialog.close()).

closeSuggestion(input)

Close suggestion dropdown/overlay.

**Legacy**: closeSuggestion() / onCloseSuggestion() **New**: closeSuggestion(input?) with state management

deactivateFocusTrap()

protected

Deactivate focus trap, removing the keyboard event listener.

debounce(func, wait)

protected

Simple debounce utility.

destroy()

Cleanup event listeners and resources.

detectMobileStyleFromDOM()

protected

Detect the mobile ISW style from the rendered DOM. - **style1** (full-width overlay): mobile container contains .boost-sd__search-bar-wrapper--mobile - **style2** (dropdown): no .boost-sd__search-bar-wrapper--mobile present

Override to customise detection for non-standard Liquid template structures.

dispatchRenderedEvent(data)

protected

Dispatch rendered event.

ensureMobileWrapperVisible()

protected

Ensure the mobile search bar wrapper is visible.

Some themes initially hide the mobile wrapper. This method removes the hide class on user interaction (input, click, focus).

**Legacy**: ensureMobileWrapperVisible() inline closure **New**: Dedicated method on controller

getActiveInput()

protected

Get active input element.

getFocusTrapElements()

protected

Collect all keyboard-focusable elements inside the full-width overlay.

getNavigableItems()

protected

Get all keyboard-navigable items including interactive buttons.

Returns items in navigation order: clear button, close button, suggestion items, then view-all products button.

**Legacy**: onKeyboardNavigation() counted these separately with index offsets **New**: Single ordered array for clean navigation

getShopSpecificStyles()

protected

Get shop-specific CSS custom properties to inject into the widget container.

Override to provide per-shop theming without touching global CSS. The returned object is applied via container.style.setProperty(), so keys must be valid CSS custom property names (e.g. --boost-isw-max-width).

getState()

Get current ISW state.

getSuggestionData()

Get current suggestion data.

getSuggestionItems()

protected

Get suggestion items.

handleBundleEnter(current)

protected

Handle Enter on bundle items by dispatching events to DI-based controllers.

handleDialogIntegration()

protected

Handle dialog integration for dropdown styles.

For dropdown styles, observes the theme's #search-modal host element and injects ISW into the dialog when it opens, then moves it back to the body when the dialog closes. Full-width styles skip this entirely — the ISW overlay already covers the viewport.

**Legacy**: handleDialogIntegrationForDropdownStyles() **New**: handleDialogIntegration() + injectISWIntoDialog() + moveISWBackToBody()

handleEnter(input)

protected

Handle Enter key press.

handleInputChange(event, input)

Handle input change event.

**Legacy**: handleSearchInputChange(context, e, input) + searchInputListener() **New**: handleInputChange(e, input) with state management

handleInputClick(event, input)

Handle input click event.

Respects data-disable-open-on-empty: when this attribute is present on the input element, clicking an empty search box will not open the suggestion panel. The panel still opens normally once the user starts typing.

handleInputFocus(event, input)

Handle input focus event.

Respects data-disable-open-on-empty: when this attribute is present on the input element, focusing an empty search box will not open the suggestion panel. The panel still opens normally once the user starts typing.

handleKeydown(event, input)

Handle keydown event for keyboard navigation.

**Legacy**: searchInputKeydownListener(context, e, input) **New**: handleKeydown(e, input) with proper state management

handleReset(input, resetButton)

protected

Handle reset button click.

handleSubmit(event, input)

protected

Handle form submit.

handleSubmitButtonKeydown(event, button)

protected

Handle submit button keydown for WCAG keyboard activation tracking.

**Legacy**: Inline keydown handler on submit button in initInstantSearchWidgetEvents() **New**: Dedicated method for extensibility

handleTab(event)

protected

Handle Tab key press.

hideContainerPanel()

protected

Hide the suggestion panel and clean up body classes.

Matches legacy onCloseSuggestion exactly: - Adds boost-sd__g-hide to the container > div element - Clears aria-controls - Removes body classes - Always calls restoreThemeDialog

init()

Initialize controller without context (basic setup).

**Legacy**: Part of handleInstantSearchWidget() **New**: Separated initialization method

initWithContext(searchSettings)

Initialize controller with full context.

**Legacy**: initInstantSearchWidget(context) + initInstantSearchWidgetEvents(context) **New**: initWithContext(searchSettings) with proper typing

injectISWIntoDialog(dialog)

protected

Inject the ISW element into a theme search dialog.

Waits for the ISW root element and the predictive-search container inside the dialog to be available, then inserts ISW immediately after the predictive-search container and sizes the dialog to fit.

moveISWBackToBody(dialog)

protected

Move the ISW element back to document.body after a dialog closes.

Restores dialog dimensions and resets wrapper position styles so that subsequent dropdown-style positioning calculations start from a clean state.

navigateDown(input)

protected

Navigate down in suggestions.

navigateUp(input)

protected

Navigate up in suggestions.

openDropdown(input)

protected

Open dropdown style.

openFullWidth(input)

protected

Open full-width style overlay.

openSuggestion(input)

Open suggestion dropdown/overlay.

**Legacy**: openSuggestion() / onOpenSuggestion() **New**: openSuggestion(input) with state management

performClose(isFullWidth, input)

protected

Perform the actual close operation.

Separated from closeSuggestion to support deferred close (e.g., Symmetry theme delay).

processWidgetDataForRendering(data)

protected

Process suggestion data before passing it to the template renderer.

Extension point for TS teams to modify, filter, or augment suggestion data immediately before rendering — without overriding the entire render() method.

removeCurrentSelected()

protected

Remove current selection.

render(data)

Render suggestion data.

**Legacy**: replaceHTML() + render logic in handleInstantSearchWidget **New**: render(data) with concurrent render prevention

render3rdAppSupportButton()

protected

Render a 3rd-party support CRM button inside the ISW container.

renderDefaultData()

protected

Render default data.

replaceBlock(container, htmlDoc, selector)

protected

Replace a block in the container.

replaceHTML(htmlString)

protected

Replace HTML in ISW container.

**Legacy**: replaceHTML(context, htmlString) **New**: replaceHTML(htmlString) method

restoreFocusedElement()

protected

Restore saved focus element.

saveClickedSuggestionTerm(term)

protected

Save clicked suggestion term to localStorage for AIML analytics.

The collection-filter module reads this value to attach suggestion, parent_request_id, and item_rank parameters to search API requests.

**Legacy**: setLocalStorage(CLICK_SUGGESTION_TERM, title) in render callback **New**: Dedicated method for extensibility and testability

saveFocusElement(element)

protected

Save focus element for restoration.

searchAndRender(query)

protected

Search and render results.

setupAccessibility(input)

Setup accessibility attributes.

**Legacy**: Inline in initInstantSearchWidgetEvents() **New**: Dedicated method for WCAG compliance

setupEventListeners()

protected

Setup all event listeners: global (document click, resize) + custom window events.

All handlers are stored in boundHandlers so destroy() can clean them up.

setupFormButtons(input)

protected

Setup form buttons (submit, reset, close).

setupGlobalEventListeners()

protected

Setup global event listeners.

setupInputAttributes(input, index)

protected

Setup input element attributes.

setupSuggestionClickHandlers()

protected

Setup click handlers on suggestion items.

stripHtml(str)

protected

Strip HTML tags from string.

syncAllInputs(value)

protected

Sync value across all search inputs.

toggleResetButton(input, show)

protected

Toggle reset button visibility.

toggleSuggestion()

Toggle suggestion visibility.

updatePosition(input)

protected

Update ISW dropdown position for a given input.

Convenience method wrapping the PositionService.updatePosition flow. Manages scroll handler cleanup automatically.

**Legacy**: calcPositionSuggestionResult(context, input) **New**: updatePosition(input) with lifecycle management

updateSelection(items, input)

protected

Update selection state and UI.