I’ve had this site here for a while and I’ve never taken the time to actually blog. Better now than never, so here’s my first post! Let me start off by giving you a bit of my background.
For the past 6 months I have been working with the ServiceNow platform, a SAAS product for managing corporate data and streamlining business processes. There are numerous little challenges that I am faced with throughout a day and sometimes I land on some unexpected solutions.
For example, when viewing an Incident as a fulfiller, there is an option to attach a related article to the additional comments section of the ticket for the end user.
When the ‘Attach’ button is pressed, a url pattern is generated from the KnowledgeAjaxSNC script to include a sys_id reference to the article. The link is wraped in [code] block with an href that points to the kb_view page using the sys_id to reference the document.
There are a couple problems with this. One is that referencing the id does not take you to the most recent article version if there are updated publishings. The other problem is that the article is displayed in the kb_view page, which is not attractive to users and directs them away from the service portal.
I didn’t want to modify the KnowledgeAjaxSNC because of its core purpose and risk to future upgrades, so I created an onChange client script instead to listen for instances of the url being added to the comment field.
Within my code, I put a listener onto the comments field to watch for text from the URL referencing the kb_view.do page. The URL test is pointed to the end of the string where the sys_id would be displayed by providing a count of 21 characters. I add another 53 to get 32 characters, the length of the sys_id.
var kbId = comment.substring( comment.lastIndexOf('kb_view.do?sys_kb_id=') + 21, comment.lastIndexOf('kb_view.do?sys_kb_id=') + 53 ); var beforeText = comment.substr(0, comment.indexOf('kb_view.do?sys_kb_id=')); var afterText = comment.substring( comment.lastIndexOf('kb_view.do?sys_kb_id=') + 53 );
By getting the substring of index 0 from the same string, I can get all the text before this and get the text immediately after the sys_id and put them into beforeText and afterText variables. I have essentially taken the url and split it into multiple variables to use throughout my script.
From here, I query the knowledge base using the sys_id stripped from the original url. I then use this result to fetch the article number and perform a second query and order it descending from the date it was created. I limit the query to the top result and use this to construct the new url, effectively ensuring the latest version is always referenced.
// query to retrieve KB article data var gr = new GlideRecord('kb_knowledge'); gr.addQuery('sys_id', kbId); gr.orderByDesc('sys_created_on'); gr.setLimit(1); gr.query(); gr.next(); // KB Number var kbNumber = gr.getValue('number'); // KB Title var kbTitle = gr.getValue('short_description'); // KB Knowledge Base var knowledgeBase = gr.getValue('kb_knowledge_base');
In the last step, I replace the value in the comments field with the text I stripped before the url reference, then re-construct the url with reference to the service portal knowledge base page, and provide a reference the article by its number rather than sys_id so it will always direct users to the most recent version.
g_form.setValue("comments", newValue.replace(comment, beforeText + pageURL +"?id=kb_article&sysparm_article="+ kbNumber + afterText));
The new url ends up looking like this:
When the user clicks the link they are directed to the most recent article version without leaving the service portal, which effectively provides a better experience to the end user.