<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marek Krčma</title>
    <description>The latest articles on DEV Community by Marek Krčma (@mkrcma).</description>
    <link>https://dev.to/mkrcma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1002659%2Fccc61ac8-ef15-4282-be03-df9bb959a858.png</url>
      <title>DEV Community: Marek Krčma</title>
      <link>https://dev.to/mkrcma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mkrcma"/>
    <language>en</language>
    <item>
      <title>ServiceNow: reference vs. primitive data types</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Thu, 23 Mar 2023 21:25:33 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-reference-vs-primitive-data-types-2bjp</link>
      <guid>https://dev.to/mkrcma/servicenow-reference-vs-primitive-data-types-2bjp</guid>
      <description>&lt;p&gt;Following code shows the correct and bad way how to work with field values using GlideRecord. It simply puts values into an array. Take time and go through the code, all explained after in detail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;prbArray_CORRECT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;prbArray_WRONG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;grPrb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlideRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;problem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// grPrb is iterable collection, it moves to the next element with each iteration&lt;/span&gt;
    &lt;span class="c1"&gt;// grPrb.number is object GlideElement, not string/integer/date&lt;/span&gt;
    &lt;span class="c1"&gt;// reference is pushed to array&lt;/span&gt;
    &lt;span class="c1"&gt;// Wrong way&lt;/span&gt;
    &lt;span class="nx"&gt;prbArray_WRONG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Correct way&lt;/span&gt;
    &lt;span class="c1"&gt;// grPrb.getValue('number') returns string&lt;/span&gt;
    &lt;span class="c1"&gt;// The same can be done by explicit retype:&lt;/span&gt;
    &lt;span class="c1"&gt;// grPrb.number + '';&lt;/span&gt;
    &lt;span class="c1"&gt;// grPrb.number.toString();&lt;/span&gt;
    &lt;span class="c1"&gt;// grPrb.number.getValue();&lt;/span&gt;
    &lt;span class="nx"&gt;prbArray_CORRECT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prbArray_CORRECT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Correct output: PRB0040003,PRB0040004,PRB0040005,PRB0040006,PRB0040007&lt;/span&gt;

&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prbArray_WRONG&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Unexpected output: PRB0040007,PRB0040007,PRB0040007,PRB0040007,PRB0040007&lt;/span&gt;
&lt;span class="c1"&gt;// Array prbArray_WRONG contains elements with the same value&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The issue is &lt;code&gt;prbArray_WRONG&lt;/code&gt; which stores unexpected values (all values are the same: PRB0040007,PRB0040007,PRB0040007,...) even though there were simply saved values of field &lt;code&gt;grPrb.number&lt;/code&gt; for active problems. To tell what is happening, it is important to explain two principles. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first&lt;/strong&gt; is related to JavaScript and &lt;strong&gt;the second&lt;/strong&gt; is related to ServiceNow. &lt;/p&gt;

&lt;h3&gt;
  
  
  Object vs. primitive data type
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;First principle:&lt;/strong&gt; when assigning value to a variable, &lt;strong&gt;the type of value matters&lt;/strong&gt; in JavaScript. Primitive types (string, integers, boolean, null) are &lt;strong&gt;assigned directly as value&lt;/strong&gt;, no confusion here. But object types are &lt;strong&gt;assigned as reference&lt;/strong&gt; and are treated more as the pointer somewhere into memory where the object is stored. This is an important difference because it has consequences when working with objects. &lt;/p&gt;

&lt;h3&gt;
  
  
  ServiceNow GlideElement
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The second principle&lt;/strong&gt; is related to ServiceNow and is also a tricky one. Which type of value would you expect in &lt;code&gt;grPrb.number&lt;/code&gt;? Let's try this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Is grPrb.number a string?&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;grPrb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlideRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;problem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Returns "object"&lt;/span&gt;
    &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grPrb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Returns "GlideElement"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45od4jmiphiippva5cck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45od4jmiphiippva5cck.png" alt="ServiceNow GlideElement"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, right, ehm it is object GlideElement. And this is the confusing part, because logically I would expect string (primitive type) in grPrb.number. &lt;/p&gt;

&lt;p&gt;When connecting these two principles, it explains what is happening: &lt;br&gt;
1) Putting &lt;code&gt;grPrb.number&lt;/code&gt; into array means there is put reference to GlideElement object in each iteration instead of actual value of field&lt;br&gt;
2) When the records' iteration is done, &lt;strong&gt;all array elements reference to the last GlideElement&lt;/strong&gt;. Because "grPrb" is iterable &amp;gt; the current pointer is the last record at the end of iteration &amp;gt; all elements in the array now point to this last record. &lt;/p&gt;

&lt;p&gt;Confusing? Yes, it is not easy to get it and explain it. Important is to keep in mind that &lt;strong&gt;whenever you do something with GlideRecord fields, just retype the value to the string or any other primitive data type&lt;/strong&gt; to avoid unexpected behavior. GlideElement provides a set of methods for dealing with fields and their values (see &lt;a href="https://docs.servicenow.com/en-US/bundle/utah-api-reference/page/app-store/dev_portal/API_reference/GlideElement_global/concept/c_GlideElementAPI.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;). When you convert into the primitive data type, it will be handled as value (not as object reference) in the array element/variable. It will save you headache and hours of debugging. As mentioned in the script, you can retype it in the following ways: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;var prbNumber = grPrb.number + "";&lt;/code&gt;&lt;br&gt;
&lt;code&gt;var prbNumber = grPrb.number.toString();&lt;/code&gt;&lt;br&gt;
&lt;code&gt;var prbNumber = grPrb.number.getValue();&lt;/code&gt;&lt;br&gt;
&lt;code&gt;var prbNumber = grPrb.getValue('number');&lt;/code&gt;&lt;br&gt;
&lt;code&gt;var recordSysID = grPrb.getUniqueValue();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you need to pass a record &lt;em&gt;sys_id&lt;/em&gt; as an event parameter or a parameter in script include, you can use &lt;code&gt;getUniqueValue()&lt;/code&gt;  &lt;a href="https://docs.servicenow.com/bundle/utah-api-reference/page/app-store/dev_portal/API_reference/GlideRecord/concept/c_GlideRecordAPI.html" rel="noopener noreferrer"&gt;GlideRecord&lt;/a&gt; method. &lt;/p&gt;




&lt;p&gt;No matter if you work with field number, description, priority, sys_id the behavior is the same: GlideElement represents the field and if you need a field value, you need to use &lt;code&gt;getValue()&lt;/code&gt;, &lt;code&gt;toString()&lt;/code&gt; methods or explicitly retype it.&lt;/p&gt;

&lt;p&gt;If you want to go deeper (and I recommend it) and understand the differences of how the primitive and reference data types work in JavaScript, check these posts. This principle is general and is fundamental for object-oriented programming languages. It is more technical but interesting to understand how computer works with memory:&lt;br&gt;
&lt;a href="https://www.freecodecamp.org/news/primitive-vs-reference-data-types-in-javascript/" rel="noopener noreferrer"&gt;https://www.freecodecamp.org/news/primitive-vs-reference-data-types-in-javascript/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ui.dev/primitive-vs-reference-values-in-javascript" rel="noopener noreferrer"&gt;https://ui.dev/primitive-vs-reference-values-in-javascript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>glideelement</category>
      <category>gliderecord</category>
      <category>servicenow</category>
    </item>
    <item>
      <title>ServiceNow: related list conditions in reports</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Tue, 14 Mar 2023 20:53:08 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-related-list-conditions-in-reports-oai</link>
      <guid>https://dev.to/mkrcma/servicenow-related-list-conditions-in-reports-oai</guid>
      <description>&lt;p&gt;Reporting in ServiceNow has some less known features and one of them are &lt;strong&gt;related list conditions&lt;/strong&gt;. Think about these use cases how would you achieve:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;1) Show users without any role&lt;/code&gt;&lt;br&gt;
