To Display All Catalog Items in Service Portal

rishabh31
Mega Sage

Dear Team,

 

I am working on Portal, when a user opens the Service Portal> Catalog, then I want to display the 'All Items' just beside the My Recent Items and Popular Items (as marked in the attached screenshot). So when user clicks on 'All Items' they can see all catalog items and further click on them and raise request.

 

This is coming from a widget named 'Recent & Popular Items', I cloned this and tried to modify the server scripts and all but no luck. Can anyone please help to modify this widget script, so that all items will be displayed in the section as shown in the attached screenshot?

*Body HTML Template-

<div class="recent-widget" ng-if="!c.hideWidget">
    <div class="panel panel-default">
        <div class="panel-heading pad-bottom">
            <ul class="nav nav-tabs" style="border-bottom : 0px" role="tablist">
                <li class="item" id="tab-recent-items" ng-if="data.recentItems.length > 0"
                    ng-click="c.changePanel('recent')" ng-keydown="c.switchTab($event, 'recent')"
                    role="presentation">
                    <div ng-class="{'sc-tab-div' : c.show_recent}" class="recent"
                         ng-attr-tabindex="{{!c.show_recent ? '-1': 0}}"
                         ng-attr-aria-controls="{{c.show_recent ? 'tabpanel-recent-items' : undefined}}"
                         aria-selected="{{c.show_recent}}" role="tab">
                        <span> ${My Recent Items} </span>
                    </div>
                </li>
                <li class="item" id="tab-popular-items" ng-if="data.popularItems.length > 0"
                    ng-keydown="c.switchTab($event, 'popular')" ng-click="c.changePanel('popular')"
                    role="presentation">
                    <div ng-class="{'sc-tab-div' : !c.show_recent}" class="popular"
                         ng-attr-tabindex="{{c.show_recent ? '-1': 0}}"
                         ng-attr-aria-controls="{{!c.show_recent ? 'tabpanel-popular-items' : undefined}}"
                         aria-selected="{{!c.show_recent}}" role="tab">
                        <span> ${Popular Items} </span>
                    </div>
                </li>
            </ul>
        </div>

        <div id="tabpanel-recent-items" class="panels-container" ng-if="c.show_recent" role="tabpanel"
             aria-labelledby="tab-recent-items">
            <span class="sr-only" role="heading" aria-level="2"> ${My Recent Items} </span>
            <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-recent-items">
                <li class="item-card-column" ng-repeat="item in data.recentItems track by item.sys_id" role="listitem" ng-init="startItemList()">
                    <div class="panel-default item-card b" data-original-title="{{::item.name}}">
                        <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=recent_items"
                           class="panel-body block height-100"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Recent Item", "Item Clicked");'>
                            <div>
                                <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis catalog-item-name" title="{{::item.name}}">{{::item.name}}</h3>
                                <img ng-src="{{::item.picture}}" ng-if="::item.picture"
                                     class="m-r-sm m-b-sm item-image pull-left" alt="" aria-hidden="true"/>
                                <div class="text-muted item-short-desc catalog-text-wrap">{{::item.short_description}}
                                </div>
                            </div>
                        </a>
                    </div>
                    <div class="panel-footer b">
                        <a href="?id={{::item.page}}&sys_id={{item.sys_id}}&referrer=recent_items"
                           class="pull-left text-muted" aria-label="${View Details} {{::item.name}}"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Recent Item", "Item Clicked");'>${View Details}</a>
                        <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span>
                        &nbsp;
                    </div>
                </li>
            </ul>
        </div>

        <div id="tabpanel-popular-items" class="panels-container" ng-if="!c.show_recent" role="tabpanel"
             aria-labelledby="tab-popular-items">
            <span class="sr-only" role="heading" aria-level="2"> ${Popular Items} </span>
            <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-popular-items">
                <li class="item-card-column"
                    ng-repeat="item in data.popularItems | orderBy: 'order' | limitTo: data.limit track by item.sys_id"
                    role="listitem" ng-init="startItemList()">
                    <div class="panel-default item-card b" data-original-title="{{::item.name}}">
                        <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=popular_items"
                           class="panel-body block height-100"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Popular Item", "Item Clicked");'>
                            <div>
                                <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis catalog-item-name" title="{{::item.name}}">{{::item.name}}</h3>
                                <img ng-src="{{::item.picture}}" ng-if="::item.picture"
                                     class="m-r-sm m-b-sm item-image pull-left" alt="" aria-hidden="true"/>
                                <div class="text-muted item-short-desc catalog-text-wrap">{{::item.short_description}}
                                </div>
                            </div>
                        </a>
                    </div>
                    <div class="panel-footer b">
                        <a href="?id={{::item.page}}&sys_id={{item.sys_id}}&referrer=popular_items"
                           class="pull-left text-muted" aria-label="${View Details} {{::item.name}}"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Popular Item", "Item Clicked");'>${View Details}</a>
                        <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span>
                        &nbsp;
                    </div>
                </li>
            </ul>
        </div>
 </div>
</div>

 

*Server Script:

(function() {
  /* populate the 'data' object */
	data.limit = options.limit || 8;
	var recent_by = options.recent_by || 'view';
	var recent = new GlideRecord('sp_log');
	if (recent_by === 'view')
		recent.addEncodedQuery('userDYNAMIC90d1921e5f510100a9ad2572f2b477fe^type=Cat Item View^sys_created_onONThis quarter@javascript&colon;gs.beginningOfThisQuarter()@javascript&colon;gs.endOfThisQuarter()');
	else
		recent.addEncodedQuery('userDYNAMIC90d1921e5f510100a9ad2572f2b477fe^type=Cat Item Request^sys_created_onONThis quarter@javascript&colon;gs.beginningOfThisQuarter()@javascript&colon;gs.endOfThisQuarter()');
	recent.orderByDesc('sys_created_on');
	recent.query();
	var recentItems = [];
	var catalogArr = ($sp.getCatalogs().value + "").split(",");
	data.showPrices = $sp.showCatalogPrices();

	while (recent.next() && recentItems.length < data.limit) {
		if (isAlreadyAdded(recent.getValue('id')))
			continue;
		var catalogItemJS = new sn_sc.CatItem(recent.getValue('id'));
		if (!catalogItemJS.canView(gs.isMobile()) || !catalogItemJS.isVisibleServicePortal())
			continue;
		var item = {};
		var catItemDetails = catalogItemJS.getItemSummary(true);
		if(!catItemDetails.visible_standalone)
			continue;
		var inCatalog = false;
		for (var i=0; i<catItemDetails.catalogs.length; i++) {
			if (catalogArr.indexOf(catItemDetails.catalogs[i].sys_id + "") >= 0) {
				inCatalog = true;
				break;
			}
		}
		if (inCatalog) {
			item.name = catItemDetails.name;
			item.short_description = catItemDetails.short_description;
			item.picture = catItemDetails.picture;
			item.price = catItemDetails.price;
			item.sys_id = catItemDetails.sys_id;
			item.hasPrice = item.price != 0;
			item.page = catItemDetails.type == 'order_guide'? 'sc_cat_item_guide' : 'sc_cat_item';
			recentItems.push(item);
		}
	}

	function isAlreadyAdded(catItemSysId) {
		for (var i=0;i<recentItems.length;i++) {
			if (catItemSysId==recentItems[i].sys_id)
				return true;
		}
		return false;
	}

	data.recentItems = recentItems;

	data.popularItems = getPopularItems();

	function getPopularItems() {
        return new SCPopularItems().useOptimisedQuery(gs.getProperty('glide.sc.portal.popular_items.optimize', true) + '' == 'true')
            .baseQuery(options.popular_items_created + '')
            .allowedItems($sp.getAllowedItems())
            .visibleStandalone(true)
            .visibleServicePortal(true)
            .itemsLimit(options.limit || 8)
            .restrictedItemTypes(['sc_cat_item_guide', 'sc_cat_item_wizard', 'sc_cat_item_content', 'sc_cat_item_producer'])
            .itemValidator(function(item, itemDetails) {
                if (!item.canView(gs.isMobile()) || !item.isVisibleServicePortal())
                    return false;

                return true;
            })
            .responseObjectFormatter(function(item, itemType, itemCount) {
                return {
                    order: 0 - itemCount,
                    name: item.name,
                    short_description: item.short_description,
                    picture: item.picture,
                    price: item.price,
                    sys_id: item.sys_id,
                    hasPrice: item.price != 0,
                    page: itemType == 'sc_cat_item_guide' ? 'sc_cat_item_guide' : 'sc_cat_item'
                };
            })
            .generate();
    }
})();

*Client script/Controller:

function($scope, $timeout, $window) {
  /* widget controller */
  var c = this;
	c.show_recent = false;
	
	c.KEYS = {
						DOWN:40,
						LEFT:37,
						RIGHT:39,
						TAB:9,
						UP:38
					 }
	
	var tabSelectors = ['div.recent', 'div.popular'];
	function focusTab(recent) {
		var ele;
		if (recent)
			ele = $(tabSelectors[0]);
		else
			ele = $(tabSelectors[1]);

		if (ele)
			ele.focus();
	}

	if (c.data.recentItems.length > 0)
		c.show_recent = true;

	c.changePanel = function(panel_name) {
		if (c.show_recent) {
			if (panel_name == 'popular')
				c.show_recent = false;
		} else {
			if (panel_name == 'recent')
				c.show_recent = true;
		}
	};

	c.switchTab = function($event, tab) {
		var key = null;
		if (event.keyCode === c.KEYS.LEFT || event.keyCode === c.KEYS.UP)
			key = c.KEYS.LEFT;
		else if (event.keyCode === c.KEYS.RIGHT || event.keyCode === c.KEYS.DOWN)
			key = c.KEYS.RIGHT;
		else if (event.keyCode === c.KEYS.TAB) {
			return;
		}
		if (key === null)
			return;

		$event.preventDefault();
		c.show_recent = !c.show_recent;
		focusTab(c.show_recent);
	}

	c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0);

	function handleTooltip() {
		if(!$scope.isTouchDevice()) {
			$timeout(function() {
				$(".item-card").each(function(index) {
					var itemNameElement = $(this).find(".catalog-item-name");
					if(itemNameElement && itemNameElement[0] && itemNameElement.width() < itemNameElement[0].scrollWidth) {
						$(this).attr('data-toggle','tooltip');
					}
				});
			});
		}
	}
	
	$scope.isTouchDevice = function() {
		return ('ontouchstart' in $window);
	}
	
	$scope.startItemList = function() {
		handleTooltip();
	}
}

Requesting help on this.

@Nia McCash or any one who can help on this.

 

Thanks in adavnce

3 ACCEPTED SOLUTIONS

Add the new tab HTML:

<div class="recent-widget" ng-if="!c.hideWidget">
    <div class="panel panel-default">
        <div class="panel-heading pad-bottom">
            <ul class="nav nav-tabs" style="border-bottom : 0px" role="tablist">
                <li class="item" id="tab-recent-items" ng-if="data.recentItems.length > 0"
                    ng-click="c.changePanel('recent')" ng-keydown="c.switchTab($event, 'recent')"
                    role="presentation">
                    <div ng-class="{'sc-tab-div' : c.show_recent}" class="recent"
                         ng-attr-tabindex="{{!c.show_recent ? '-1': 0}}"
                         ng-attr-aria-controls="{{c.show_recent ? 'tabpanel-recent-items' : undefined}}"
                         aria-selected="{{c.show_recent}}" role="tab">
                        <span> ${My Recent Items} </span>
                    </div>
                </li>
                <li class="item" id="tab-popular-items" ng-if="data.popularItems.length > 0"
                    ng-keydown="c.switchTab($event, 'popular')" ng-click="c.changePanel('popular')"
                    role="presentation">
<!-- 
##########################################
START CUSTOM CODE
##########################################
Original DIV
                    <div ng-class="{'sc-tab-div' : !c.show_recent}" class="popular"
                         ng-attr-tabindex="{{c.show_recent ? '-1': 0}}"
                         ng-attr-aria-controls="{{!c.show_recent ? 'tabpanel-popular-items' : undefined}}"
                         aria-selected="{{!c.show_recent}}" role="tab">
                        <span> ${Popular Items} </span>
                    </div>
-->
                    <div ng-class="{'sc-tab-div' : !c.show_recent}" class="popular"
                         ng-attr-tabindex="{{c.show_popular ? '-1': 1}}"
                         ng-attr-aria-controls="{{c.show_popular ? 'tabpanel-popular-items' : undefined}}"
                         aria-selected="{{c.show_popular}}" role="tab">
                        <span> ${Popular Items} </span>
                    </div>
                </li>
                <li class="item" id="tab-all-items" ng-if="data.allItems.length > 0"
                    ng-keydown="c.switchTab($event, 'allitems')" ng-click="c.changePanel('allitems')"
                    role="presentation">
                    <div ng-class="{'sc-tab-div' : c.show_allitems}" class="allitems"
                         ng-attr-tabindex="{{c.show_allitems ? '-1': 2}}"
                         ng-attr-aria-controls="{{c.show_allitems ? 'tabpanel-all-items' : undefined}}"
                         aria-selected="{{c.show_allitems}}" role="tab">
                        <span> ${All Items} </span>
                    </div>
<!-- 
##########################################
END CUSTOM CODE
##########################################
-->
              </li>
            </ul>
        </div>

        <div id="tabpanel-recent-items" class="panels-container" ng-if="c.show_recent" role="tabpanel"
             aria-labelledby="tab-recent-items">
            <span class="sr-only" role="heading" aria-level="2"> ${My Recent Items} </span>
            <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-recent-items">
                <li class="item-card-column" ng-repeat="item in data.recentItems track by item.sys_id" role="listitem" ng-init="startItemList()">
                    <div class="panel-default item-card b" data-original-title="{{::item.name}}">
                        <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=recent_items"
                           class="panel-body block height-100"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Recent Item", "Item Clicked");'>
                            <div>
                                <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis catalog-item-name" title="{{::item.name}}">{{::item.name}}</h3>
                                <img ng-src="{{::item.picture}}" ng-if="::item.picture"
                                     class="m-r-sm m-b-sm item-image pull-left" alt="" aria-hidden="true"/>
                                <div class="text-muted item-short-desc catalog-text-wrap">{{::item.short_description}}
                                </div>
                            </div>
                        </a>
                    </div>
                    <div class="panel-footer b">
                        <a href="?id={{::item.page}}&sys_id={{item.sys_id}}&referrer=recent_items"
                           class="pull-left text-muted" aria-label="${View Details} {{::item.name}}"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Recent Item", "Item Clicked");'>${View Details}</a>
                        <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span>
                        &nbsp;
                    </div>
                </li>
            </ul>
        </div>

<!-- 
##########################################
START CUSTOM CODE
##########################################
Original DIV
        <div id="tabpanel-popular-items" class="panels-container" ng-if="!c.show_recent" role="tabpanel"
             aria-labelledby="tab-popular-items">
-->
        <div id="tabpanel-popular-items" class="panels-container" ng-if="c.show_popular" role="tabpanel"
             aria-labelledby="tab-popular-items">
<!-- 
##########################################
END CUSTOM CODE
##########################################
-->          
            <span class="sr-only" role="heading" aria-level="2"> ${Popular Items} </span>
            <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-popular-items">
                <li class="item-card-column"
                    ng-repeat="item in data.popularItems | orderBy: 'order' | limitTo: data.limit track by item.sys_id"
                    role="listitem" ng-init="startItemList()">
                    <div class="panel-default item-card b" data-original-title="{{::item.name}}">
                        <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=popular_items"
                           class="panel-body block height-100"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Popular Item", "Item Clicked");'>
                            <div>
                                <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis catalog-item-name" title="{{::item.name}}">{{::item.name}}</h3>
                                <img ng-src="{{::item.picture}}" ng-if="::item.picture"
                                     class="m-r-sm m-b-sm item-image pull-left" alt="" aria-hidden="true"/>
                                <div class="text-muted item-short-desc catalog-text-wrap">{{::item.short_description}}
                                </div>
                            </div>
                        </a>
                    </div>
                    <div class="panel-footer b">
                        <a href="?id={{::item.page}}&sys_id={{item.sys_id}}&referrer=popular_items"
                           class="pull-left text-muted" aria-label="${View Details} {{::item.name}}"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "Popular Item", "Item Clicked");'>${View Details}</a>
                        <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span>
                        &nbsp;
                    </div>
                </li>
            </ul>
        </div>
      
<!-- 
##########################################
START CUSTOM CODE
##########################################
-->
        <div id="tabpanel-all-items" class="panels-container" ng-if="c.show_allitems" role="tabpanel"
             aria-labelledby="tab-all-items">
            <span class="sr-only" role="heading" aria-level="2"> ${All Items} </span>
            <ul class="row item-list-style-type-none item-card-row" role="list" aria-labelledby="tab-all-items">
                <li class="item-card-column" ng-repeat="item in data.allItems track by item.sys_id" role="listitem" ng-init="startItemList()">
                    <div class="panel-default item-card b" data-original-title="{{::item.name}}">
                        <a href="?id={{::item.page}}&sys_id={{::item.sys_id}}&referrer=all_items"
                           class="panel-body block height-100"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "All Items", "Item Clicked");'>
                            <div>
                                <h3 class="h4 m-t-none m-b-xs text-overflow-ellipsis catalog-item-name" title="{{::item.name}}">{{::item.name}}</h3>
                                <img ng-src="{{::item.picture}}" ng-if="::item.picture"
                                     class="m-r-sm m-b-sm item-image pull-left" alt="" aria-hidden="true"/>
                                <div class="text-muted item-short-desc catalog-text-wrap">{{::item.short_description}}
                                </div>
                            </div>
                        </a>
                    </div>
                    <div class="panel-footer b">
                        <a href="?id={{::item.page}}&sys_id={{item.sys_id}}&referrer=all_items"
                           class="pull-left text-muted" aria-label="${View Details} {{::item.name}}"
                           onclick='window.GlideWebAnalytics.trackEvent("Service Catalog", "All Items", "Item Clicked");'>${View Details}</a>
                        <span ng-if="data.showPrices && item.hasPrice" class="pull-right item-price font-bold">{{::item.price}}</span>
                        &nbsp;
                    </div>
                </li>
            </ul>
        </div>     
      
<!-- 
##########################################
END CUSTOM CODE
##########################################
-->      
 </div>
</div>

 

Add the class in the CSS:

.nav > li.item {
            text-align: center;
            }

            .recent-widget {
            .panel-heading {
            padding-bottom: 0px;
            }

            .row {
            margin-left: 0;
            margin-right: 0;
            padding-top: 15px;
            padding-left: 10px;
            padding-right: 10px;
            }
            }

            @media (min-width: 768px) {
            .item-card-column {
            -ms-flex: 0 0 50%;
            -moz-box-flex: 0 0 50%;
            -moz-flex: 0 0 50%;
            -webkit-box-flex: 0 0 50%;;
            -webkit-flex: 0 0 50%;
            flex: 0 0 50%;
            max-width: 50%;
            width: 50%;
            }
            }

            @media (min-width: 992px) {
            .item-card-column {
            -ms-flex: 0 0 25%;
            -moz-box-flex: 0 0 25%;
            -moz-flex: 0 0 25%;
            -webkit-box-flex: 0 0 25%;
            -webkit-flex: 0 0 25%;
            flex: 0 0 25%;
            max-width: 25%;
            width: 25%;
            }
            }

