Service Portal -How Do i Code individual Catalogs

Blaze2
Kilo Guru

I am working on developing the Service Portal and would like assistance in what should be done as far as the catalogs go.

I have downloaded the HR Service Catalog for CMS which provides a Service Catalog.

That being said, when I load the hrsp page, The service Catalog has all catalog items, including those that do not pertain to HR.

find_real_file.png

Under Sp_config > Widget Editor > Sc Category Page this is the script that I have

(function() {

  data.category_id = $sp.getParameter("sys_id");

  if (options && options.sys_id)

  data.category_id = options.sys_id;

  data.sc_catalog_page = $sp.getDisplayValue("sc_catalog_page") || "sc_home";

  // Does user have permission to see this category?

  if (!$sp.canReadRecord("sc_category", data.category_id)) {

  data.error = "You do not have permission to see this category";

  return;

  }

  var cat = new GlideRecord('sc_category');

  cat.get(data.category_id);

  data.category = cat.getDisplayValue('title');

  var items = data.items = [];

  var sc = new GlideRecord('sc_cat_item_category');

  if (data.category_id)

  sc.addQuery('sc_category', data.category_id);

  sc.addQuery('sc_cat_item.active',true);

  sc.addQuery('sc_cat_item.sys_class_name', 'NOT IN', 'sc_cat_item_wizard,sc_cat_item_content');

  sc.orderBy('sc_cat_item.order');

  sc.orderBy('sc_cat_item.name');

  sc.query();

  while (sc.next()) {

  // Does user have permission to see this item?

  if (!$sp.canReadRecord("sc_cat_item", sc.sc_cat_item.sys_id.getDisplayValue()))

  continue;

  var item = {};

  var gr = new GlideRecord('sc_cat_item');

  gr.get(sc.sc_cat_item);

  $sp.getRecordDisplayValues(item, gr, 'name,short_description,picture,price,sys_id');

  item.sys_class_name = sc.sc_cat_item.sys_class_name + "";

  item.page = 'sc_cat_item';

  if (item.sys_class_name == 'sc_cat_item_guide')

  item.page = 'sc_cat_item_guide';

  items.push(item);

  }

})()

How would I modify the scripts into a new widget to do just this?

1 ACCEPTED SOLUTION

Blaze2
Kilo Guru

Harish,



Yes actually.



I Cloned the SC Categories Widget


HTML


<div ng-class="::{'hidden-xs' : options.hide_xs}" class="panel panel-{{::options.color}} b">


  <div class="panel-heading">


      <h4 class="panel-title">${CHANGE THE NAME OF THE CATEGORY HERE IE "FACILITIES CATEGORIES"}</h4>


          <span ng-if="::options.glyph">


              <fa name="{{::options.glyph}}" />


          </span>{{::options.title}}</h4>


  </div>


  <div class="list-group no-radius alt">


      <sp-category-list-item ng-repeat="cat in data.categories"


                                                    category="cat"


                                                    omit-badges="options.omit_badges"


                                                    page="options.page"


                                                    level="0"></sp-category-list-item>


  </div>


</div>



Server Script Changed just copy and paste this.



// populate the 'data' object


data.categories = [];


options.category_layout = options.category_layout || "Nested";




if (options.page) {


var pageGR = new GlideRecord("sp_page");


options.page = (pageGR.get(options.page)) ? pageGR.getValue("id") : null;


} else {


options.page = 'sc_category';


}




if (input && input.action === "retrieve_nested_categories") {


var childCategoriesGR = buildSubcategoryGR(input.parentID)


data.subcategories = retrieveCategoriesFromGR(childCategoriesGR);


return;


}




var sc = new GlideRecord('sc_category');


sc.addQuery('sys_class_name', 'sc_category');


sc.addActiveQuery();


sc.orderBy('title');


data.sc_catalog = $sp.getValue('sc_catalog');


if (data.sc_catalog)


