How to use widgets correctly in calalog items

yuf
Tera Contributor

How to use widgets correctly in calalog items

Hello, there is a problem that has troubled me for a few days. I want to add some custom things to calalog items. I investigated for a long time and learned that when creating a variable in calalog item, you can select the custom type, and then select the widget you created in the Widget in the type specifications. But I don’t know if this is the right way to do it. And the screen keeps reporting errors.
content.js:1 Uncaught IndexSizeError: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.
Please tell me how to do it right, I will be very grateful to you!

2 REPLIES 2

Cheikh Ahmadou
Tera Guru

Using custom widgets in catalog items is a powerful way to extend Service Catalog functionality in the Service Portal. But it's also one of the trickiest areas due to how widgets interact with variable types and the portal rendering engine.

Correct Way to Use Custom Widgets in Catalog Items

1. Create Your Custom Widget

In Service Portal > Widgets:

  • Create a new widget or use one you’ve already made.

  • It should be designed to work inside a catalog item, meaning:

    • Use input object to receive data

    • Use options to receive parameters

    • Use $sp.getValue() and $sp.setValue() to support two-way binding

2. Create a Catalog Variable

  • Go to the Catalog Item > Variables tab

  • Create a new variable:

    • Type: Custom

    • Type Specifications → Widget: select your custom widget

    • Optional: check Visible, Mandatory, etc.

 

Fixing the Error

Uncaught IndexSizeError: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.

This is usually caused by a widget trying to access the DOM or selection before it’s ready — typically inside a setTimeout, selection.getRangeAt(), or similar browser DOM operation.



NB: In your widget’s Client Script, wrap any DOM-accessing code in a setTimeout or $timeout, but make sure the element is actually present and active in the DOM:

$timeout(function() {
  var el = document.getElementById('my-widget-element');
  if (el) {
    // safe to use el now
  }
}, 0);

Also avoid manipulating selections or DOM directly inside $watch() unless you're sure the element is present. 

Ankur Bawiskar
Tera Patron
Tera Patron

@yuf 

yes that's the correct way.

what that widget contains? Are you sure your widget is not throwing that error?

I haven't seen such issues in past.

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader