Custom Field of Catalog Item in Service Catalog Category Table view
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-03-2023 08:34 AM - edited 03-11-2023 02:42 AM
Hi All,
we have a requirement to show a custom field and it's value on the service portal in the Table View of the service catalog. Values of the custom field are not showing up in the list/table.
Back-end view:
SP View:
Steps so far:
- created custom field on the Catalog Item / Table in the back-end. (The custom field is of the Translated Text type)
- cloned the sc_category page to allow customizing
- changed Server Script to this:
function fetchItemDetails(itemRecord, items) {
while (itemRecord.next()) {
var catalogItemJS = new sn_sc.CatItem(itemRecord.getUniqueValue());
if (!catalogItemJS.canView())
continue;
var catItemDetails = catalogItemJS.getItemSummary();
var item = {};
item.name = catItemDetails.name;
item.short_description = catItemDetails.short_description;
item.u_custom_field = catItemDetails.u_custom_field; //<- THIS IS MY CUSTOM FIELD
item.picture = catItemDetails.picture;
item.price = catItemDetails.price;
item.sys_id = catItemDetails.sys_id;
item.hasPrice = catItemDetails.show_price;
item.page = 'sc_cat_item';
item.type = catItemDetails.type;
item.order = catItemDetails.order;
item.sys_class_name = catItemDetails.sys_class_name;
item.titleTag = catItemDetails.name;
if (item.type == 'order_guide') {
item.page = 'sc_cat_item_guide';
} else if (item.type == 'content_item') {
item.content_type = catItemDetails.content_type;
item.url = catItemDetails.url;
if (item.content_type == 'kb') {
item.kb_article = catItemDetails.kb_article;
item.page = 'kb_article';
} else if (item.content_type == 'external') {
item.target = '_blank';
item.titleTag = catItemDetails.name + " ➚";
}
}
items.push(item);
}
}
- and changed HTML code to this:
<div id="tabpanel-grid-{{::data.category_id}}" role="tabpanel" aria-labelledby="{{'tab-grid'}}" ng-if="view == 'grid' && data.items.length > 0">
<table class="table table-striped item-table" aria-label="{{::data.category.title}}" aria-describedby="id-caption-category">
<caption id="id-caption-category"><span class="sr-only">{{::data.category.title}}</span></caption>
<thead>
<tr>
<th id="id-header-item" scope="col" colspan="2">${Item}</th>
<th id="id-header-description" scope="col" colspan="3">${Description}</th>
<th id="id-header-custom_field" scope="col" colspan="3">${Custom Field}</th> //<-THIS IS THE CUSTOM FIELDS TABLE HEADER
<th id="id-header-price" scope="col" ng-if="data.showPrices">${Price}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data.items | orderBy: 'order' | limitTo: data.limit track by item.sys_id" ng-init="startItemList()">
<td id="id-item-{{item.sys_id}}" headers="id-header-item" scope="row" colspan="2">
<a target="{{::item.target}}" ng-href="{{::getItemHREF(item)}}" sn-focus="{{::item.highlight}}" ng-click="onClick($event, item)">
<div>
<img ng-src="{{::item.picture}}?t=small" ng-if="item.picture" alt="" class="m-r-sm m-b-sm item-image pull-left"/>
<span class="catalog-text-wrap catalog-item-name">{{::item.name}}</span>
<span ng-if="item.content_type == 'external'"><span class="sr-only">${External Link}</span> ➚</span>
</div>
</a>
</td>
<td headers="id-header-description id-item-{{item.sys_id}}" class="catalog-text-wrap" colspan="3">{{::item.short_description}}</td>
<td headers="id-header-u_custom_field id-item-{{item.sys_id}}" class="catalog-text-wrap" colspan="3">{{::item.u_custom_field}}</td> //<- THIS IS WERE THE VALUE OF THE CUSTOM FIELD SHOULD SHOW UP
<td headers="id-header-price id-item-{{item.sys_id}}" ng-if="data.showPrices">{{::item.price}}</td>
</tr>
</tbody>
</table>
</div>
Is there anything else I needed to do to make this work? Thank you in advance!
This requirement is the same for the Popular Items View in the service catalog on the Portal.
#tokyo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-09-2023 09:47 AM - edited 03-13-2023 01:23 AM
Hi all,
I solved this myself partially.
item.u_custom_field = itemRecord.getDisplayValue('u_custom_field'); //<- This will show the custom field value from the Catalog Item
I now need to find the way to achieve the same for the Popular Items Table View, because the values don't show up.
Anyone have an idea how to change the below script?
function getPopularItems() {
return new SCPopularItems().useOptimisedQuery(gs.getProperty('glide.sc.portal.popular_items.optimize', true) + '' == 'true')
.baseQuery(options.popular_items_created + '')
.allowedItems(getAllowedCatalogItems())
.visibleStandalone(true)
.visibleServicePortal(true)
.itemsLimit(6)
.restrictedItemTypes('sc_cat_item_guide,sc_cat_item_wizard,sc_cat_item_content,sc_cat_item_producer'.split(','))
.itemValidator(function(item, itemDetails) {
if (!item.canView() || !item.isVisibleServicePortal())
return false;
return true;
})
.responseObjectFormatter(function(item, itemType, itemCount) {
return {
order: 0 - itemCount,
name: item.name,
short_description: item.short_description,
u_custom_field: item.u_custom_field, //<-this doesn't work
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();
}
Thank you in advance!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-11-2024 07:08 PM
Hi,
Could you make it work as you wanted?
Where exactly did you add this line?
item.u_custom_field = itemRecord.getDisplayValue('u_custom_field'); //<- This will show the custom field value from the Catalog Item
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-11-2024 11:49 PM
Hi @jose_quinonez ,
yes I did. You have to change the server script in 4 places within the SC Category Page (in Widget Editor).
1. Under the function fetchItemDetails add:
item.u_custom_field = itemRecord.u_custom_field.getDisplayValue();
2. Under the function getPopularItems you have to add this in each "while" loop
item.u_custom_field = count.cat_item.u_custom_field.getDisplayValue();
3. Under the var Producers you also have to add the same thing once
item.u_custom_field = count.cat_item.u_custom_field.getDisplayValue();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-11-2024 11:50 PM
Here is the complete script for your reference.
(function() {
if (input && input.category_id)
data.category_id = input.category_id;
else
data.category_id = $sp.getParameter("sys_id");
data.error = '';
data.catalog_id = $sp.getParameter("catalog_id") ? $sp.getParameter("catalog_id") + "" : "-1";
var catalogsInPortal = ($sp.getCatalogs().value + "").split(",");
var isCatalogAccessibleViaPortal = data.catalog_id == -1 ? true : false;
catalogsInPortal.forEach(function(catalogSysId) {
if (data.catalog_id == catalogSysId) {
isCatalogAccessibleViaPortal = true;
}
});
data.categorySelected = gs.getMessage('category selected');
if(!isCatalogAccessibleViaPortal) {
data.error = gs.getMessage("You do not have permission to see this catalog");
return;
}
var catalogDisplayValue;
if (data.catalog_id && data.catalog_id !== "-1") {
var catalogObj = new sn_sc.Catalog(data.catalog_id);
if (catalogObj) {
if (!catalogObj.canView()) {
data.error = gs.getMessage("You do not have permission to see this catalog");
return;
}
catalogDisplayValue = catalogObj.getTitle();
}
}
if (options && options.sys_id)
data.category_id = options.sys_id;
data.showPrices = $sp.showCatalogPrices();
data.sc_catalog_page = $sp.getDisplayValue("sc_catalog_page") || "sc_home";
data.sc_category_page = $sp.getDisplayValue("sc_category_page") || "sc_category";
catalogDisplayValue = catalogDisplayValue ? catalogDisplayValue : $sp.getCatalogs().displayValue + "";
var catalogIDs = (data.catalog_id && data.catalog_id !== "-1") ? data.catalog_id : $sp.getCatalogs().value + "";
var catalogArr = catalogDisplayValue.split(",");
var catalogIDArr = catalogIDs.split(",");
data.sc_catalog = catalogArr.length > 1 ? "" : catalogArr[0];
data.show_more = false;
if (GlideStringUtil.nil(data.category_id)) {
data.items = getPopularItems();
data.show_popular_item = true;
data.all_catalog_msg = (($sp.getCatalogs().value + "").split(",")).length > 1 ? gs.getMessage("All Catalogs") : "";
data.all_cat_msg = gs.getMessage("All Categories");
data.category = {title: gs.getMessage("Popular Items"),
description: ''};
return;
}
data.show_popular_item = false;
// Does user have permission to see this category?
var categoryId = '' + data.category_id;
var categoryJS = new sn_sc.CatCategory(categoryId);
if (!categoryJS.canView()) {
data.error = gs.getMessage("You do not have permission to see this category");
return;
}
data.category = {title: categoryJS.getTitle(),
description: categoryJS.getDescription()};
var catalog = $sp.getCatalogs().value;
data.items = [];
var itemsInPage = options.limit_item || 999;
data.limit = itemsInPage;
if (input && input.new_limit)
data.limit = input.new_limit;
if (input && input.items) {
data.items = input.items.slice();//Copy the input array
}
if (input && input.startWindow) {
data.endWindow = input.endWindow;
}
else {
data.startWindow = 0;
data.endWindow = 0;
}
while (data.items.length < data.limit + 1) {
data.startWindow = data.endWindow;
data.endWindow = data.endWindow + itemsInPage;
var itemGR = queryItems(catalog, categoryId, data.startWindow, data.endWindow);
if (!itemGR.hasNext())
break;
fetchItemDetails(itemGR, data.items);
}
if (data.items.length > data.limit)
data.show_more = true;
data.more_msg = gs.getMessage(" Showing {0} items", data.limit);
data.categories = [];
while(categoryJS && categoryJS.getParent()) {
var parentId = categoryJS.getParent();
categoryJS = new sn_sc.CatCategory(parentId);
var category = {
label: categoryJS.getTitle(),
url: '?id='+data.sc_category_page+'&sys_id=' + parentId
};
data.categories.unshift(category);
}
data.all_catalog_msg = (($sp.getCatalogs().value + "").split(",")).length > 1 ? gs.getMessage("All Catalogs") : "";
function fetchItemDetails(itemRecord, items) {
while (itemRecord.next()) {
var catalogItemJS = new sn_sc.CatItem(itemRecord.getUniqueValue());
if (!catalogItemJS.canView())
continue;
var catItemDetails = catalogItemJS.getItemSummary(true);
var item = {};
item.u_custom_field = itemRecord.u_custom_field.getDisplayValue(); //<-custom row
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 = catItemDetails.show_price;
item.page = 'sc_cat_item';
item.type = catItemDetails.type;
item.order = catItemDetails.order;
item.sys_class_name = catItemDetails.sys_class_name;
item.titleTag = catItemDetails.name;
if (item.type == 'order_guide') {
item.page = 'sc_cat_item_guide';
} else if (item.type == 'content_item') {
item.content_type = catItemDetails.content_type;
item.url = catItemDetails.url;
if (item.content_type == 'kb') {
item.kb_article = catItemDetails.kb_article;
item.page = 'kb_article';
} else if (item.content_type == 'external') {
item.target = '_blank';
item.titleTag = catItemDetails.name + " ➚";
}
}
items.push(item);
}
}
function queryItems(catalog, categoryId, startWindow, endWindow) {
var scRecord = new sn_sc.CatalogSearch().search(catalog, categoryId, '', false, options.show_items_from_child != 'true');
scRecord.addQuery('sys_class_name', 'NOT IN', 'sc_cat_item_wizard');
scRecord.addEncodedQuery('hide_sp=false^ORhide_spISEMPTY^visible_standalone=true');
scRecord.chooseWindow(startWindow, endWindow);
scRecord.orderBy('order');
scRecord.orderBy('name');
scRecord.query();
return scRecord;
}
function getPopularItems (itemRecord, items) {
var catalog = $sp.getValue('sc_catalog');
var limit = 106;
var items = [];
var itemRecord = [];
var count = new GlideAggregate('sc_req_item');
count.addAggregate('COUNT','cat_item');
count.groupBy('cat_item');
count.addQuery('cat_item.sys_class_name', 'NOT IN', 'sc_cat_item_guide,sc_cat_item_wizard,sc_cat_item_content');
count.addQuery('cat_item.sc_catalogs', 'IN', catalog);
count.addEncodedQuery('cat_item.hide_sp=false^ORcat_item.hide_spISEMPTY');
count.orderByAggregate('COUNT', 'cat_item');
count.query();
while (count.next() && items.length < limit) {
var catalogItemJS = new sn_sc.CatItem(count.cat_item.sys_id.getValue());
if (!catalogItemJS.canView() || !catalogItemJS.isVisibleServicePortal())
continue;
var item = {};
var catItemDetails = catalogItemJS.getItemSummary();
item.order = 0 - count.getAggregate('COUNT', 'cat_item');
item.name = catItemDetails.name;
item.short_description = catItemDetails.short_description;
item.u_custom_field = count.cat_item.u_custom_field.getDisplayValue(); //<-custom row
item.picture = catItemDetails.picture;
item.price = catItemDetails.price;
item.sys_id = catItemDetails.sys_id;
item.hasPrice = item.price != 0;
item.page = 'sc_cat_item';
items.push(item);
}
while (itemRecord.next()) {
var catalogItemJS = new sn_sc.CatItem(itemRecord.getUniqueValue());
if (!catalogItemJS.canView())
continue;
var catItemDetails = catalogItemJS.getItemSummary();
var item = {};
item.name = catItemDetails.name;
item.short_description = catItemDetails.short_description;
item.u_custom_field = count.cat_item.u_custom_field.getDisplayValue(); //<-custom row
item.picture = catItemDetails.picture;
item.price = catItemDetails.price;
item.sys_id = catItemDetails.sys_id;
item.hasPrice = item.price != 0;
item.page = 'sc_cat_item';
items.push(item);
}
var producers = 0;
count = new GlideAggregate('sc_item_produced_record');
count.addQuery('producer.sc_catalogs', 'IN', catalog);
count.addEncodedQuery('producer.hide_sp=false^ORproducer.hide_spISEMPTY');
count.addAggregate('COUNT', 'producer');
count.groupBy('producer');
count.orderByAggregate('COUNT', 'producer');
count.query();
while (count.next() && producers < limit) {
var catalogItemJS = new sn_sc.CatItem(count.getValue('producer'));
if (!catalogItemJS.canView() || !catalogItemJS.isVisibleServicePortal())
continue;
var catItemDetails = catalogItemJS.getItemSummary();
var item = {};
item.order = 0 - count.getAggregate('COUNT', 'producer');
item.name = catItemDetails.name;
item.short_description = catItemDetails.short_description;
item.u_custom_field = count.cat_item.u_custom_field.getDisplayValue(); //<-custom row
item.picture = catItemDetails.picture;
item.price = catItemDetails.price;
item.hasPrice = item.price != 0;
item.sys_id = catItemDetails.sys_id;
item.page = 'sc_cat_item';
items.push(item);
producers++;
}
return items;
}
function getAllowedCatalogItems () {
var allowedItems = [];
catalogIDArr.forEach(function(catalogID) {
var catalogObj = new sn_sc.Catalog(catalogID);
var catItemIds = catalogObj.getCatalogItemIds();
for(var i=0; i<catItemIds.length; i++) {
if (!allowedItems.includes(catItemIds[i]))
allowedItems.push(catItemIds[i]);
}
});
return allowedItems;
}
})();