Create incident button in footer of every knowledge article in esc portal

Kishor O
Tera Sage

How to build create incident button in the footer of every KA in esc portal?

Once we create an incident from a particular KA incident comment and short description should be updated with the Knowledge article short description (KA name).

1 ACCEPTED SOLUTION

ChrisBurks
Mega Sage

@Kishor O  - Explanation is within the code comments

 

Widget build:

HTML Template

 

<div>
  <!-- anchor tag styled as button using ng-href to assign link -->
  <a ng-href="{{c.redirect}}" class="btn btn-default col-xs-12 col-sm-12 col-md-12 m-b-lg">Create an Incident</a>
</div>

 

 

Server Script

 

(function() {

	//if client sends a get request use the details to get the title
	if(input && input.action == 'GET ARTICLE TITLE'){
		var kaGr = new GlideRecord('kb_knowledge');
		if(input.is_article_number){
			if(kaGr.get('number', input.ka_id))
				data.title = kaGr.short_description.toString();
		}else{
			if(kaGr.get(input.ka_id))
				data.title = kaGr.short_description.toString();
		}
	}
})();

 

 

Client controller

 

api.controller = function($scope, $location) {

    var c = this;
    //use $location to grab parameters to place on redirect url
    var urlParams = $location.search();

    // get the value of sysparm_article or sys_id
    var ka_id = urlParams.sysparm_article || urlParams.sys_id;

    //check which param exists
    var isArticleNumber = urlParams.hasOwnProperty('sysparm_article') ? 'number' : 'sys_id';

    c.redirect = "";

    if (ka_id) {
        c.server.get({
            "action": "GET ARTICLE TITLE",
            "ka_id": ka_id,
            "is_article_number": isArticleNumber
        }).then(function(resp) {
            c.title = resp.data.title;

		//build url that points to the catalog item page including params with KA details
    	//start with question mark in case the page this widget is rendered in different portals
        //?id=sc_cat_item&sys_id=SYS_ID_TO_YOUR_RECORD_PRODUCER_HERE&ka_title=TITLE OF ARTICLE HERE
          c.redirect = "?id=sc_cat_item&sys_id=3f1dd0320a0a0b99000a53f7604a2ef9&ka_title=" + c.title;
        })
    }
);

 

 