//##########################################
//START CUSTOM CODE
//##########################################	
//.popular, .recent {
.popular, .recent, .allitems {
 //##########################################
//END CUSTOM CODE
//##########################################	
            position: relative;
            display: block;
            padding: $nav-link-padding;
            line-height: $line-height-base;
            margin-right: 2px;
            border-radius: $border-radius-base $border-radius-base 0 0;
            color: $brand-primary-darker;

            &:hover {
            border-color: $nav-tabs-link-hover-border-color $nav-tabs-link-hover-border-color $nav-tabs-border-color;
            }

            &:focus {
            box-shadow: 0 0 0 1.5px $input-border-focus;
            outline: 4px solid transparent;
            }

            &:hover, &:focus {
            text-decoration: none;
            background-color: $nav-link-hover-bg;
            }

            &.sc-tab-div {
            border: 0;
            border-bottom: 3px solid $primary;
            background-color: transparent;
            color: $primary;

            &:hover, &:focus {
            background-color: $nav-link-hover-bg;
            }

            &:hover {
            border-color: $nav-tabs-link-hover-border-color $nav-tabs-link-hover-border-color $nav-tabs-border-color;
            }
            }
            }

            .catalog-item-name {
                text-decoration: underline;
            }


Rework the Client Script for more than 2 tabs:

function($scope, $timeout, $window) {
  /* widget controller */
  var c = this;
	console.dir(c.data.allItems);
	c.show_recent = false;
//##########################################
//START CUSTOM CODE
//##########################################	
	c.show_popular = false;
	c.show_allitems = false;
//##########################################
//END CUSTOM CODE
//##########################################		
	c.KEYS = {
						DOWN:40,
						LEFT:37,
						RIGHT:39,
						TAB:9,
						UP:38
					 }
//##########################################
//START CUSTOM CODE
//##########################################	
// var tabSelectors = ['div.recent', 'div.popular'];
	var tabSelectors = ['div.recent', 'div.popular', 'div.allitems'];
	
//	function focusTab(recent) {
		function focusTab(x) {
		var ele;
//	if (recent)
		if (x == 'recent')
			ele = $(tabSelectors[0]);
//	else
		else if (x == 'popular')
			ele = $(tabSelectors[1]);
		else
			ele = $(tabSelectors[2]);
		if (ele)
			ele.focus();
	}

//	if (c.data.recentItems.length > 0)
//		c.show_recent = true;
//	c.changePanel = function(panel_name) {
//		if (c.show_recent) {
//			if (panel_name == 'popular')
//				c.show_recent = false;
//		} else {
//			if (panel_name == 'recent')
//				c.show_recent = true;
//		}
//	};

	if (c.data.recentItems.length > 0)
		c.show_recent = true;
	c.changePanel = function(panel_name) {
		if (panel_name == 'recent') {
			c.show_recent = true;
			c.show_popular = false;
			c.show_allitems = false;
		} else if (panel_name == 'popular'){
			c.show_recent = false;
			c.show_popular = true;
			c.show_allitems = false;
		} else if (panel_name == 'allitems'){
			c.show_recent = false;
			c.show_popular = false;
			c.show_allitems = true;
		} else {
			c.show_recent = true;
			c.show_popular = false;
			c.show_allitems = false;
		}
	};

//##########################################
//END CUSTOM CODE
//##########################################	
	
	c.switchTab = function($event, tab) {
		var key = null;
		if (event.keyCode === c.KEYS.LEFT || event.keyCode === c.KEYS.UP)
			key = c.KEYS.LEFT;
		else if (event.keyCode === c.KEYS.RIGHT || event.keyCode === c.KEYS.DOWN)
			key = c.KEYS.RIGHT;
		else if (event.keyCode === c.KEYS.TAB) {
			return;
		}
		if (key === null)
			return;

		$event.preventDefault();
		
//##########################################
//START CUSTOM CODE
//##########################################	
//		c.show_recent = !c.show_recent;
//		focusTab(c.show_recent);
		if (panel_name == 'recent') {
			focusTab('recent');
		} else if (panel_name == 'popular'){
			focusTab('popular');
		} else if (panel_name == 'allitems'){
			focusTab('allitems');		
		}
//##########################################
//END CUSTOM CODE
//##########################################
	}

//##########################################
//START CUSTOM CODE
//##########################################	
//	c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0);
		c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0 && c.data.allItems.length === 0);
