- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-25-2021 01:46 AM
Hello All, I am new to SP and Angular. Can you please help me with a widget.
Here on search option i only get Item name, But instead we need Item name + short description
this is my Client code & below that is HTML code, Can you please suggest me what changes are required here to get Item name + short description
Service Portal Search : [ We need Item name + Short description ]
Client Code:
function ($http, $filter, $location,spAriaUtil, $window, $scope, spAriaFocusManager, snAnalytics) {
var c = this;
c.options.glyph = c.options.glyph || 'search';
c.options.title = c.options.title || c.data.searchMsg;
c.options.color = c.options.color || "default";
c.searchTerm = c.data.q;
c.searchQuery = "";
c.pageID = $scope.page && $scope.page.id;
c.showSuggestions = c.data.searchTypeBehavior === "suggestions" && c.data.isSuggestionsEnabled === "true";
c.suggestionsLimit = c.options.limit > 0 ? c.options.limit : "";
c.latitude = null;
c.longitude = null;
c.isGlideSignalsLoaded = false;
c.isLocationTrackerDisabled = c.data.isLocationTrackerDisabled === "true";
c.sendAnalytics = function(type){
var payload= {};
payload.name = "Initiate Search";
payload.data = {};
payload.data["Keyword"] = (type == 'User Entered' ? c.searchTerm : c.searchQuery);
payload.data["Type"] = type;
payload.data["Page ID"] = c.pageID;
snAnalytics.addEvent(payload);
};
function initializeGlideSignals() {
if (!c.isLocationTrackerDisabled && window.GlideSignals.init) {
window.GlideSignals.init();
}
if (window.GlideSignals.trackEvent) {
c.isGlideSignalsLoaded = true;
}
}
if (window.GlideSignals)
initializeGlideSignals();
c.trackSuggestionsRenderedEvent = function(searchQueryLength, responseTimeInMilliSeconds){
if(c.isGlideSignalsLoaded)
GlideSignals.trackEvent('SEARCH_SUGGESTIONS_RENDERED', GlideSignals.priority.INFO,
{'applicationId': c.data.portalID,
'searchQueryLength': searchQueryLength,
'totalSuggestionsCount': c.totalSuggestionsCount,
'userHistorySuggestionsCount' : c.userHistorySuggestionsCount,
'instanceHistorySuggestionsCount' : c.instanceHistorySuggestionsCount,
'responseTime': responseTimeInMilliSeconds+' ms'
});
};
c.trackSearchClickedEvent = function(model){
if(c.isGlideSignalsLoaded) {
if(c.showSuggestions) {
GlideSignals.trackEvent('SEARCH_SUGGESTION_CLICKED', GlideSignals.priority.INFO,
{'applicationId': c.data.portalID,
'searchQueryLength' : c.searchQuery.length,
'suggestionClickedLength': model.name.length,
'totalSuggestionsCount': c.totalSuggestionsCount,
'suggestionClickedType': model.type,
'aggregatedClickIndex': getSearchItemIndex(c.searchItems, model),
'userHistorySuggestionsCount' : c.userHistorySuggestionsCount,
'instanceHistorySuggestionsCount' : c.instanceHistorySuggestionsCount,
'suggestionsDisplayLimit': c.suggestionsLimit,
'relativeClickIndex': getRelativeSearchItemIndex(c.searchItems, model)
})
}
else {
GlideSignals.trackEvent('SEARCH_TYPEAHEAD_CLICKED', GlideSignals.priority.INFO,
{'applicationId': c.data.portalID,
'searchQueryLength' : c.searchQuery.length,
'typeaheadClickedLength': model.name && model.name.length,
'resultSysId': model.sys_id,
'clickIndex': model.query_location != null ? model.query_location : getSearchItemIndex(c.searchItems, model),
'sourceId': model.type != null ? model.type : model.table,
'typeaheadDisplayLimit': c.options.limit
})
}
}
}
c.onSelect = function($item, $model, $label) {
c.sendAnalytics(c.showSuggestions ? "Suggestions" : "Typeahead");
c.searchTerm = ""; // prevents unexpected result if user quickly clicks search button after selecting
if (c.showSuggestions)
$item.url = "?id=search&q="+encodeURIComponent($item.name);
if(!$item.url || $item.url === "")
return;
if (!c.showSuggestions) {
var index = $(".typeahead-popup li.active").data('index');
c.trackSearchResultClicked(index + 1);
}
c.trackSearchClickedEvent($model);
if ($item.target)
window.open($item.url, $item.target);
else {
var newUrl = $location.url($item.url);
spAriaFocusManager.navigateToLink(newUrl.url());
}
};
function recordSuggestionsCount(){
c.instanceHistorySuggestionsCount = 0;
c.userHistorySuggestionsCount = 0;
c.searchItems.forEach(function(item){
return item.type === 'INSTANCE_HISTORY' ? c.instanceHistorySuggestionsCount++ : c.userHistorySuggestionsCount++;
});
}
function getSearchItemIndex(items, targetItem) {
return (items || []).findIndex(function(item) {
return item.name === targetItem.name;
});
}
function getRelativeSearchItemIndex(items, targetItem) {
var groupedItems = (items || []).filter(function(item) {
return item.type === targetItem.type;
});
return getSearchItemIndex(groupedItems, targetItem);
}
c.getSearchSuggestions = function(query) {
c.searchQuery = query;
if ($location.search().q == c.searchQuery)
return;
var payload = {
params: {
"sysparm_term" : c.searchQuery,
"sysparm_sp_portal_id": c.data.portalID,
"sysparm_suggestions_limit": c.suggestionsLimit,
"sysparm_search_sources": c.data.searchSourceSysIds || ""
},
headers : {'Accept' : 'application/json'}
};
var requestTimeStamp = new Date().getTime();
return $http.get("/api/now/search/sp_suggestions", payload).then(function(response){
var responseTimeStamp = new Date().getTime();
var responseTimeInMilliSeconds = (responseTimeStamp - requestTimeStamp);
var result = response.data.result;
c.totalSuggestionsCount = result != null ? result.entries.length : 0;
sendLiveMessage(c.totalSuggestionsCount);
c.searchItems = result.entries.map(function(item) {
item.query = getQueryToHighlight(item, c.searchQuery);
item.glyph = getIcon(item.type);
item.term = item.name;
return item;
});
recordSuggestionsCount();
c.trackSuggestionsRenderedEvent(query.length, responseTimeInMilliSeconds);
return c.searchItems;
});
};
function getSearchSources(results, c) {
var sources = {};
c.data.searchSources.map(function(key) {
sources[key] = 0;
});
results.map(function(item) {
if(sources[item.type])
sources[item.type]++;
else
sources[item.type] = 1;
});
var searchSources = [];
Object.keys(sources).map(function(key) {
var source_id = c.data.searchSourceConfiguration[key] ? c.data.searchSourceConfiguration[key].sys_id : key;
searchSources.push({
source_id: source_id,
number_of_results: sources[key]
});
});
return searchSources;
}
function getSearchResultsSignals(results, c) {
return results.map(function(item) {
var recordId = item.sys_id;
var tableName = item.table;
return {
record_id: recordId,
table_name: tableName
};
});
}
function setUserLocationCoords(cb) {
var onSuccess = function(pos) {
return cb({
latitude: pos.coords.latitude,
longitude: pos.coords.longitude
})
};
var onError = function() {
return cb({
latitude: null,
longitude: null
});
};
return window.navigator.geolocation.getCurrentPosition(onSuccess, onError, {
enableHighAccuracy: true
});
}
if(!c.isLocationTrackerDisabled) {
setUserLocationCoords(function(coords) {
c.latitude = coords.latitude;
c.longitude = coords.longitude;
});
}
function getResultDescription(result){
var description = null;
if(result.name != null)
description = result.name;
else if(result.primary != null)
description = result.primary;
else if(result.sec_title != null)
description = result.sec_title;
return description;
}
c.trackSearchResultClicked = function(rank) {
if (!rank || rank < 1) return ;
var query = c.latestQuery;
var results = _.get(c.data, 'results', []);
var result = results[rank-1];
var sourceTable = result.table != null ? result.table : null;
var payloadObject = {
action: "GlideSPSearchAnalyticsUpdateRank",
payload: {
query: query,
portal_id: this.data.portalID,
page_id: this.pageID,
results_per_source: getSearchSources(results, this),
search_results: getSearchResultsSignals(results, this),
refinement_occurred: false,
browser_info: $window.navigator.userAgent,
location: {
latitude: c.latitude,
longitude: c.longitude
},
result_event_sys_id : result.sys_id,
label_description : getResultDescription(result),
source_table: sourceTable,
signal_type: "CLICK",
signal_value: rank
}
};
$window.spSearchAnalytics = {
query: query
};
c.server.get(payloadObject);
}
c.getResults = function(query) {
c.searchQuery = query;
var payload = {
"query": c.searchQuery,
"portal": c.data.portalID,
"page": c.pageID,
"source": c.data.searchSources,
"include_facets": false,
"searchType": "typeahead"
};
if (c.options.limit || c.options.limit == 0)
payload.count = c.options.limit;
return $http.post("/api/now/sp/search", payload).then(function(response) {
// Prevents typeahead from displaying suggestions if queries from page and input are the same
if ($location.search().q == c.searchQuery)
return;
var result = response.data.result;
var resultCount = result != null ? result.results.length : 0
sendLiveMessage(resultCount);
c.data.results = result.results;
c.latestQuery = c.searchQuery;
c.searchItems = result.results.map(function(item) {
var config = c.data.searchSourceConfiguration[item.__search_source_id__];
if (!item.url && config.linkToPage) {
item.url = "?id=" + config.linkToPage;
if (item.sys_id)
item.url += "&sys_id=" + item.sys_id;
if (item.table)
item.url += "&table=" + item.table
}
if (config.type == "ADVANCED") {
item.templateID = config.template;
} else {
item.glyph = config.glyph;
}
return item;
});
if (c.searchItems.length == 0)
c.searchItems = [{"primary": c.data.noResultsFoundMsg}];
return c.searchItems;
});
}
c.searchType = c.data.searchType;
$scope.$on('$locationChangeSuccess', onLocationChangeSuccess);
function onLocationChangeSuccess(event, newUrl, oldUrl) {
if(searchSourceChanged(newUrl, oldUrl)) {
var newUrlParams = newUrl.match(/t=.+/);
if(!newUrlParams) {
c.searchType = null;
} else {
c.searchType = newUrlParams[0].split("&")[0].substring(2);
}
}
}
function searchSourceChanged(newUrl, oldUrl) {
var newUrlParams = newUrl.match(/t=.+/),
oldUrlParams = oldUrl.match(/t=.+/);
if(!newUrlParams && !oldUrlParams) {
return false;
}
if((!newUrlParams && oldUrlParams) || (newUrlParams && !oldUrlParams)) {
return true;
}
return newUrlParams[0].split("&")[0] !== oldUrlParams[0].split("&")[0];
}
c.submitSearch = function() {
c.sendAnalytics("User Entered");
var shouldReloadPage = c.data.refreshPageOnSearch && $location.search().id === 'search';
if (c.searchTerm) {
var newUrl = $location.search({
id: 'search',
spa: '1',
t: c.searchType,
q: c.searchTerm
});
if (shouldReloadPage)
$scope.$emit("sp.page.reload");
spAriaFocusManager.navigateToLink(newUrl.url());
//Pass the current page ID to search page for Search Analytics
$window.spSearchAnalytics = {
page_id: c.pageID
};
}
}
function sendLiveMessage(resultCount) {
spAriaUtil.sendLiveMessage(resultCount + " " +
c.data.resultMsg + " " +
(resultCount > 0 ? ' ' + c.data.navigationMsg : ''));
}
function getIcon(itemType) {
return itemType === "INSTANCE_HISTORY" ? 'search' : 'clock-o';
}
function getQueryToHighlight(item, query) {
return item.type === "INSTANCE_HISTORY" ? item.name.substring(query.length) : query;
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-25-2021 06:33 AM
I made changes with OOTB. What I did is update the typeahead template of Catalogs Search Source of /sp Service Portal
Code:
<!-- prefer item picture to item icon, prefer item icon to default icon -->
<div onclick="window.GlideWebAnalytics.trackEvent('Service Catalog', 'Catalog Search Type Ahead', 'Item Clicked')">
<i ng-if="match.model.picture" class="ta-img" style="background-image:url('{{match.model.picture}}?t=small')"></i>
<i ng-if="!match.model.picture && match.model.icon" class="ta-icon" style="background-image:url('{{match.model.icon}}'); width:16px; height:16px"></i>
<i ng-if="!match.model.picture && !match.model.icon" class="ta-icon fa fa-{{match.model.default_icon}}"></i>
<span ng-bind-html="match.label | uibTypeaheadHighlight:query"></span>
<p>
<span ng-bind-html="match.model.short_description | uibTypeaheadHighlight:query"></span>
</p>
<strong ng-if="match.model.type == 'sc_content' && match.model.content_type == 'external'">âžš</strong>
</div>
Result:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-25-2021 07:48 AM
Thank You replying me, I'll check this
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-25-2021 08:00 AM
This code did not work, Below is the code whicch is written in my HTML
My Code
<div id="homepage-search" class="hidden-xs wrapper-xl">
<div class="wrapper-xl">
<h2 class="text-center text-4x m-b-lg sp-tagline-color" ng-bind="options.title"></h2>
<div ng-if="options.short_description" class="text-center h4 m-b-lg sp-tagline-color" ng-bind="options.short_description"></div>
<sp-widget widget="data.typeAheadSearch" />
</div>
</div>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-25-2021 09:41 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-25-2021 10:35 AM
Thank You So Much ..
It worked .....
Thanks A Lot Again Carlos for helping me ..