&lt;code&gt;2) Show Problems with more than 5 incidents&lt;/code&gt;&lt;br&gt;
&lt;code&gt;3) Show analysts who did not touch any incident in last 6 months&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You would probably start with Group by aggregation and ended up with scripted workaround (no way). For the first case "Show users without any role" (this is quite useful list for platform admins) we actually want to technically search for no data (without role). So group by would not help us. Glory to the related list conditions!&lt;/p&gt;

&lt;p&gt;You start build report (&lt;code&gt;Reports &amp;gt; Create New&lt;/code&gt;) and related list conditions are just under the &lt;em&gt;Conditions&lt;/em&gt; in report builder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iZ3k0ce3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nv5tw144ahlheijdr9kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iZ3k0ce3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nv5tw144ahlheijdr9kq.png" alt="Related list conditions" width="789" height="848"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most complicated thing is to find the correct relationship from the dropdown box. It is based on all relations on the reported table, so there can be many relationships. You also choose the quantity. It means you tell the machine how many records in the related list are applicable for your query. You will mostly use &lt;code&gt;equal&lt;/code&gt;, &lt;code&gt;greater than&lt;/code&gt;, &lt;code&gt;less than&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LwpzymBI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds66v2i4917up3umpx56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LwpzymBI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds66v2i4917up3umpx56.png" alt="Related list conditions: quantity" width="432" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, we can also apply conditions on related list records (the third use case). The limitation is that you can use only one related list in the conditions, it is not possible to combine it.&lt;/p&gt;

&lt;p&gt;No one built report right the first time, so take time, don't stress and play with it. Let's describe 3 scenarios mentioned in the beginning.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Show users without any role
&lt;/h3&gt;

&lt;p&gt;Target table is &lt;code&gt;sys_user&lt;/code&gt; and select &lt;code&gt;Roles&lt;/code&gt; as related list. Quantity condition is &lt;code&gt;None&lt;/code&gt; (no records = no roles).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M3lzyXat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m6w94v5qm99ypugpay14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M3lzyXat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m6w94v5qm99ypugpay14.png" alt="Related list conditions: Show users without any role" width="880" height="788"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quick verification, click &lt;code&gt;Run&lt;/code&gt; on the report:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EJbKVUHQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bnn8u2cdojftpykhbfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EJbKVUHQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bnn8u2cdojftpykhbfe.png" alt="Run report" width="638" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and open any record, you should see no records in &lt;code&gt;Roles&lt;/code&gt; related list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OpNFUKah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsyc711worp19fjuyiao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OpNFUKah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsyc711worp19fjuyiao.png" alt="Related list conditions: Show users without any role" width="668" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Show Problems with more than 5 incidents
&lt;/h3&gt;

&lt;p&gt;Target table is &lt;code&gt;problem&lt;/code&gt;, related list is &lt;code&gt;Incident-&amp;gt;Problem&lt;/code&gt; and quantity &lt;code&gt;Greater than 5&lt;/code&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7J-I81jI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu66t8a73hg1g44567yc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7J-I81jI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu66t8a73hg1g44567yc.png" alt="Related list conditions: Show Problems with more than 5 incidents" width="880" height="777"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click &lt;code&gt;Run&lt;/code&gt; and open any record, check the related list &lt;code&gt;Incidents&lt;/code&gt;. It will have more than 5 incidents:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0s-uPXpI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8f4bko4u4fx5pbzvttz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0s-uPXpI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8f4bko4u4fx5pbzvttz.png" alt="Related list conditions: Show Problems with more than 5 incidents" width="321" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Show analysts who did not touch any incident in last 6 months
&lt;/h3&gt;

&lt;p&gt;I have moral problem with this kind of reports but why not for the use case :) &lt;/p&gt;

&lt;p&gt;Target table is &lt;code&gt;sys_user&lt;/code&gt;, apply conditions &lt;code&gt;active=true&lt;/code&gt; and roles has &lt;code&gt;itil&lt;/code&gt;. In related list select &lt;code&gt;Incident-&amp;gt;Assigned to&lt;/code&gt;, quantity is &lt;code&gt;None&lt;/code&gt; and condition is &lt;code&gt;Updated on Last 6 months&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Let's explain it a bit more, I need to tell machine this fact: show me users who have &lt;strong&gt;0 records&lt;/strong&gt; in related list &lt;code&gt;Incident⇾Assigned to&lt;/code&gt; while applying condition that incidents were updated in &lt;em&gt;last 6 months&lt;/em&gt;. With quantity &lt;code&gt;None&lt;/code&gt; it is exactly what I need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--atL6H47K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qyxdd2xl95v4c2q6a8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--atL6H47K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qyxdd2xl95v4c2q6a8p.png" alt="Show analysts who did not touch any incident in last 6 month" width="880" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quick verification, click &lt;code&gt;Run&lt;/code&gt; on the report and open any user, you should see only incidents which were updated 6 months ago and before that. (You will probably need to add related list "Incident⇾Assigned to" on user form to check the results.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xjGBgEJD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3n2z68cxyxjjb0fw7qou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xjGBgEJD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3n2z68cxyxjjb0fw7qou.png" alt="Related list conditions" width="697" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The magic here is the condition &lt;code&gt;Updated on Last 6 months&lt;/code&gt; because we can apply conditions on related list records too! This gives us a powerful tool for many reporting use cases. &lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;It might take some time on large data sets to get report results because technically related list conditions must do some extra queries. I am not sure how exactly is this done in the backend, if there is somehow one join SQL, or it goes one record by one and does separate queries. &lt;/p&gt;

&lt;p&gt;When you build report always start on a small subset (like incidents created on this week). On the other hand, do not be afraid, ServiceNow performance is scalable and in the worst case you will block just your session.&lt;/p&gt;

&lt;p&gt;I naively thought that all 3 use cases would be easily done by &lt;code&gt;Create your report with Analytics Q&amp;amp;A&lt;/code&gt; feature directly in Report designer which utilizes natural language understanding. The questions are well-structured, ServiceNow language model could understand it, but no result. I can see some space for improvement.&lt;/p&gt;




&lt;p&gt;What is the biggest power of report designer? The best thing is that report designer is available for users with itil role. Anyone with itil role can make and save the reports. There is literally just a small step to inform itil people about the report designer power and which use cases they can do by themselves. No admin needed, no expensive consultancy services. Just spread the information.&lt;/p&gt;

</description>
      <category>servicenow</category>
      <category>report</category>
      <category>dashboard</category>
    </item>
    <item>
      <title>ServiceNow: activating ITSM dashboards with Performance analytics</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Thu, 09 Mar 2023 23:13:30 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-activating-performance-analytics-itsm-dashboards-3bif</link>
      <guid>https://dev.to/mkrcma/servicenow-activating-performance-analytics-itsm-dashboards-3bif</guid>
      <description>&lt;h2&gt;
  
  
  What is Performance Analytics in ServiceNow