//##########################################
//END CUSTOM CODE
//##########################################
	
	function handleTooltip() {
		if(!$scope.isTouchDevice()) {
			$timeout(function() {
				$(".item-card").each(function(index) {
					var itemNameElement = $(this).find(".catalog-item-name");
					if(itemNameElement && itemNameElement[0] && itemNameElement.width() < itemNameElement[0].scrollWidth) {
						$(this).attr('data-toggle','tooltip');
					}
				});
			});
		}
	}
	
	$scope.isTouchDevice = function() {
		return ('ontouchstart' in $window);
	}
	
	$scope.startItemList = function() {
		handleTooltip();
	}
}


Pull the data in the Server Script:

(function() {
	/* populate the 'data' object */
	data.limit = options.limit || 8;
	var recent_by = options.recent_by || 'view';
	var recent = new GlideRecord('sp_log');
	if (recent_by === 'view')
		recent.addEncodedQuery('userDYNAMIC90d1921e5f510100a9ad2572f2b477fe^type=Cat Item View^sys_created_onONThis quarter@javascript&colon;gs.beginningOfThisQuarter()@javascript&colon;gs.endOfThisQuarter()');
	else
		recent.addEncodedQuery('userDYNAMIC90d1921e5f510100a9ad2572f2b477fe^type=Cat Item Request^sys_created_onONThis quarter@javascript&colon;gs.beginningOfThisQuarter()@javascript&colon;gs.endOfThisQuarter()');
	recent.addEncodedQuery('active=true^sys_class_name!=sc_cat_item_wizard^sys_class_name!=sc_cat_item_guide^sys_class_name!=sc_cat_item_content^sys_class_name!=sc_cat_item_producer^categoryISNOTEMPTY^hide_sp!=true');
	recent.orderByDesc('sys_created_on');
	recent.query();
	var recentItems = [];
	var catalogArr = ($sp.getCatalogs().value + "").split(",");
	data.showPrices = $sp.showCatalogPrices();

	while (recent.next() && recentItems.length < data.limit) {
		if (isAlreadyAdded(recent.getValue('id')))
			continue;
		var catalogItemJS = new sn_sc.CatItem(recent.getValue('id'));
		if (!catalogItemJS.canView(gs.isMobile()) || !catalogItemJS.isVisibleServicePortal())
			continue;
		var item = {};
		var catItemDetails = catalogItemJS.getItemSummary(true);
		if(!catItemDetails.visible_standalone)
			continue;
		var inCatalog = false;
		for (var i=0; i<catItemDetails.catalogs.length; i++) {
			if (catalogArr.indexOf(catItemDetails.catalogs[i].sys_id + "") >= 0) {
				inCatalog = true;
				break;
			}
		}
		if (inCatalog) {
			item.name = catItemDetails.name;
			item.short_description = catItemDetails.short_description;
			item.picture = catItemDetails.picture;
			item.price = catItemDetails.price;
			item.sys_id = catItemDetails.sys_id;
			item.hasPrice = item.price != 0;
			item.page = catItemDetails.type == 'order_guide'? 'sc_cat_item_guide' : 'sc_cat_item';
			recentItems.push(item);
		}
	}

	function isAlreadyAdded(catItemSysId) {
		for (var i=0;i<recentItems.length;i++) {
			if (catItemSysId==recentItems[i].sys_id)
				return true;
		}
		return false;
	}

	data.recentItems = recentItems;

	data.popularItems = getPopularItems();

	function getPopularItems() {
		return new SCPopularItems().useOptimisedQuery(gs.getProperty('glide.sc.portal.popular_items.optimize', true) + '' == 'true')
			.baseQuery(options.popular_items_created + '')
			.allowedItems($sp.getAllowedItems())
			.visibleStandalone(true)
			.visibleServicePortal(true)
			.itemsLimit(options.limit || 8)
			.restrictedItemTypes(['sc_cat_item_guide', 'sc_cat_item_wizard', 'sc_cat_item_content', 'sc_cat_item_producer'])
			.itemValidator(function(item, itemDetails) {
			if (!item.canView(gs.isMobile()) || !item.isVisibleServicePortal())
				return false;

			return true;
		})
			.responseObjectFormatter(function(item, itemType, itemCount) {
			return {
				order: 0 - itemCount,
				name: item.name,
				short_description: item.short_description,
				picture: item.picture,
				price: item.price,
				sys_id: item.sys_id,
				hasPrice: item.price != 0,
				page: itemType == 'sc_cat_item_guide' ? 'sc_cat_item_guide' : 'sc_cat_item'
			};
		})
			.generate();
	}

	//##########################################
	//START CUSTOM CODE
	//##########################################	
	var gr = new GlideRecord('sc_cat_item');
	gr.addEncodedQuery('active=true^sys_class_name!=sc_cat_item_wizard^sys_class_name!=sc_cat_item_guide^sys_class_name!=sc_cat_item_content^sys_class_name!=sc_cat_item_producer^categoryISNOTEMPTY^hide_sp!=true');
	gr.orderBy('name');
	gr.query();
	var allItems = [];

	while (gr.next()) {
		var item2 = {};
		$sp.getRecordDisplayValues(item2, gr, 'name,short_description,picture,price,sys_id,tags,sys_class_name,sc_catalogs');
		item2.hasPrice = item2.price != 0;
		item2.page = 'sc_cat_item';
		allItems.push(item2);
	}

	data.allItems = allItems;
	//##########################################
	//END CUSTOM CODE
	//##########################################	
})();