sc.addQuery('sc_catalog', data.sc_catalog);


if (options.category_layout === "Nested")


sc.addQuery('parent', '');


sc.query();


data.categories = retrieveCategoriesFromGR(sc);




// If the selected category is a subcategory, we need to


// open all it's parent categories


var selectedCategory = new GlideRecord("sc_category");


var categoryID = $sp.getParameter("sys_id");


if (!categoryID || !selectedCategory.get(categoryID))


return;




var parentArr;


if (options.category_layout !== "Nested" || !selectedCategory.parent)


parentArr = data.categories;


else


parentArr = openParent(selectedCategory.getElement("parent").getRefRecord());




var selectedCategoryItem = findElementBySysID(parentArr, selectedCategory.getUniqueValue());


if (selectedCategoryItem)


selectedCategoryItem.selected = true;




function openParent(gr) {


var catItem;



if (!gr.parent) {


catItem = findElementBySysID(data.categories, gr.getUniqueValue());


} else {


var parentCategoryArr = openParent(gr.getElement("parent").getRefRecord());


catItem = findElementBySysID(parentCategoryArr, gr.getUniqueValue());


}



if (!catItem)


return [];



var subcategoryGR = buildSubcategoryGR(catItem.sys_id);


catItem.subcategories = retrieveCategoriesFromGR(subcategoryGR);


catItem.showSubcategories = true;


return catItem.subcategories;


}




function findElementBySysID(arr, id) {


var foundElements = arr.filter(function(item) {


return item.sys_id === id;


});



return (foundElements.length > 0) ? foundElements[0] : null;


}




function retrieveCategoriesFromGR(gr) {


var categories = []


while (gr.next()) {


var category = retrieveCategoryFromGR(gr);


if (category)


categories.push(category);


}



return categories;


}




function retrieveCategoryFromGR(gr) {


if (!$sp.canReadRecord("sc_category", gr.getUniqueValue()))


return null;




var isParentCategory = checkIsParentCategory(gr);



if (options.check_can_view != true && options.check_can_view != "true") {


// use GlideAggregate by way of GlideRecordCounter, doesn't check canView on each item


var count = new GlideRecordCounter('sc_cat_item_category');


prepQuery(count, gr.getUniqueValue());


var item_count = count.getCount();


if (item_count > 0 || (options.category_layout === "Nested" && isParentCategory)) {


var cat = {};


cat.title = gr.title.getDisplayValue();


cat.sys_id = gr.getUniqueValue();


cat.count = item_count;


cat.parent = gr.parent.getDisplayValue();


if (options.category_layout === "Nested")


cat.isParentCategory = isParentCategory;


return cat;


}


}




if (options.check_can_view == true || options.check_can_view == "true") {


// use GlideRecord, checking canView on each item


var itemCat = new GlideRecord('sc_cat_item_category');


prepQuery(itemCat, gr.getUniqueValue());


itemCat.query();


var validatedCount = 0;


var checked = 0;


while (itemCat.next()) {


checked++;


if ($sp.canReadRecord("sc_cat_item", itemCat.sc_cat_item))


validatedCount++;




// if user can't see the first 50 items in this category, give up


if (validatedCount == 0 && checked == 50)


break;




// if omitting badges, and if we found one, work is done


if (validatedCount > 0 && options.omit_badges)


break;


}




if (validatedCount > 0 || (options.category_layout === "Nested" && isParentCategory)) {


var cat = {};


cat.title = gr.title.getDisplayValue();


cat.sys_id = gr.getUniqueValue();


cat.count = validatedCount;


cat.parent = gr.parent.getDisplayValue();


if (options.category_layout === "Nested")


cat.isParentCategory = isParentCategory;


return cat;


}


}



return null;


}




function prepQuery(gr, scUniqueValue) {


gr.addQuery('sc_category', scUniqueValue);


gr.addQuery('sc_cat_item.active', true);


gr.addQuery('sc_cat_item.visible_standalone', true);


gr.addQuery('sc_cat_item.sys_class_name', 'NOT IN', 'sc_cat_item_wizard');


}