&lt;/h2&gt;

&lt;p&gt;Performance Analytics is a solution for collecting and analyzing data. It provides tracking, aggregating, and visualizing key performance indicators over time, so everyone involved knows how the process is performing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuq7rclo9lx5fzy3ja91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuq7rclo9lx5fzy3ja91.png" alt="ServiceNow Performance analytics" width="800" height="836"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It has a rich sets of possibilities how to configure indicators (KPI) and how to visualize. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F432zwtnxx8i92mys429z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F432zwtnxx8i92mys429z.png" alt="ServiceNow Performance analytics" width="800" height="724"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ITSM processes in ServiceNow
&lt;/h2&gt;

&lt;p&gt;The aim of ITSM is to manage access and availability of services, fulfill service requests coming from end-users, provide single cloud-based interface.&lt;/p&gt;

&lt;p&gt;The key ITSM processes/pillars are: &lt;strong&gt;Incident management&lt;/strong&gt; &lt;br&gt;
restores services and resolve issues quickly. &lt;strong&gt;Problem management&lt;/strong&gt; identifies the root-cause of an issue in the IT service, reported as occurring incidents. &lt;strong&gt;Change and release management&lt;/strong&gt; prioritizing, approval, scheduling, and execution of changes to IT systems (software, hardware).&lt;br&gt;
&lt;strong&gt;Request management&lt;/strong&gt; addresses service requests from customers, employees. &lt;strong&gt;Knowledge management&lt;/strong&gt; enables the sharing of information in knowledge bases. &lt;strong&gt;Configuration management&lt;/strong&gt; builds logical representations of assets, services, and the relationships between them.&lt;/p&gt;

&lt;p&gt;To be able to measure the process performance we have &lt;code&gt;Performance Analytics (PA)&lt;/code&gt; which collects and visualizes data in the dashboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  PA for ITSM and available content packs
&lt;/h2&gt;

&lt;p&gt;Each ITSM process has a content pack which is a collection of predefined dashboards, visualizations, indicators (KPI). There are &lt;code&gt;Performance Analytics - Content Pack - Change Management&lt;/code&gt;, &lt;code&gt;Performance Analytics - Content Pack - Problem Management&lt;/code&gt;,  &lt;code&gt;Performance Analytics - Content Pack - Incident SLA Management&lt;/code&gt;, etc. It is distributed by plugins, and it is possible to install as a package. &lt;/p&gt;

&lt;p&gt;You get a nice solution for process monitoring with low effort. If your ServiceNow implementation is out-of-the-box, it is easy to use: install the plugin and activate the collection jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to activate ITSM Dashboards
&lt;/h2&gt;

&lt;p&gt;(Proceed these steps as admin user)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Plugin activations:&lt;/strong&gt; &lt;br&gt;
&lt;code&gt;Content Pack - ITSM Dashboards (com.snc.pa.itsm_dashboards)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxeqlv63v74bfur73t63c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxeqlv63v74bfur73t63c.png" alt="Performance analytics ITSM Dashboards" width="800" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Set dashboard permissions:&lt;/strong&gt;&lt;br&gt;
After plugin activation, navigate to:&lt;br&gt;
&lt;code&gt;Performance Analytics &amp;gt; Dashboards&lt;/code&gt;&lt;br&gt;
and search for:&lt;br&gt;
&lt;code&gt;IT Executive dashboard&lt;/code&gt;&lt;br&gt;
&lt;code&gt;IT Manager dashboard&lt;/code&gt;&lt;br&gt;
&lt;code&gt;IT Agent dashboard&lt;/code&gt;&lt;br&gt;
Follow the steps to activate and set sharing options for these three dashboards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb9016q49rxbn9vl5y95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb9016q49rxbn9vl5y95.png" alt="Dashboard properties" width="475" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set &lt;code&gt;Active&lt;/code&gt; and &lt;code&gt;Owner&lt;/code&gt; and &lt;code&gt;Update&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgtv96tavk4vt7q74tgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgtv96tavk4vt7q74tgk.png" alt="Activate dashboard" width="800" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to the dashboard and on right-top use &lt;code&gt;Sharing&lt;/code&gt;. Add groups, users, roles who should be able to access the dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9hwd97j8txfzhdc5cxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9hwd97j8txfzhdc5cxs.png" alt="Share dashboard" width="351" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you set up the dashboards, but one more step is needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Enable performance analytics data collection jobs&lt;/strong&gt;&lt;br&gt;
Performance Analytics does not use real-time data, but it stores data in dedicated data tables. It allows using complex aggregation operations and stores lots of data with minimum impact on instance performance. By default, the collection jobs are inactive, so admin should activate it.&lt;/p&gt;

&lt;p&gt;There are two types of PA collections job &lt;code&gt;historic / daily&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Historic&lt;/code&gt;: it is usually run only once when plugin is activated, and it collects historical scores in defined period. You can find them easily: name contains &lt;code&gt;historic&lt;/code&gt; and Run is &lt;code&gt;On Demand&lt;/code&gt;. The job is not run automatically, admin should perform it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35ra15lqbhbddb7lo3zy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F35ra15lqbhbddb7lo3zy.png" alt="Performance analytics - historic collection job" width="703" height="327"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;It is important to note: running a historic collection job will rewrite existing scores. So it is recommended to run it just once.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Daily&lt;/code&gt;: it collects data on a daily basis and needs to be activated by admin (it is inactive after plugin activation).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjn47sk2w2yw9isyo8p58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjn47sk2w2yw9isyo8p58.png" alt="Performance analytics - daily collection job" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Performance Analytics &amp;gt; Data Collector &amp;gt; Jobs&lt;/code&gt;&lt;br&gt;
and look for ITSM related daily collection jobs. For example: &lt;code&gt;[PA Incident] Daily Data Collection&lt;/code&gt;, &lt;code&gt;[PA Incident SLA] Daily Data Collection&lt;/code&gt; for Incident, similar for Problem management &lt;code&gt;[PA Problem] Daily Data Collection&lt;/code&gt;, &lt;code&gt;[PA KM] Daily Data Collection&lt;/code&gt; etc. for other processes. Open collection job and, check &lt;code&gt;Active&lt;/code&gt;, &lt;code&gt;Run as&lt;/code&gt; must be existing admin user and click &lt;code&gt;Execute Now&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Job Logs&lt;/code&gt; related list you will see data collection status and if any error occurs with details. Now it will automatically run daily at specified time and will collect data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwyhztfdvsjtuzcqzo70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwyhztfdvsjtuzcqzo70.png" alt="Performance analytics collection job" width="800" height="831"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do the same for other ITSM related collection jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  IT Executive dashboard
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv7mgywvs7pt4jx95o6i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv7mgywvs7pt4jx95o6i.png" alt="IT Executive dashboard" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It provides a high-level view across all ITSM processes and is intended to be used on executive level. There are KPIs like: % of new critical incidents, Active Breached SLAs Today, Average reassignment of open incidents, % of overdue requested items. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gb5w0o4tbpf1pmg9pph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gb5w0o4tbpf1pmg9pph.png" alt="IT Executive dashboard" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  IT Manager dashboard
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9qdevzgeqoz2vgotylz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9qdevzgeqoz2vgotylz.png" alt="IT Manager dashboard" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The aim is to present data on a group manager level. It shows important metrics on a daily and weekly basis for incidents, problems, and requests. Metrics are filterable by group. KPIs are like: Customer satisfaction score, % Breached SLAs, Open / New / Closed workload, Workload backlog growth, Mean-time to resolve, Planned changes in next 7 days, Average cost per resolved incident, Average cost per resolved request.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8c8vwsob34qxajq8knbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8c8vwsob34qxajq8knbz.png" alt="IT Manager dashboard" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaaye4z58u3dcd2f63if.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhaaye4z58u3dcd2f63if.png" alt="IT Manager dashboard" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  IT Agent dashboard
&lt;/h3&gt;