View solution in original post

@rishabh31 

 

 

jaheerhattiwale_2-1685774728246.png

 

 

jaheerhattiwale_0-1685774664826.png

 

This is issue is because the code is copied from the editor in community. Community editor have issue with showing colon symbol.

 

This should fix the recent tab issue.

 

Please mark as correct answer.

 

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

View solution in original post

@rishabh31 And the below updated client script to fix the popular items issue.

 

function($scope, $timeout, $window) {
  /* widget controller */
  var c = this;
console.dir(c.data.allItems);
c.show_recent = false;
//##########################################
//START CUSTOM CODE
//##########################################
c.show_popular = false;
c.show_allitems = false;
//##########################################
//END CUSTOM CODE
//##########################################
c.KEYS = {
DOWN:40,
LEFT:37,
RIGHT:39,
TAB:9,
UP:38
}
//##########################################
//START CUSTOM CODE
//##########################################
// var tabSelectors = ['div.recent', 'div.popular'];
var tabSelectors = ['div.recent', 'div.popular', 'div.allitems'];
 
// function focusTab(recent) {
function focusTab(x) {
var ele;
// if (recent)
if (x == 'recent')
ele = $(tabSelectors[0]);
// else
else if (x == 'popular')
ele = $(tabSelectors[1]);
else
ele = $(tabSelectors[2]);
if (ele)
ele.focus();
}
 
// if (c.data.recentItems.length > 0)
// c.show_recent = true;
// c.changePanel = function(panel_name) {
// if (c.show_recent) {
// if (panel_name == 'popular')
// c.show_recent = false;
// } else {
// if (panel_name == 'recent')
// c.show_recent = true;
// }
// };
 
if (c.data.recentItems.length > 0){
c.show_recent = true;
}
else if(c.data.popularItems.length > 0){
c.show_popular = true;
}
c.changePanel = function(panel_name) {
if (panel_name == 'recent') {
c.show_recent = true;
c.show_popular = false;
c.show_allitems = false;
} else if (panel_name == 'popular'){
c.show_recent = false;
c.show_popular = true;
c.show_allitems = false;
} else if (panel_name == 'allitems'){
c.show_recent = false;
c.show_popular = false;
c.show_allitems = true;
} else {
c.show_recent = true;
c.show_popular = false;
c.show_allitems = false;
}
};
 
//##########################################
//END CUSTOM CODE
//##########################################
 
c.switchTab = function($event, tab) {
var key = null;
if (event.keyCode === c.KEYS.LEFT || event.keyCode === c.KEYS.UP)
key = c.KEYS.LEFT;
else if (event.keyCode === c.KEYS.RIGHT || event.keyCode === c.KEYS.DOWN)
key = c.KEYS.RIGHT;
else if (event.keyCode === c.KEYS.TAB) {
return;
}
if (key === null)
return;
 
$event.preventDefault();
 
//##########################################
//START CUSTOM CODE
//##########################################
// c.show_recent = !c.show_recent;
// focusTab(c.show_recent);
if (panel_name == 'recent') {
focusTab('recent');
} else if (panel_name == 'popular'){
focusTab('popular');
} else if (panel_name == 'allitems'){
focusTab('allitems');
}
//##########################################
//END CUSTOM CODE
//##########################################
}
 
//##########################################
//START CUSTOM CODE
//##########################################
// c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0);
c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0 && c.data.allItems.length === 0);
//##########################################
//END CUSTOM CODE
//##########################################
 
function handleTooltip() {
if(!$scope.isTouchDevice()) {
$timeout(function() {
$(".item-card").each(function(index) {
var itemNameElement = $(this).find(".catalog-item-name");
if(itemNameElement && itemNameElement[0] && itemNameElement.width() < itemNameElement[0].scrollWidth) {
$(this).attr('data-toggle','tooltip');
}
});
});
}
}
 
$scope.isTouchDevice = function() {
return ('ontouchstart' in $window);
}
 
$scope.startItemList = function() {
handleTooltip();
}
}
 
This will show the popular items onload when there are no recent items.
 
Please mark my both answers as correct answer if this solves your issue.
Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

View solution in original post

15 REPLIES 15

@rishabh31 

 

 

jaheerhattiwale_2-1685774728246.png

 

 

jaheerhattiwale_0-1685774664826.png

 

This is issue is because the code is copied from the editor in community. Community editor have issue with showing colon symbol.

 

This should fix the recent tab issue.

 