function checkIsParentCategory(cat) {


var count = new GlideRecordCounter('sc_category');


count.addQuery('active', true);


count.addQuery('parent', cat.getUniqueValue());


return count.getCount() > 0;


}




function buildSubcategoryGR(parentID) {


var subcategoryGR = new GlideRecord("sc_category");


subcategoryGR.addActiveQuery();


subcategoryGR.orderBy('title');


var sc_catalog = $sp.getValue('sc_catalog');


if (sc_catalog)


subcategoryGR.addQuery('sc_catalog', sc_catalog);


subcategoryGR.addQuery('parent', parentID);


subcategoryGR.query();


return subcategoryGR;


}






Going forward, you just have to clone the change the name of the widget and title of the categories in the HTML.
Then add the widget to your form


find_real_file.png


View solution in original post

4 REPLIES 4

rohantyagi
ServiceNow Employee
ServiceNow Employee

Did you try widget editor? Widget editor


More documentation here: Widgets


Yes,



The code is from the widget editor, my question is what would I need to edit in order to make it function for my needs.


Inactive_Use167
Mega Expert

Hi,



I am facing the same issue. Did you get a solution for the issue.



Thanks



Harish Gubba


Blaze2
Kilo Guru

Harish,



Yes actually.



I Cloned the SC Categories Widget


HTML


<div ng-class="::{'hidden-xs' : options.hide_xs}" class="panel panel-{{::options.color}} b">


  <div class="panel-heading">


      <h4 class="panel-title">${CHANGE THE NAME OF THE CATEGORY HERE IE "FACILITIES CATEGORIES"}</h4>


          <span ng-if="::options.glyph">


              <fa name="{{::options.glyph}}" />


          </span>{{::options.title}}</h4>


  </div>


  <div class="list-group no-radius alt">


      <sp-category-list-item ng-repeat="cat in data.categories"


                                                    category="cat"


                                                    omit-badges="options.omit_badges"


                                                    page="options.page"


                                                    level="0"></sp-category-list-item>


  </div>


</div>



Server Script Changed just copy and paste this.



// populate the 'data' object


data.categories = [];


options.category_layout = options.category_layout || "Nested";




if (options.page) {


var pageGR = new GlideRecord("sp_page");


options.page = (pageGR.get(options.page)) ? pageGR.getValue("id") : null;


} else {


options.page = 'sc_category';


}




if (input && input.action === "retrieve_nested_categories") {


var childCategoriesGR = buildSubcategoryGR(input.parentID)


data.subcategories = retrieveCategoriesFromGR(childCategoriesGR);


return;


}




var sc = new GlideRecord('sc_category');


sc.addQuery('sys_class_name', 'sc_category');


sc.addActiveQuery();


sc.orderBy('title');


data.sc_catalog = $sp.getValue('sc_catalog');


if (data.sc_catalog)


sc.addQuery('sc_catalog', data.sc_catalog);


if (options.category_layout === "Nested")


sc.addQuery('parent', '');


sc.query();


data.categories = retrieveCategoriesFromGR(sc);




// If the selected category is a subcategory, we need to


// open all it's parent categories


var selectedCategory = new GlideRecord("sc_category");


var categoryID = $sp.getParameter("sys_id");


if (!categoryID || !selectedCategory.get(categoryID))


return;




var parentArr;


if (options.category_layout !== "Nested" || !selectedCategory.parent)


parentArr = data.categories;


else


parentArr = openParent(selectedCategory.getElement("parent").getRefRecord());




var selectedCategoryItem = findElementBySysID(parentArr, selectedCategory.getUniqueValue());


if (selectedCategoryItem)


selectedCategoryItem.selected = true;




