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 You can add the below line after "var c = this" line.

 

c.changePanel('popular')

 

And make c.show_popular to true

c.show_popular = true;

 

jaheerhattiwale_0-1685772069437.png

 

Please mark my answer and @sethhumphrey answer as correct answers 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 for the response. I made modifications as you mentioned in the Client controller Script.

 

But per below screenshot now it's not displaying anything.

rishabh31_0-1685773075763.png

 

@rishabh31 Can you please send screen shot of changed code

 

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

 

@jaheerhattiwale , sure please check below screenshot, I even tried to apply a semicolon to 1st yellow highlighted line, but won't work. Also per my earlier comment 'My Recent Items' tab is not appearing.

 

rishabh31_0-1685773515834.png

 

@rishabh31 Give me 10 minutes i am adding the code to my PDI

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