&lt;p&gt;It shows open incidents, problems, and requests that belong to you and your assignment groups. It is intended to be used on an operational daily basis by agents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x63oel1s5is4brqe8f1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x63oel1s5is4brqe8f1.png" alt="IT Agent dashboard" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  ServiceNow documentation
&lt;/h4&gt;

&lt;p&gt;Check ServiceNow documentation for more details: &lt;a href="https://docs.servicenow.com/bundle/utah-it-service-management/page/use/dashboards/application-content-packs/itsm-dashboards-content-pack.html" rel="noopener noreferrer"&gt;ServiceNow documentation&lt;/a&gt;&lt;br&gt;
Statement: Tested on Tokyo ServiceNow release, used with demo data on personal development instance. &lt;/p&gt;




&lt;p&gt;Almost every process has its own Performance analytics content pack with predefined dashboards, metrics, visualizations (e.g. ITSM, CSM, GRC, SecOps, ITOM, ...) and they are ready to be used with minimum effort. When the process is customized like any out-of-the-box field is changed, modified states it might be needed to change it also in PA, because content packs are built on out-of-the-box process implementation. &lt;/p&gt;

&lt;p&gt;You can also create your own metrics, however it is a paid feature and some additional license might be required. Sometimes clients do not even know they can do it or what added value Performance analytics would bring. If you are a client, so reach your ServiceNow contact and check what you pay for and open your Service Management potential with PA :) &lt;/p&gt;

</description>
      <category>marketing</category>
      <category>startup</category>
      <category>productivity</category>
      <category>networking</category>
    </item>
    <item>
      <title>ServiceNow: 1 thing for safer GlideRecord scripts</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Sat, 04 Mar 2023 19:59:44 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-1-thing-for-safer-gliderecord-scripts-le2</link>
      <guid>https://dev.to/mkrcma/servicenow-1-thing-for-safer-gliderecord-scripts-le2</guid>
      <description>&lt;p&gt;Many task-based tables use parent-child relationship and run logic: to do something on child tasks, or roll-up something into parent. Imagine you do some stuff on child incidents like state change, update work notes (by business rule, event, flow, flow action) where parent is some sys_id.&lt;/p&gt;

&lt;p&gt;You pass parent incident, but this is the pain point: when testing it, you are sure that you pass sys_id. But step out and think in this way: &lt;br&gt;
&lt;code&gt;What if the parameter is empty or null value is pushed?&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;And actually this might happen pretty easily. For example when event parameter is not initialized, or flow action returns null. &lt;/p&gt;

&lt;p&gt;I will show the wrong code later, so this is the correct code with if condition which checks the variable parent record sys_id. Pain point is explained below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
* Get child incidents for a given parent incident and update comments
* sys_id of parent incident is pushed by argument (event parm, sub flow, scheduled job, script include) 
* and sets sysIdParent variable
*/&lt;/span&gt;

&lt;span class="c1"&gt;// (1) var sysIdParent = '';&lt;/span&gt;
&lt;span class="c1"&gt;// (2) var sysIdParent = null;&lt;/span&gt;
&lt;span class="c1"&gt;// (3) var sysIdParent = undefined;&lt;/span&gt;
&lt;span class="c1"&gt;// (4) var sysIdParent = '14fef3c7878230105d8afea9cebb3594';&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sysIdParent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sys_id of parent incident&lt;/span&gt;
&lt;span class="c1"&gt;// This IF checks sysIdParent variable to avoid null/empty/undefined&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sysIdParent&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;sysIdParent&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlideRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incident&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parent_incident&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sysIdParent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRowCount&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Child incident triggered from script.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sysIdParent is null/empty/undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You expect the real sys_id is pushed (case 4 in the script). What will happen, if it is passed &lt;code&gt;null&lt;/code&gt; value here &lt;code&gt;gr_ChildIncidents.addQuery('parent_incident', sysIdParent);&lt;/code&gt; and there is no if condition checking input parameters? Logic assumption is that nothing happens. &lt;del&gt;It is null so GlideRecord will not fetch any data.&lt;/del&gt; &lt;strong&gt;Wrong!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Well, the script will execute for all active parent incidents (field parent incident is empty/null). It can be large number, instead of 3 child incidents… This is not good. Imagine there is deleteRecord() instead of update. You can simulate it on your personal development instance and see how many incidents are affected by script (wrong code):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Instance has active 10K parent incidents, &lt;/span&gt;
&lt;span class="c1"&gt;// 3 child incidents related to parent with sys_id: 14f...594&lt;/span&gt;
&lt;span class="c1"&gt;// (1) var sysIdParent = '';&lt;/span&gt;
&lt;span class="c1"&gt;// (2) var sysIdParent = null;&lt;/span&gt;
&lt;span class="c1"&gt;// (3) var sysIdParent = undefined;&lt;/span&gt;
&lt;span class="c1"&gt;// (4) var sysIdParent = '14fef3c7878230105d8afea9cebb3594';&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sysIdParent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sys_id of parent incident&lt;/span&gt;
&lt;span class="c1"&gt;// sysIdParent variable is not checked and null value will cause&lt;/span&gt;
&lt;span class="c1"&gt;// unexpected behaviour in GlideRecord query&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlideRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incident&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parent_incident&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sysIdParent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Number of affected rows&lt;/span&gt;
&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gr_ChildIncidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRowCount&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Number of affected records:&lt;/span&gt;
&lt;span class="c1"&gt;// (1) 10 000&lt;/span&gt;
&lt;span class="c1"&gt;// (2) 10 000&lt;/span&gt;
&lt;span class="c1"&gt;// (3) 10 000&lt;/span&gt;
&lt;span class="c1"&gt;// (4) 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you come from Java world or any strict object language you are learned to check the input parameters. Do the same when dealing with GlideRecord. &lt;code&gt;Check parameters used in GlideRecord queries,&lt;/code&gt; it will prevent your stress level from reaching level billion.&lt;/p&gt;