function openParent(gr) {


var catItem;



if (!gr.parent) {


catItem = findElementBySysID(data.categories, gr.getUniqueValue());


} else {


var parentCategoryArr = openParent(gr.getElement("parent").getRefRecord());


catItem = findElementBySysID(parentCategoryArr, gr.getUniqueValue());


}



if (!catItem)


return [];



var subcategoryGR = buildSubcategoryGR(catItem.sys_id);


catItem.subcategories = retrieveCategoriesFromGR(subcategoryGR);


catItem.showSubcategories = true;


return catItem.subcategories;


}




function findElementBySysID(arr, id) {


var foundElements = arr.filter(function(item) {


return item.sys_id === id;


});



return (foundElements.length > 0) ? foundElements[0] : null;


}




function retrieveCategoriesFromGR(gr) {


var categories = []


while (gr.next()) {


var category = retrieveCategoryFromGR(gr);


if (category)


categories.push(category);


}



return categories;


}




function retrieveCategoryFromGR(gr) {


if (!$sp.canReadRecord("sc_category", gr.getUniqueValue()))


return null;




var isParentCategory = checkIsParentCategory(gr);



if (options.check_can_view != true && options.check_can_view != "true") {


// use GlideAggregate by way of GlideRecordCounter, doesn't check canView on each item


var count = new GlideRecordCounter('sc_cat_item_category');


prepQuery(count, gr.getUniqueValue());


var item_count = count.getCount();


if (item_count > 0 || (options.category_layout === "Nested" && isParentCategory)) {


var cat = {};


cat.title = gr.title.getDisplayValue();


cat.sys_id = gr.getUniqueValue();


cat.count = item_count;


cat.parent = gr.parent.getDisplayValue();


if (options.category_layout === "Nested")


cat.isParentCategory = isParentCategory;


return cat;


}


}




if (options.check_can_view == true || options.check_can_view == "true") {


// use GlideRecord, checking canView on each item


var itemCat = new GlideRecord('sc_cat_item_category');


prepQuery(itemCat, gr.getUniqueValue());


itemCat.query();


var validatedCount = 0;


var checked = 0;


while (itemCat.next()) {


checked++;


if ($sp.canReadRecord("sc_cat_item", itemCat.sc_cat_item))


validatedCount++;




// if user can't see the first 50 items in this category, give up


if (validatedCount == 0 && checked == 50)


break;




// if omitting badges, and if we found one, work is done


if (validatedCount > 0 && options.omit_badges)


break;


}




if (validatedCount > 0 || (options.category_layout === "Nested" && isParentCategory)) {


var cat = {};


cat.title = gr.title.getDisplayValue();


cat.sys_id = gr.getUniqueValue();


cat.count = validatedCount;


cat.parent = gr.parent.getDisplayValue();


if (options.category_layout === "Nested")


cat.isParentCategory = isParentCategory;


return cat;


}


}



return null;


}




function prepQuery(gr, scUniqueValue) {


gr.addQuery('sc_category', scUniqueValue);


gr.addQuery('sc_cat_item.active', true);


gr.addQuery('sc_cat_item.visible_standalone', true);


gr.addQuery('sc_cat_item.sys_class_name', 'NOT IN', 'sc_cat_item_wizard');


}




function checkIsParentCategory(cat) {


var count = new GlideRecordCounter('sc_category');


count.addQuery('active', true);


count.addQuery('parent', cat.getUniqueValue());


return count.getCount() > 0;


}




function buildSubcategoryGR(parentID) {


var subcategoryGR = new GlideRecord("sc_category");


subcategoryGR.addActiveQuery();


subcategoryGR.orderBy('title');


var sc_catalog = $sp.getValue('sc_catalog');


if (sc_catalog)


subcategoryGR.addQuery('sc_catalog', sc_catalog);


subcategoryGR.addQuery('parent', parentID);


subcategoryGR.query();


return subcategoryGR;


}






Going forward, you just have to clone the change the name of the widget and title of the categories in the HTML.
Then add the widget to your form


find_real_file.png