Catalog Client Script (UI Type set to All or Mobile/Service Portal

function onLoad() {
    //get the url params
	try{
    var urlParams = decodeURIComponent(location.search);
	}catch(err){
		console.error("err", err)
	}
    //unlike working with AngularJS we need to work for getting each param
    //split the url string into an array by "&"
    var urlArr = urlParams.split("&")

    //array should look something like this ['?id=sc_cat_item','sys_id=SYS_ID_TO_YOUR_RECORD_PRODUCER_HERE','ka_title=TITLE OF ARTICLE HERE']
    //now we filter it down to just get the ka_title parameter and value and assign to the short_descrition variable
    g_form.setValue('short_description', urlArr.reduce(filterForTitle, ""))

	//callback function for reduce array method
    function filterForTitle(str, param) {
        //split each iteration by = 
        var paramValueArray = param.split("=");

        //assign str if param is the same as ka_title else return empty string
        str = paramValueArray[0] == 'ka_title' ? paramValueArray[1] : "";

        return str;
    }

}

 

Example

create_incident_prepopulate.gif

View solution in original post

15 REPLIES 15

@ChrisBurks  when I click create incident button it should redirect me to create incident record producer and it should populate KA short description to record producer variable. Then user fills other details in required variable and submits the form. Can we do it? Is it possible requirement?

@Kishor O  yes, what you described is possible and can be implemented in many different ways. A very basic way to do this is refactor the widget to build a url adding a url parameter that contains the KA along with the URL parameters of the record producer page and desired record producer. Then use that URL to set an href on an anchor tag or use javascript location or window.location to do the redirect.

On the record producer there needs to be variable that maps to the short description and you'll need to write an onLoad catalog client script to grab the url parameter that holds the KA name. Then have the script place that name into the variable using the g_form method.

ChrisBurks
Mega Sage

@Kishor O  - Explanation is within the code comments

 

Widget build:

HTML Template

 

<div>
  <!-- anchor tag styled as button using ng-href to assign link -->
  <a ng-href="{{c.redirect}}" class="btn btn-default col-xs-12 col-sm-12 col-md-12 m-b-lg">Create an Incident</a>
</div>

 

 

Server Script

 

(function() {

	//if client sends a get request use the details to get the title
	if(input && input.action == 'GET ARTICLE TITLE'){
		var kaGr = new GlideRecord('kb_knowledge');
		if(input.is_article_number){
			if(kaGr.get('number', input.ka_id))
				data.title = kaGr.short_description.toString();
		}else{
			if(kaGr.get(input.ka_id))
				data.title = kaGr.short_description.toString();
		}
	}
})();

 

 

Client controller

 

api.controller = function($scope, $location) {

    var c = this;
    //use $location to grab parameters to place on redirect url
    var urlParams = $location.search();

    // get the value of sysparm_article or sys_id
    var ka_id = urlParams.sysparm_article || urlParams.sys_id;

    //check which param exists
    var isArticleNumber = urlParams.hasOwnProperty('sysparm_article') ? 'number' : 'sys_id';

    c.redirect = "";

    if (ka_id) {
        c.server.get({
            "action": "GET ARTICLE TITLE",
            "ka_id": ka_id,
            "is_article_number": isArticleNumber
        }).then(function(resp) {
            c.title = resp.data.title;

		//build url that points to the catalog item page including params with KA details
    	//start with question mark in case the page this widget is rendered in different portals
        //?id=sc_cat_item&sys_id=SYS_ID_TO_YOUR_RECORD_PRODUCER_HERE&ka_title=TITLE OF ARTICLE HERE
          c.redirect = "?id=sc_cat_item&sys_id=3f1dd0320a0a0b99000a53f7604a2ef9&ka_title=" + c.title;
        })
    }
);

 

 

Catalog Client Script (UI Type set to All or Mobile/Service Portal

function onLoad() {
    //get the url params
	try{
    var urlParams = decodeURIComponent(location.search);
	}catch(err){
		console.error("err", err)
	}
    //unlike working with AngularJS we need to work for getting each param
    //split the url string into an array by "&"
    var urlArr = urlParams.split("&")

    //array should look something like this ['?id=sc_cat_item','sys_id=SYS_ID_TO_YOUR_RECORD_PRODUCER_HERE','ka_title=TITLE OF ARTICLE HERE']
    //now we filter it down to just get the ka_title parameter and value and assign to the short_descrition variable
    g_form.setValue('short_description', urlArr.reduce(filterForTitle, ""))

	//callback function for reduce array method
    function filterForTitle(str, param) {
        //split each iteration by = 
        var paramValueArray = param.split("=");

        //assign str if param is the same as ka_title else return empty string
        str = paramValueArray[0] == 'ka_title' ? paramValueArray[1] : "";

        return str;
    }

}

 

Example

create_incident_prepopulate.gif

@ChrisBurks 

 

KishorO_0-1700676752302.png

*In the above image  we can see

The button which I created is not aligning with OOB knowledge article helpful widget.

How can I make it aligned like (helpful and rate this article in one line and create incident in other line) 

Add some CSS styling to the HTML markup. Either use some of the SN Bootstrap class utilities or make your own.

For example if you have something like the following:

<div>
  <button class="btn btn-primary pull-right m-b" ng-click="createIncident()">Create Incident</button>
</div>

The "pull-right" utility is taking that element out of the normal flow of the DOM. One way of getting the surrounding HTML to behave as if that section took up the whole space is adding a "clearfix" class on its parent element like so:

<div class="clearfix">
  <button class="btn btn-primary pull-right m-b" ng-click="createIncident()">Create Incident</button>
</div>

 

This will apply styling to the parent and keep its original structure as a block element. You can test this in action in the "Inspect" of your browser's development tools

 

use_clearfix.gif