&lt;p&gt;I explained the issue on incident table, but the same issue is valid for other use cases where you use GlideRecord in scripts. Consequences on cmdb could be serious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is null nothing in JavaScript?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The value null represents the intentional absence of any object value. It is one of JavaScript's primitive values.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I would use &lt;code&gt;typeof&lt;/code&gt; operator. The typeof operator returns a string indicating the type of the operand's value. But check this and run on your personal development instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// boolean&lt;/span&gt;
&lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// object (wait?!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujcezbiptzs8640a1y19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujcezbiptzs8640a1y19.png" alt="typeof null" width="723" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;typeof null&lt;/code&gt; &lt;strong&gt;returns object in JavaScript&lt;/strong&gt;… But it was said that &lt;code&gt;null&lt;/code&gt; is primitive type. This sounds like singularity in JavaScript world. Well, this is not issue related to ServiceNow, there is &lt;strong&gt;a bug in core JavaScript&lt;/strong&gt; since the beginning unfortunately:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/there-is-a-bug-in-javascript-since-day-one-typeof-null-9b18da349cc6" rel="noopener noreferrer"&gt;https://javascript.plainenglish.io/there-is-a-bug-in-javascript-since-day-one-typeof-null-9b18da349cc6&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to check variables to avoid empty/null/undefined?&lt;/strong&gt;&lt;br&gt;
So &lt;code&gt;typeof&lt;/code&gt; will not help you. Instead, I use conditions &lt;br&gt;
&lt;code&gt;sysIdParent != '' &amp;amp;&amp;amp; sysIdParent != null&lt;/code&gt; &lt;br&gt;
which check that variable is not empty / null / undefined. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F034e3wyt4s7x50qsfcn5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F034e3wyt4s7x50qsfcn5.png" alt="null == undefined" width="688" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are curious more about &lt;code&gt;null&lt;/code&gt; value in JavaScript, check this post, it goes deeper: &lt;a href="https://javascript.plainenglish.io/how-to-check-for-null-in-javascript-dffab64d8ed5" rel="noopener noreferrer"&gt;https://javascript.plainenglish.io/how-to-check-for-null-in-javascript-dffab64d8ed5&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;It is easy to write 15 lines GlideRecord script which is working on the first sight. But the devil is always looking for opportunity. Step out and always think about possible situations: What if &lt;code&gt;null, undefined, false, empty string&lt;/code&gt; is passed as parameter? What if previous action like flow, subflow ends with error? Did I treat these errors?&lt;/p&gt;

&lt;p&gt;These &lt;code&gt;whatifs&lt;/code&gt; will help you to analyze and step back to see the wider perspective. And then write safer code. Take time to analyze what are the input parameters, where do they come from. And take time to test it on a dev instance. &lt;/p&gt;

&lt;p&gt;I am curious to hear about some "fun dev stories when null is passed" in comments :)&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>tools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ServiceNow: How to pass Performance analytics CAS certification</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Sun, 26 Feb 2023 23:17:33 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-how-to-pass-performance-analytics-cas-certification-1n7b</link>
      <guid>https://dev.to/mkrcma/servicenow-how-to-pass-performance-analytics-cas-certification-1n7b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Performance analytics (PA)&lt;/strong&gt; knowledge is quite rare in ServiceNow world. It goes across platform, you can use it in Incident management, GRC, SecOps, Event mng., Problem mng., etc. PA is useful in process monitoring, forecasting, analyzing process deflections. Dashboards present important data for all organizational levels. It is a great method of how to provide visible and added-value output to your customer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawvjk17izdvc69p75tl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawvjk17izdvc69p75tl2.png" alt=" " width="726" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ServiceNow offers mainline certification for PA. In general two types of certification are in ServiceNow: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Micro-certifications&lt;/strong&gt;: is non-proctored, free, and you have unlimited attempts. After completing, it says that you have fundamental knowledge of chosen topic. It is a good starting point on a longer journey. You can do micro-certification for PA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mainline certification&lt;/strong&gt;: is proctored, you need to pay for the exam, you have 4 attempts and each attempt is paid. It is more serious type of exam and after completing it proves that you know the chosen process/area in deep, and you are able to implement it on a client side. Mainline certifications are valuable assets in ServiceNow world and your career. The process related (ITSM, Event, CSM, etc.) are called Certified Implementation Specialist (CIS). Performance analytics has its own category: Certified Application Specialist (CAS). &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A complete overview of ServiceNow certifications is here (The journey to certification with ServiceNow): &lt;a href="https://www.servicenow.com/content/dam/servicenow/other-documents/training/tp-certification-guide.pdf" rel="noopener noreferrer"&gt;https://www.servicenow.com/content/dam/servicenow/other-documents/training/tp-certification-guide.pdf&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And PA certification path is here:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2r569g1lyjsgio2y30cd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2r569g1lyjsgio2y30cd.png" alt=" " width="800" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All mandatory courses are provided in Nowlearning portal, and they are available on-demand. You don't have to register for instructor led courses anymore. That's good, you can proceed the learning in your pace.&lt;/p&gt;




&lt;p&gt;Follow &lt;strong&gt;Nowlearning courses&lt;/strong&gt; (if links not working, search by course title in Nowlearning, courses are regularly updated and old ones are retired):&lt;br&gt;
1) &lt;code&gt;Performance Analytics (PA) Essentials&lt;/code&gt; &lt;a href="https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=289a949bdb2b009015531cbd139619d1" rel="noopener noreferrer"&gt;https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=289a949bdb2b009015531cbd139619d1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;code&gt;Performance Analytics (PA) Fundamentals On Demand&lt;/code&gt; &lt;a href="https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=cbf3497e8759d1586a0bedbd0ebb351c" rel="noopener noreferrer"&gt;https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=cbf3497e8759d1586a0bedbd0ebb351c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;code&gt;Performance Analytics Implementation Simulator&lt;/code&gt; &lt;a href="https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=aac27a94db711c90bc99e05e13961993" rel="noopener noreferrer"&gt;https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=aac27a94db711c90bc99e05e13961993&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) &lt;code&gt;Performance Analytics (PA) Simulator - Micro Certification&lt;/code&gt; &lt;a href="https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=4240b5fe879d55586a0bedbd0ebb3597" rel="noopener noreferrer"&gt;https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=4240b5fe879d55586a0bedbd0ebb3597&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) &lt;code&gt;Performance Analytics (PA) Advanced On Demand&lt;/code&gt; &lt;a href="https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=36c8c3cf8771151424e0bb39dabb35fa" rel="noopener noreferrer"&gt;https://nowlearning.servicenow.com/lxp?id=learning_course_prev&amp;amp;course_id=36c8c3cf8771151424e0bb39dabb35fa&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also recommend this source on developer's site, it is practical and step by step: &lt;a href="https://developer.servicenow.com/dev.do#!/learn/courses/tokyo/app_store_learnv2_reportanalytics_tokyo_reporting_and_analytics/app_store_learnv2_reportanalytics_tokyo_performance_analytics/app_store_learnv2_reportanalytics_tokyo_performance_analytics_objectives" rel="noopener noreferrer"&gt;Performance Analytics Objectives&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After completing &lt;strong&gt;PA advanced course&lt;/strong&gt;, you get exam voucher, and you can schedule the exam in Webassessor Kryterion. &lt;strong&gt;Exam blueprint&lt;/strong&gt; with exam details is here: &lt;a href="https://www.servicenow.com/content/dam/servicenow/other-documents/training/mainline-blueprint-cas-pa.pdf" rel="noopener noreferrer"&gt;https://www.servicenow.com/content/dam/servicenow/other-documents/training/mainline-blueprint-cas-pa.pdf&lt;/a&gt; &lt;br&gt;
It is important to note that for success it is essential to have at least basic PA implementation experience. Memorizing does not work, some exam questions are tricky and only practicing PA gives the correct answer because you will see all the relations.&lt;/p&gt;

&lt;p&gt;I do not recommend any Udemy courses and sample tests as main source. Just &lt;strong&gt;follow official ServiceNow courses&lt;/strong&gt; and the most important information is covered in the last &lt;strong&gt;PA advanced&lt;/strong&gt; course. Go through this course and provided materials carefully and read it minimally 3 times. Yes, it takes time and there are many topics, but it pays off in the exam. &lt;/p&gt;