Please mark as correct answer.

 

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

@rishabh31 And the below updated client script to fix the popular items issue.

 

function($scope, $timeout, $window) {
  /* widget controller */
  var c = this;
console.dir(c.data.allItems);
c.show_recent = false;
//##########################################
//START CUSTOM CODE
//##########################################
c.show_popular = false;
c.show_allitems = false;
//##########################################
//END CUSTOM CODE
//##########################################
c.KEYS = {
DOWN:40,
LEFT:37,
RIGHT:39,
TAB:9,
UP:38
}
//##########################################
//START CUSTOM CODE
//##########################################
// var tabSelectors = ['div.recent', 'div.popular'];
var tabSelectors = ['div.recent', 'div.popular', 'div.allitems'];
 
// function focusTab(recent) {
function focusTab(x) {
var ele;
// if (recent)
if (x == 'recent')
ele = $(tabSelectors[0]);
// else
else if (x == 'popular')
ele = $(tabSelectors[1]);
else
ele = $(tabSelectors[2]);
if (ele)
ele.focus();
}
 
// if (c.data.recentItems.length > 0)
// c.show_recent = true;
// c.changePanel = function(panel_name) {
// if (c.show_recent) {
// if (panel_name == 'popular')
// c.show_recent = false;
// } else {
// if (panel_name == 'recent')
// c.show_recent = true;
// }
// };
 
if (c.data.recentItems.length > 0){
c.show_recent = true;
}
else if(c.data.popularItems.length > 0){
c.show_popular = true;
}
c.changePanel = function(panel_name) {
if (panel_name == 'recent') {
c.show_recent = true;
c.show_popular = false;
c.show_allitems = false;
} else if (panel_name == 'popular'){
c.show_recent = false;
c.show_popular = true;
c.show_allitems = false;
} else if (panel_name == 'allitems'){
c.show_recent = false;
c.show_popular = false;
c.show_allitems = true;
} else {
c.show_recent = true;
c.show_popular = false;
c.show_allitems = false;
}
};
 
//##########################################
//END CUSTOM CODE
//##########################################
 
c.switchTab = function($event, tab) {
var key = null;
if (event.keyCode === c.KEYS.LEFT || event.keyCode === c.KEYS.UP)
key = c.KEYS.LEFT;
else if (event.keyCode === c.KEYS.RIGHT || event.keyCode === c.KEYS.DOWN)
key = c.KEYS.RIGHT;
else if (event.keyCode === c.KEYS.TAB) {
return;
}
if (key === null)
return;
 
$event.preventDefault();
 
//##########################################
//START CUSTOM CODE
//##########################################
// c.show_recent = !c.show_recent;
// focusTab(c.show_recent);
if (panel_name == 'recent') {
focusTab('recent');
} else if (panel_name == 'popular'){
focusTab('popular');
} else if (panel_name == 'allitems'){
focusTab('allitems');
}
//##########################################
//END CUSTOM CODE
//##########################################
}
 
//##########################################
//START CUSTOM CODE
//##########################################
// c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0);
c.hideWidget = (c.data.recentItems.length === 0 && c.data.popularItems.length === 0 && c.data.allItems.length === 0);
//##########################################
//END CUSTOM CODE
//##########################################
 
function handleTooltip() {
if(!$scope.isTouchDevice()) {
$timeout(function() {
$(".item-card").each(function(index) {
var itemNameElement = $(this).find(".catalog-item-name");
if(itemNameElement && itemNameElement[0] && itemNameElement.width() < itemNameElement[0].scrollWidth) {
$(this).attr('data-toggle','tooltip');
}
});
});
}
}
 
$scope.isTouchDevice = function() {
return ('ontouchstart' in $window);
}
 
$scope.startItemList = function() {
handleTooltip();
}
}
 
This will show the popular items onload when there are no recent items.
 
Please mark my both answers as correct answer if this solves your issue.
Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

Hi @jaheerhattiwale Thanks man🙂, It looks good now, ultimately 'Popular Items' also gets fixed per script provided by @sethhumphrey Sir. Because when the page loads/opened then by default 'My Recent Items' tab is already selected and displays all its items, and then later anyhow we must need to select/click on the 'Popular Items' tab which displays all its popular items as expected.

 

Marking your response as helpful and correct!

@rishabh31 When there are no recent items available then it should show the popular items onload. With the current code shared by @sethhumphrey that will not work. So please use the client script i shared and test it.

 

to test that first remove the recent items. for that

go to "sp_log" table and remove the recent items from there, then load page it should show the popular items.

 

So i would suggest to use the client script shared by me it just have 2 lines extra.

Please mark the answer as correct or helpful based on impact
ServiceNow Community Rising Star, Class of 2023

@jaheerhattiwale Thanks for giving useful insights, I am marking your provided Client Script as Correct and helpful. Could you please help me to show where you made changes in the client script please I understand why you made changes but where please show.

 

Thanks