---
original_url: "https://jace.pro/blog/service-portal-custom-search-source/"
format: markdown
ai_optimized: true
---

Service Portal - Custom Search Source# Service Portal - Custom Search Source

October 18, 2017 [servicenow](/tags/servicenow/)

  Enable AI AnimationWe have knowledge bases at my work and as such the default search is limited. I wanted to add to the type ahead a result like “Search all KB’s for `your term here`”.

I looked at the search sources and found it has a scripted bit but it’s [not documented well](https://docs.servicenow.com/bundle/jakarta-servicenow-platform/page/build/service-portal/task/add-table-search-source.html).

## [OOB Search Source](#oob-search-source)

So first lets look at the out of box “Service Catalog” search source,
specifically it’s data fetch (shows up when you select,
`Is scripted source`)

`(function(query) {
    var results = [];
    //Here goes the logic. Compute results how you want!
    if (!gs.isLoggedIn())
        return results;

    var sc = new GlideRecord('sc_cat_item');
    sc.addQuery('123TEXTQUERY321', query);
    sc.addQuery('active',true);
    sc.addQuery('no_search', '!=', true);
    sc.addQuery('visible_standalone', true);
    sc.addQuery('sys_class_name', 'NOT IN', 'sc_cat_item_wizard');
    var portalValue = $sp.getValue('sc_catalog');
    if (portalValue)
        sc.addQuery('sc_catalogs', portalValue);
    sc.query();
    var catCount = 0;
    while (sc.next() && catCount < data.limit) {
        if (!$sp.canReadRecord(sc))
            continue;

        var item = {};
        item.type = "sc";
        item.page = "sc_cat_item";

        if (sc.getRecordClassName() == "sc_cat_item_guide")
            item.page = "sc_cat_item_guide";
        else if (sc.getRecordClassName() == "sc_cat_item_content") {
            var gr = new GlideRecord('sc_cat_item_content');
            gr.get(sc.getUniqueValue());
            $sp.getRecordValues(item, gr, 'url,content_type,kb_article');
            item.type = "sc_content";
        }
        else
            item.type = "sc";

        $sp.getRecordDisplayValues(item, sc, 'name,short_description,picture,price,sys_id,sys_class_name');
        item.score = parseInt(sc.ir_query_score.getDisplayValue());
        item.label = item.name;
        item.primary = item.name;

        //calculating URL
        if (item.type == "sc")
            item.url = '?id=' + item.page + '&sys_id=' + item.sys_id;
        if (item.type == "sc_content") {
            if (item.content_type == "kb")
                item.url = '?id=kb_article&sys_id=' + item.kb_article;
            else if (item.content_type == "external")
                item.target = '_blank';
            else
                item.url = '?id=sc_cat_item&sys_id=' + item.sys_id;
        }
        if (item.type == "sc_guide")
            item.url = '?id=sc_cat_item_guide&sys_id=' + item.sys_id;

        results.push(item);
        catCount++;
    }

    return results;
})(query);`There’s a lot going on there, but what I picked out was, it returns an
array of objects where the object has the following properties;

`{
    score:"-100",
    label:resultMsg,
    primary:resultMsg,
    url: "?id=kb_search&spa=1&query=" + query,
    //target: "",
    //page:"kb_search"
}`## [Score](#score)

This seems pretty obvious to me, a integer to determine order in the results

## [Label and Primary](#label-and-primary)

I’m not sure the difference but this seems to be what shows up as text in the result.

## [URL](#url)

This is where the browser will go on click.

## [Target](#target)

I assume this is the a tag’s `target` attribute, so if you want a new tab each time use a value of `_blank`.

## [Page](#page)

I am not sure if this does anything on it’s own, in the out of box widget they use this in the defined url.

## [Search Source I made](#search-source-i-made)

Below is my search source script.

`(function(query) {
    var resultMsg = "Search KB for " + query;
    var results = [{
        score:"-100",
        label:resultMsg,
        primary:resultMsg,
        url: "?id=kb_search&spa=1&query=" + query,
        //target: "",
        //page:"kb_search"
    }];
    return results;
})(query);`## [Further Reading](#further-reading)

[Community Thread](https://community.servicenow.com/community/develop/blog/2017/03/29/using-scripted-search-sources-to-search-external-websites-and-applications)

---
[View this page on GitHub](https://github.com/jacebenson/jace.pro/tree/main/./src/posts/2017/2017-10-17-sp-custom-search-source.md).

[Service Portal - Custom Search Source](https://jace.pro/blog/service-portal-custom-search-source/) [Jace Benson](https://jace.pro) ![Jace Benson](https://jace.pro/icon-512x512.png)

---

*This content is from Jace Benson's ServiceNow and tech blog at jace.pro*
*Original post: https://jace.pro/blog/service-portal-custom-search-source/*