&lt;p&gt;Don't forget checkout &lt;a href="https://www.servicenow.com/community/performance-analytics-blog/bg-p/platform-analytics-blog" rel="noopener noreferrer"&gt;Performance Analytics blog &lt;/a&gt;. There are many useful posts and release updates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4fj8vsrcg0gz0r156wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4fj8vsrcg0gz0r156wm.png" alt=" " width="388" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much time does it take to study?&lt;/strong&gt; For all Nowlearning courses count with 10 days. Before PA Advanced course try to practice it, ideally on project, but you can practice on your development instance with PA content packs (install plugins and explore). Take time to be confident in UI and know all relations. In parallel, you can start PA Advanced course. Finally, preparing for exam like reading provided materials again and again will take 3 days of intensive learning. Exam has 60 questions, time limit is 1.5 hour, it is more than enough time. Passing percentage is about 75 % (better to be prepared for 80 %). However, &lt;a href="https://www.servicenow.com/content/dam/servicenow/other-documents/training/mainline-blueprint-cas-pa.pdf" rel="noopener noreferrer"&gt;exam blueprint&lt;/a&gt; does not mention the threshold score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does it cost?&lt;/strong&gt; If you work for any ServiceNow partner organization, the on-demand courses are for free. Only exam is paid about $300. If you do it by yourself on your personal ServiceNow account, on-demand courses are paid about $300 for PA Fundamentals, $500 for PA Advanced, plus exam $300. I don't mention instructor-led courses which are much more expensive. As far as I remember PA advanced is mandatory, the rest is up to you. But maybe it changed, check the latest requirements. So, is it worth of money? Definitely yes, you get better position on the market and consulting companies invest to get certified people because ROI is pretty fast. Moreover, you really get specialized knowledge about topic. The same is valid for freelancers, it is easier to get contract if you prove your knowledge with certification.&lt;/p&gt;




&lt;p&gt;I prepared sample questions, it is not copy-paste from the exam, but the nature of exams questions is similar. 1 option is correct, if not mentioned something else.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Scores for formula indicators are calculated:&lt;br&gt;
a) when data collected by scheduled job&lt;br&gt;
b) when widget with formula indicator displayed&lt;br&gt;
c) when contributing indicators are collected&lt;br&gt;
d) after formula indicator is saved&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Which widget type to use for multiple indicators and their relations:&lt;br&gt;
a) score widget&lt;br&gt;
b) breakdown widget&lt;br&gt;
c) workbench widget&lt;br&gt;
d) pivot widget&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to configure second-level breakdowns for indicator?&lt;br&gt;
a) "Collect breakdown matrix" checkbox in automated indicator &lt;br&gt;
b) "Collect breakdown matrix" checkbox in collection job definition&lt;br&gt;
c) "Collect breakdown matrix" system property&lt;br&gt;
d) No need to set, it works automatically for all indicators.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Collect records" checkbox on indicator enables (2 correct):&lt;br&gt;
a) Collecting scores for indicator&lt;br&gt;
b) Collecting sys_id of related records&lt;br&gt;
c) Drill-down to the records in Analytics hub&lt;br&gt;
d) Is available for formula and automated indicators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select syntax correct formula indicators (2 correct):&lt;br&gt;
a) &lt;code&gt;([[Number of open incidents not updated in last 5 days]] / [[Number of open incidents]]) * 100&lt;/code&gt;&lt;br&gt;
b) &lt;code&gt;[Summed age of open incidents] / [Number of open incidents] / 24&lt;/code&gt;&lt;br&gt;
c) &lt;code&gt;[[Number of new incidents]] / {{Number of resolved incidents}}&lt;/code&gt;&lt;br&gt;
d) &lt;code&gt;{Number of new incidents} / {Number of resolved incidents}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When "Scripted" checkbox is checked on the automated indicator, which field appears on the form?&lt;br&gt;
a) Aggregation&lt;br&gt;
b) Calculation&lt;br&gt;
c) Method&lt;br&gt;
d) Script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to visualize "incident age by range" (like 00 - 01 Day, 01 - 05 Days, 06 - 30 Days on x-axis and number of inc in range on y-axis). How to achieve it? &lt;br&gt;
a) Bucket groups &amp;gt; Breakdown source &amp;gt; Automated Breakdown &amp;gt; Scripted Breakdown mapping&lt;br&gt;
b) Breakdown source &amp;gt; Manual breakdown &amp;gt; Breakdown mapping&lt;br&gt;
c) Breakdown source &amp;gt; Automated Breakdown &amp;gt; Breakdown mapping&lt;br&gt;
d) No correct option&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Which is NOT correct for breakdowns? (2 correct)&lt;br&gt;
a) Enables you to group or filter indicator scores by an attribute&lt;br&gt;
b) Database view is a correct data input for breakdown source&lt;br&gt;
c) Maximum is two breakdowns for indicators &lt;br&gt;
d) It is possible to use three-breakdown matrix combinations in Analytics hub&lt;br&gt;
e) Breakdown relation allows hierarchy navigation (parent-child, member of)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Which breakdown matrix does NOT make sense? (2 correct)&lt;br&gt;
a) Country, Region&lt;br&gt;
b) Priority, Country&lt;br&gt;
c) Assignment group, Resolution Group&lt;br&gt;
d) State, Priority&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Where will you check collection jobs errors? (2 correct)&lt;br&gt;
a) "Job Logs" related list in collection job record&lt;br&gt;
b) "Job Logs" related list in indicator record&lt;br&gt;
c) Diagnostics in Analytics Hub&lt;br&gt;
d) Admin Console&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;I will post the correct answers later here in comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>claude</category>
      <category>startup</category>
    </item>
    <item>
      <title>ServiceNow: popup confirmation message, part 2/2 (with flow)</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Sun, 19 Feb 2023 21:37:39 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-22-with-flow-1d5k</link>
      <guid>https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-22-with-flow-1d5k</guid>
      <description>&lt;p&gt;Let's continue with the second use case for popup confirmation message (&lt;a href="https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-12-p6j"&gt;first part here&lt;/a&gt;). &lt;/p&gt;




&lt;p&gt;Here is the result what user will see: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft132vh3a5x4aoec34ua4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft132vh3a5x4aoec34ua4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create UI page with confirmation modal popup window and define all logic in the processing script. You can trigger subflow for example. Fully customized design and advance processing logic is a great advantage for this approach, but some intermediate scripting skills are needed.&lt;/p&gt;




&lt;p&gt;This popup window has some title, text, buttons like in previous use case (&lt;a href="https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-12-p6j"&gt;part one&lt;/a&gt;). But there is more: standard input for date time field and checkbox. Processing logic is triggering flow (explained later).&lt;/p&gt;

&lt;p&gt;There are three parts which you as developer need to do in ServiceNow:&lt;br&gt;
1) &lt;code&gt;Create/duplicate UI page&lt;/code&gt; how it will look, what will be visible in the window&lt;br&gt;
2) &lt;code&gt;Define processing logic&lt;/code&gt; what will happen after button clicked&lt;br&gt;
3) &lt;code&gt;UI action&lt;/code&gt; which adds a button on the form and shows the popup message on click. For sure instead of UI action, it could be triggered from client script, it depends on use case.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create/duplicate UI page
&lt;/h4&gt;

&lt;p&gt;As the starting point, you can choose any existing UI page and copy it to your UI page and then make modifications. Or starting from the scratch. The code is standard HTML with CSS so no rocket science, moreover you can use many useful ServiceNow macros and Jelly (Navigate to: &lt;code&gt;System UI &amp;gt; UI Macros&lt;/code&gt; and explore). The sky is your limit.&lt;/p&gt;

&lt;p&gt;To create a new UI page, navigate to: &lt;code&gt;System UI &amp;gt; UI Pages&lt;/code&gt; and use &lt;code&gt;New&lt;/code&gt;. Or select existing and use &lt;code&gt;Insert and stay&lt;/code&gt;, this will create the copy. Do not forget to rename it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oydy2a7ni8twp38y9gl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oydy2a7ni8twp38y9gl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three important parts (fields) of UI page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HTML&lt;/code&gt;: defines design of popup window. HTML, CSS, Jelly, ServiceNow UI macros can be used (Navigate to: &lt;code&gt;System UI &amp;gt; UI Macros&lt;/code&gt;). 
```javascript
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
    &lt;br&gt;
    &lt;br&gt;
    &lt;br&gt;&lt;br&gt;
         &lt;b&gt;${gs.getMessage('Are you sure you want to continue?')} &lt;/b&gt;&lt;br&gt;&lt;br&gt;
        ${gs.getMessage('Select date and time: ')} &lt;br&gt;&lt;br&gt;
        &lt;br&gt;
        &lt;br&gt;&lt;br&gt;&lt;br&gt;
        &lt;br&gt;
        I accept everything.&lt;br&gt;
      &lt;br&gt;&lt;br&gt;
      &lt;br&gt;
        &lt;br&gt;
      &lt;br&gt;
    &lt;br&gt;
&lt;a href="/g:ui_form"&gt;/g:ui_form&lt;/a&gt;&lt;br&gt;
&lt;a href="/j:jelly"&gt;/j:jelly&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Crucial part is: 
`&amp;lt;input type="hidden" name="my_sys_id" id="my_sys_id" value="${RP.getWindowProperties().get('sys_id')}"/&amp;gt;` where is sys_id of your record. It is initialized from UI action (explained later) and used in processing script. It is crucial to have this id for processing logic. Syntax is valid for `Global` scope, for any other scopes use `${RP.getWindowProperties().sys_id}`. It took me hours to find out why in scope apps `get('sys_id')` is not working. Well, global vs. scope script differences are never ending story.

`&amp;lt;g:dialog_buttons_ok_cancel /&amp;gt;` is out-of-the-box UI macro. Navigate to: `System UI &amp;gt; UI Macros` and search for `dialog_buttons_ok_cancel`. Give a try to observe what exists. For example, check the macros starting with `dialog` or `ui`. You are free to use any other UI macros and use it in your solution, just **important note:** do not edit any macro, it is probably used somewhere else.


- `Client script`: Handles any client-side processin. Runs in the browser (e.g. functions called by buttons, etc.). We set a value of hidden form field used later in processing script.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01l6bb6ep87xm1klxgv3.png)

```javascript


/*
* When user clicks "No"
* Close the popup window
*/
function cancel() {
    GlideDialogWindow.get().destroy();
}

/*
* When user clicks "Yes"
* Sets value of hidden input field "yes_no_result" to "yes"
*/
function actionOK() {
    // gel() is equivalent to getElementbyID("element")
    // In this case it sets value of hidden input field "yes_no_result"
    var c = gel('yes_no_result');
    c.value = 'yes';
    return true;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Processing script&lt;/code&gt;: Runs on the server when the page is submitted. It contains server side scripts like GlideRecord or flow triggering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Define processing logic
&lt;/h4&gt;

&lt;p&gt;In our case, I want to run a subflow. It can contain any logic you need to run. I assume you have existing logic in the subflow (maybe some future post will be about flows). I will just show useful feature &lt;code&gt;Create code snippet&lt;/code&gt; in &lt;code&gt;Flow designer&lt;/code&gt;. It generates code which you will use in processing script:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj3m5dw4siio5otcosjws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj3m5dw4siio5otcosjws.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All you need is to create &lt;code&gt;if/else&lt;/code&gt; decision, to set variable &lt;code&gt;inputs&lt;/code&gt; and then add some final steps based on subflow &lt;code&gt;output&lt;/code&gt;. In this case, it redirects to incident record and shows success message. Check comments in code for additional details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdb62r1ttwilxvm10dcch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdb62r1ttwilxvm10dcch.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/*
* yes_no_result is value of hidden field on the form
* the same values of "accept", "my_date_time" can be reached
* Value set in client script (step before)
*/&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yes_no_result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;gr_inc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlideRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incident&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;my_sys_id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;gr_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;my_sys_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Subflow triggering code&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
            &lt;span class="c1"&gt;// Subflow inputs, input name = incident_in&lt;/span&gt;
            &lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incident_in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gr_inc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// GlideRecord of table: incident &lt;/span&gt;
            &lt;span class="c1"&gt;// Start Asynchronously: Uncomment to run in background. Code snippet will not have access to outputs.&lt;/span&gt;
                    &lt;span class="c1"&gt;// sn_fd.FlowAPI.getRunner().subflow('global.my_incident_confirmation').inBackground().withInputs(inputs).run();&lt;/span&gt;
            &lt;span class="c1"&gt;// Execute Synchronously: Run in foreground. Code snippet has access to outputs.&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sn_fd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FlowAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRunner&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;global.my_incident_confirmation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;inForeground&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;withInputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getOutputs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// Get Outputs:&lt;/span&gt;
            &lt;span class="c1"&gt;// Note: outputs can only be retrieved when executing synchronously.&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;incident_out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incident_out&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// Reference&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;incident_out&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;incident_out&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addInfoMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Action successfully done.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incident.do?sys_id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addErrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error. Check the sublow logs.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incident.do?sys_id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incident.do?sys_id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Instead of triggering flow, you can use standard server side script using GlideRecord and to do whatever is needed. For example, this code does some stuff on child incidents. &lt;code&gt;Processing script&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection_result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Is my_sys_id initialized&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;my_sys_id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;updated_child_inc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;gr_child_inc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GlideRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incident&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;gr_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parent_incident&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;gr_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Get all incident childs and add comment there&lt;/span&gt;
        &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gr_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;gr_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Comment from processing script in UI Page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;updated_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gr_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="nx"&gt;gr_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Add info message with list of affected child incidents and redirects to incident &lt;/span&gt;
        &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addInfoMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Action successfully finished. Updated child incidents: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;updated_child_inc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;incident.do?sys_id=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;my_sys_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addErrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error: sys_id is not initialized.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  3. UI action
&lt;/h4&gt;

&lt;p&gt;You just initialize popup window defined in UI page, set title, and sys_id. All the logic is in UI page. The same you can do via  client script (eg. onChange when the field value changes) instead of UI action, it depends on use case.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqocoitaw8m5oj5bjti8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feqocoitaw8m5oj5bjti8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myAction_2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;dlgClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;GlideModal&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;GlideModal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GlideDialogWindow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// IMPORTANT define which UI page will be displayed, UI page name out-of-box or custom&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;dlg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;dlgClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my_confirmation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Confirmation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// IMPORTANT set sys_id properties, it is used in UI page as record identifier&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sys_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g_form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUniqueValue&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;I always prefer to re-use existing objects. It is fast, and I am not a fan of re-inventing the wheel. I call it laziness, but you know what I mean, right? :) Sometimes it takes time to analyze existing codes, but it pays off in the end.&lt;/p&gt;

&lt;p&gt;In these posts, the aim is not to give complete steps how something is done. I would like to show the way of thinking and to show the basic working use cases. With these basics and understanding, you can develop very complex and nice solutions. Only sky is the limit. (&lt;a href="https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-12-p6j"&gt;First part here.&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Statement: Solution presented in this post is tested on personal development instance. No client ServiceNow nodes were injured during development, no data loss, no major incident occurred. Developed and tested on Tokyo ServiceNow release.&lt;/p&gt;

</description>
      <category>servicenow</category>
      <category>cloud</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>ServiceNow: popup confirmation message, part 1/2</title>
      <dc:creator>Marek Krčma</dc:creator>
      <pubDate>Sat, 18 Feb 2023 22:26:23 +0000</pubDate>
      <link>https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-12-p6j</link>
      <guid>https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-12-p6j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;"We need confirmation popup message when the record is updated to avoid unwanted update, similar style as for delete button."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;This is how it started. Unfortunately, replicating delete button code was not possible, it is too complex on the first sight and I believed there is an easier way how to meet the requirement. Yes, I am soooo lazy. As usual in ServiceNow, it already exists. You just need to dive into dark ServiceNow waters, and there are monsters in the dark: UI pages with some jelly code. The result looks like this (plus invisible logic when you click OK): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh7bsedgp6ig24mezcik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh7bsedgp6ig24mezcik.png" alt="ServiceNow popup window"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will describe two ways how to achieve popup windows: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First case&lt;/strong&gt;&lt;br&gt;
Using existing out-of-the-box glide confirmation modal windows. &lt;strong&gt;Pros:&lt;/strong&gt; Easy to implement. &lt;strong&gt;Cons:&lt;/strong&gt; Unable to use server functions, which might be limited for some cases. But client will love it, there is no need for customization, it is clean solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second case&lt;/strong&gt;&lt;br&gt;
Create your own UI page with confirmation modal window and define all logic in the processing script. You can trigger subflow for example. This is like Lego: putting bricks in the right positions. &lt;strong&gt;Pros:&lt;/strong&gt; Robust solution, you can pretty manage everything: the design of confirmation message and processing logic too. &lt;strong&gt;Cons:&lt;/strong&gt; It is more complex (intermediate scripting), it might be difficult to maintain on upgrades. &lt;a href="https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-22-with-flow-1d5k"&gt;Second case here&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  First case
&lt;/h3&gt;

&lt;p&gt;We will need only one UI action which utilize out-of-box popup modal message. Navigate to: &lt;code&gt;System UI &amp;gt; UI pages&lt;/code&gt; and search for name starting with: &lt;code&gt;glide_&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You will find for example &lt;code&gt;glide_confirm_standard&lt;/code&gt;, &lt;code&gt;glide_ask_standard&lt;/code&gt;, &lt;code&gt;glide_confirm_basic&lt;/code&gt;etc. It contains HTML//CSS/Jelly code, you can preview it and get the result. Important note: &lt;strong&gt;DO NOT EDIT existing UI pages&lt;/strong&gt;, it will have impact on related functionalities. But the good thing is that you can use it in the UI action. &lt;/p&gt;

&lt;p&gt;Take time to investigate the code, there are parameters which you can control displayed warn/info/error icon in the window, title text, body text, etc. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yqr2cjd8ke90vddkgqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yqr2cjd8ke90vddkgqi.png" alt="UI page - confirmation window"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use as it is, this part in code is important: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;tr&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dialog_buttons_row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;td&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dialog_buttons&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;dialog_buttons_ok_cancel&lt;/span&gt; &lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invokePromptCallBack('ok');&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;ok_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invokePromptCallBack('cancel')&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;cancel_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/td&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/tr&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And next the client script defining properties initializing from your UI action; &lt;code&gt;onPromptComplete&lt;/code&gt;, &lt;code&gt;onPromptCancel&lt;/code&gt; will reference callback function in UI action (explained later):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;invokePromptCallBack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;gdw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;GlideDialogWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gdw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onPromptComplete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gdw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onPromptCancel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gdw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gdw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;oldValue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;gdw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It tells what is triggered when &lt;code&gt;OK&lt;/code&gt; or &lt;code&gt;Cancel&lt;/code&gt; button is clicked. These parameters will be initialized by a callback function in UI action (explained later), so it will know what would happen when a button is clicked. In general, the logic is action driven: you have some button, button is linked with function and callback functions definitions run the logic. This is how most of modal windows in ServiceNow works. &lt;/p&gt;

&lt;p&gt;It is promising, now you need to use it in UI action. Let's have a look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6moyrpdtjplm3n9l018.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6moyrpdtjplm3n9l018.png" alt="UI action definition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the script is: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/* 
* Show modal window, set title, content and properties
* Define callback functions
*/&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myAction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Definition of the callback function for OK button&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;myActionCallbackOK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;submitNow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// Definition of the callback function for Cancel button&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;myActionCallbackCancel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;cancelNow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// Dialog window setup&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;dlgBody&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Are you sure you want to continue?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;dlgClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;GlideModal&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;GlideModal&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GlideDialogWindow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// IMPORTANT define which UI page will be displayed, UI page name OOTB or custom&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;dlg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;dlgClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;glide_confirm_standard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Proceed?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dlgBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// IMPORTANT define callback properties, properties names&lt;/span&gt;
    &lt;span class="c1"&gt;// are defined in UI page HTML code, use javascript bind() method&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onPromptComplete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myActionCallbackOK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPreference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onPromptCancel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myActionCallbackCancel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;dlg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/*
* Processing function for OK button (used in callback)
* IMPORTANT: only client side actions are allowed here, GlideAjax if needed any server side actions
* It updates the record
*/&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;submitNow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;g_form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/*
* Processing function for Cancel button (used in callback)
* IMPORTANT: only client side actions ares allowed here, GlideAjax if needed any server side actions
*/&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cancelNow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Closes the window by default, can be empty&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In short: firstly it defines OK/Cancel JavaScript functions and binds it with UI page code, secondly it creates the popup window, sets the attributes and displays the window. Finally, it defines the logic. Only client side actions are allowed because UI action is client (&lt;code&gt;Client&lt;/code&gt; checkbox). &lt;/p&gt;

&lt;p&gt;This example simply updates the record, and before it asks you if you want to do it. I can see big potential how to level up user experience.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://dev.to/mkrcma/servicenow-popup-confirmation-message-part-22-with-flow-1d5k"&gt;In part two&lt;/a&gt; I will describe the second solution which uses a custom UI page and triggers the flow. No rocket science, it will extend some of existing confirmation page, I will put there some existing UI macro and include custom process logic like triggering the subflow. It will be like Lego: putting bricks in the right positions.&lt;/p&gt;

&lt;p&gt;Statement: Solution presented in this post is done on personal development instance. No client ServiceNow nodes were injured during development, no data loss, no major incident occurred. Developed and tested on Tokyo ServiceNow release.&lt;/p&gt;

</description>
      <category>servicenow</category>
      <category>cloud</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
