servicenow documentation documentation - read the · pdf fileservicenow documentation...
TRANSCRIPT
ServiceNow DocumentationDocumentation
Release 001
Mark Carter
Nov 13 2017
Contents
1 Copying Data 311 Worknotes 312 Currency Fields 3
2 CORS Error 521 How to get around CORS Exception 5
3 Date Time Servicenow 731 Update Review Date 732 Comparing Due Date with Start Date 733 Comparing Months 834 Comparing Dates when days doesnrsquot matter (untested) 8
4 Design Resources 941 Icon Library 942 Instance Style Guide 9
5 Emails 1151 Parsing out Hidden Watermarks 11
6 GlideAjax 1361 Returning multiple values 13
7 Glide Conditionals 1571 Matching records using conditions 15
8 Hiding non-readable Rows in List View 1781 Separating Readable Projects By Department 17
9 Metrics 2191 Metric from Assignment Group to Close 21
10 Modules 23101 Open new window from module 23
11 OAuth 25111 Manual Oauth 25
i
12 Reference Qualifiers 27121 Creating a Dynamic Qualifier 27122 Qualifier that uses multiple queries 28
13 RegEx 29131 Replace with callback 29132 Example 2 replace ltltEMPLOYEEgtgt 30
14 REST Message v2 31141 External Cart Orders 31
15 Sending Attachments via REST 33151 Overview 33152 Staging Table 33153 Create a Transform Map 33154 Sending the REST Message 34155 Example Business Rule Script for Attachment 34
16 Service Portal 37161 Overview 37162 Understanding How Server Script Works 37
17 Sphinx Shortcuts 41171 Sphinx codes 41
18 Syntax Editor 43181 Location 43
19 Time Card Modifications 45191 Generate Time Cards based on Resource Allocations 45
20 UI Pages 49201 Triggering on change for select box 49202 Using a passed parameter in HTML field 50203 Using a passed parameter in the Client field 50
21 Working With Variable Sets 51211 Variable Iteration 51
22 Workflows 53221 Canceling and Reopening Workflow 53222 Sending in workflow values with StartFlow 53
23 Indices and tables 55
ii
ServiceNow Documentation Documentation Release 001
Contents
Contents 1
ServiceNow Documentation Documentation Release 001
2 Contents
CHAPTER 1
Copying Data
11 Worknotes
Copying the full set of work notes to another area
Gets all worknotes associated with currentvar notes = currentwork_notesgetJournalEntry(-1)
var newNotes = Copied notes n + notes
12 Currency Fields
Copying old funds in current to new funds in another field
bCasenew_funds = bCasenew_fundsgetReferenceCurrencyCode() + + currentold_rarr˓fundsgetReferenceValue()
3
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
Contents
1 Copying Data 311 Worknotes 312 Currency Fields 3
2 CORS Error 521 How to get around CORS Exception 5
3 Date Time Servicenow 731 Update Review Date 732 Comparing Due Date with Start Date 733 Comparing Months 834 Comparing Dates when days doesnrsquot matter (untested) 8
4 Design Resources 941 Icon Library 942 Instance Style Guide 9
5 Emails 1151 Parsing out Hidden Watermarks 11
6 GlideAjax 1361 Returning multiple values 13
7 Glide Conditionals 1571 Matching records using conditions 15
8 Hiding non-readable Rows in List View 1781 Separating Readable Projects By Department 17
9 Metrics 2191 Metric from Assignment Group to Close 21
10 Modules 23101 Open new window from module 23
11 OAuth 25111 Manual Oauth 25
i
12 Reference Qualifiers 27121 Creating a Dynamic Qualifier 27122 Qualifier that uses multiple queries 28
13 RegEx 29131 Replace with callback 29132 Example 2 replace ltltEMPLOYEEgtgt 30
14 REST Message v2 31141 External Cart Orders 31
15 Sending Attachments via REST 33151 Overview 33152 Staging Table 33153 Create a Transform Map 33154 Sending the REST Message 34155 Example Business Rule Script for Attachment 34
16 Service Portal 37161 Overview 37162 Understanding How Server Script Works 37
17 Sphinx Shortcuts 41171 Sphinx codes 41
18 Syntax Editor 43181 Location 43
19 Time Card Modifications 45191 Generate Time Cards based on Resource Allocations 45
20 UI Pages 49201 Triggering on change for select box 49202 Using a passed parameter in HTML field 50203 Using a passed parameter in the Client field 50
21 Working With Variable Sets 51211 Variable Iteration 51
22 Workflows 53221 Canceling and Reopening Workflow 53222 Sending in workflow values with StartFlow 53
23 Indices and tables 55
ii
ServiceNow Documentation Documentation Release 001
Contents
Contents 1
ServiceNow Documentation Documentation Release 001
2 Contents
CHAPTER 1
Copying Data
11 Worknotes
Copying the full set of work notes to another area
Gets all worknotes associated with currentvar notes = currentwork_notesgetJournalEntry(-1)
var newNotes = Copied notes n + notes
12 Currency Fields
Copying old funds in current to new funds in another field
bCasenew_funds = bCasenew_fundsgetReferenceCurrencyCode() + + currentold_rarr˓fundsgetReferenceValue()
3
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
12 Reference Qualifiers 27121 Creating a Dynamic Qualifier 27122 Qualifier that uses multiple queries 28
13 RegEx 29131 Replace with callback 29132 Example 2 replace ltltEMPLOYEEgtgt 30
14 REST Message v2 31141 External Cart Orders 31
15 Sending Attachments via REST 33151 Overview 33152 Staging Table 33153 Create a Transform Map 33154 Sending the REST Message 34155 Example Business Rule Script for Attachment 34
16 Service Portal 37161 Overview 37162 Understanding How Server Script Works 37
17 Sphinx Shortcuts 41171 Sphinx codes 41
18 Syntax Editor 43181 Location 43
19 Time Card Modifications 45191 Generate Time Cards based on Resource Allocations 45
20 UI Pages 49201 Triggering on change for select box 49202 Using a passed parameter in HTML field 50203 Using a passed parameter in the Client field 50
21 Working With Variable Sets 51211 Variable Iteration 51
22 Workflows 53221 Canceling and Reopening Workflow 53222 Sending in workflow values with StartFlow 53
23 Indices and tables 55
ii
ServiceNow Documentation Documentation Release 001
Contents
Contents 1
ServiceNow Documentation Documentation Release 001
2 Contents
CHAPTER 1
Copying Data
11 Worknotes
Copying the full set of work notes to another area
Gets all worknotes associated with currentvar notes = currentwork_notesgetJournalEntry(-1)
var newNotes = Copied notes n + notes
12 Currency Fields
Copying old funds in current to new funds in another field
bCasenew_funds = bCasenew_fundsgetReferenceCurrencyCode() + + currentold_rarr˓fundsgetReferenceValue()
3
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
Contents
Contents 1
ServiceNow Documentation Documentation Release 001
2 Contents
CHAPTER 1
Copying Data
11 Worknotes
Copying the full set of work notes to another area
Gets all worknotes associated with currentvar notes = currentwork_notesgetJournalEntry(-1)
var newNotes = Copied notes n + notes
12 Currency Fields
Copying old funds in current to new funds in another field
bCasenew_funds = bCasenew_fundsgetReferenceCurrencyCode() + + currentold_rarr˓fundsgetReferenceValue()
3
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
2 Contents
CHAPTER 1
Copying Data
11 Worknotes
Copying the full set of work notes to another area
Gets all worknotes associated with currentvar notes = currentwork_notesgetJournalEntry(-1)
var newNotes = Copied notes n + notes
12 Currency Fields
Copying old funds in current to new funds in another field
bCasenew_funds = bCasenew_fundsgetReferenceCurrencyCode() + + currentold_rarr˓fundsgetReferenceValue()
3
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 1
Copying Data
11 Worknotes
Copying the full set of work notes to another area
Gets all worknotes associated with currentvar notes = currentwork_notesgetJournalEntry(-1)
var newNotes = Copied notes n + notes
12 Currency Fields
Copying old funds in current to new funds in another field
bCasenew_funds = bCasenew_fundsgetReferenceCurrencyCode() + + currentold_rarr˓fundsgetReferenceValue()
3
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
4 Chapter 1 Copying Data
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 2
CORS Error
21 How to get around CORS Exception
chromeexe --user-data-dir=CChrome dev session --disable-web-security
Depending on location of Chrome file can be run with single line below
CProgram Files (x86)GoogleChromeApplicationchromeexe --user-data-dir=Crarr˓Chrome dev session --disable-web-security
Warning Goes without saying be careful of security
5
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
6 Chapter 2 CORS Error
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 3
Date Time Servicenow
31 Update Review Date
(function executeRule(current previous null when async)
var gdt = new GlideDateTime(currentends)gdtaddDays(90)currentu_review_date_custom = gdt
)(current previous)
Warning addDays() will addDays to the time but does not return a glideDateTime
currentends is a Date (not DateTime) field
32 Comparing Due Date with Start Date
On Change Client Script for Due Date
function onChange(control oldValue newValue isLoading isTemplate) if (isLoading || g_formgetValue(expected_start) == )
return
var start_date = g_formgetValue(expected_start)
Calls serverside script to check if start date is earlier than due datevar ajax = new GlideAjax(TransferOrderDateTimeAjax)ajaxaddParam(sysparm_namecompareDatesAjax)ajaxaddParam(sysparm_startDate start_date)
7
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
ajaxaddParam(sysparm_endDate newValue)ajaxgetXML(warnIfFalse)
Callback will display error if start date is earlier than due datefunction warnIfFalse(response)var answer = responseresponseXMLdocumentElementgetAttribute(answer)if (answer == false)
g_formsetValue(due_date )g_formshowErrorBox(due_date Due Date must be after Start Date)
33 Comparing Months
This code is used to find the difference between two dateTime in months
var start = profileGRgetValue(employment_start_date)var nowDate = new GlideDateTime()toString()
var year1 = startsplit(-)[0]var month1 = startsplit(-)[1]
var year2 = nowDatesplit(-)[0]var month2 = nowDatesplit(-)[1]
if (year1 == year2) return month2-month1
else var yearDiff = year2 - year1var monthDiff = month2 - month1return (yearDiff 12) + monthDiff
34 Comparing Dates when days doesnrsquot matter (untested)
Uses a milisecond timestamp works for either Date or DateTime
newDate(g_formgetValue(expected_start))getTime() gt newDate(g_formgetValue(due_rarr˓date))getTime()
8 Chapter 3 Date Time Servicenow
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 4
Design Resources
41 Icon Library
httpstyleguideservicenowcomstyleicon-library
42 Instance Style Guide
httpsltinstancenamegtservice-nowcomstylesheisenbergstyleguidedocsindexhtml
9
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
10 Chapter 4 Design Resources
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 5
Emails
51 Parsing out Hidden Watermarks
511 Business Rule on sys_email table
(function executeRule(current previous null when async)
RegEx to find remove Re in subject and anything after In-Reply-Tocurrentsubject = String(currentsubject)replace(Re+i )currentheaders = String(currentheaders)replace(In-Reply-Tolt[^gt]gtig
rarr˓ )
)(current previous)
512 Summary
We had a client where an email would continually be marked as a reply with a watermark even after the watermarkhad been removed We found in this case we needed to remove the ldquoRErdquo in the subject and the ldquoIn-Reply-Tordquo in theemail header
11
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
12 Chapter 5 Emails
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 6
GlideAjax
61 Returning multiple values
You can return more than one value easiest if you return it as a JSON string
var GetUserRecord = Classcreate()GetUserRecordprototype = ObjectextendsObject(AbstractAjaxProcessor
getForCorrectiveItem function () var userID = thisgetParameter(sysparm_user_id)
var userGR = new GlideRecord(sys_user)userGRaddQuery(sys_id userID)userGRquery()
var userProps =
if (userGRnext()) userPropsname = userGRnametoString()userPropsmanager = userGRmanagertoString()userPropsdepartment = userGRdepartmenttoString()userPropslocation = userGRlocationgetDisplayValue()
var json = new JSON()var data = jsonencode(userProps)
return data
type GetUserRecord)
13
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
14 Chapter 6 GlideAjax
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 7
Glide Conditionals
71 Matching records using conditions
The business rule below runs when a record is inserted into the table It orders the approval_conditions record andchecks to see if the current inserted record matches the condition set in the approval_condition record
(function executeRule(current previous null when async)
var approvalConditionsGR = new GlideRecord(approval_conditions_table)approvalConditionsGRorderBy(order)approvalConditionsGRquery()
while (approvalConditionsGRnext()) if (GlideFiltercheckRecord(current approvalConditionsGRapproval_condition)
rarr˓ == true) var approver = approvalConditionsGRgetValue(approver)currentapproversetValue(approver)return
)(current previous)
15
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
16 Chapter 7 Glide Conditionals
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 8
Hiding non-readable Rows in List View
Row Level Security and On Query Business Rules
81 Separating Readable Projects By Department
If you ever try placing security by record (or by row) your users may start seeing lists views with a count of Rowsremoved by Securiy contraints Even worse they may think there are no more records when records can easily be onthe first and last page with any number of removed rows in between
17
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
Hiding_non-readable_RowsimgConstraintsJPG
811 Creating a Before Query Business Rule
The query created in the Business Rule can be thought of as a filter So letrsquos say one requirement is to allow anyonefrom the InfoSec Department to see any Contract record We would start the Business Rule by wrapping the filterwith an if statement
if (gshasRole(admin) || userIsInInfoSec()) Add filter query here
function userIsInInfoSec() Normal Glide Record query to see if users Dept is InfoSec
18 Chapter 8 Hiding non-readable Rows in List View
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
Next we need to apply the query Letrsquos say therersquos a department field on each contract and if a user is in the samedepartment as the one listed in contracts then they should be able to view it
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
currentaddQuery(department uGRdepartment)
What the query is doing here is returning only records that match department with the current userrsquos departmentThese will be the only records that will show in list view and will remove the security constraints as long as they havesecurity rights Below we are going to add another query where all contracts in the ldquoGuestrdquo department can be viewedas well
if (gshasRole(admin) || userIsInInfoSec()) var uID = gsgetUserID()var uGR = new GlideRecord(sys_user)uGRget(uID)
var q = currentaddQuery(department uGRdepartment)qaddOrCondition(department Guest)
81 Separating Readable Projects By Department 19
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
20 Chapter 8 Hiding non-readable Rows in List View
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 9
Metrics
91 Metric from Assignment Group to Close
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Metric Definition
Name Assignment Group has been populatedType Script calculation
if (currentassignment_groupnil()) createMetric()
function createMetric() var mi = new MetricInstance(definition current)if (mimetricExists())
return
var gr = migetNewRecord()grfield_value = currentassignment_group
grstart = currentsys_updated_ongrcalculation_complete = falsegrinsert()
Metric Definition
Name Stop Assignment duration on closeType Script calculation
21
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
Close Durations on Closed Complete Closed Incomplete or Cancelledif (currentstate == 3 || currentstate == 4 || currentstate == 7)
closeDurations(current)
function closeDurations(current) var gr = new GlideRecord(metric_instance)graddQuery(id currentsys_id)graddQuery(calculation_complete false)graddQuery(definitionname Time to closure)grquery()while (grnext())
var definition = new GlideRecord(metric_definition)definitionget(grdefinition)var mi = new MetricInstance(definition current)miendDuration()
Warning Both Metrics need to be placed as ldquoScript calculationrdquo or it will not process correctly
22 Chapter 9 Metrics
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 10
Modules
101 Open new window from module
This will require two metric definitions One will track the assignment group field and the other will track the statefield When the assignment group is filled the metric begins and when the state turns to close the metric will find theassignment group metric and end the duration
Module
Link Type URL (from Arguments)
In the arguments field use the following
javascripttopwindowopen(sys_user_listdo _blank height=700width=1000rarr˓)
23
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
24 Chapter 10 Modules
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 11
OAuth
111 Manual Oauth
Oauth profile needs to be first set up on ServiceNow After set up code below can run Oauth for each REST call Thisis taken form a SalesForce Integration
var oAuthClient = new sn_authGlideOAuthClient()var params = grant_typepassword username username password passwordvar json = new globalJSON()var text = jsonencode(params)var tokenResponse = oAuthClientrequestToken(nameless-dev-edmysalesforcecom
rarr˓text)var token = tokenResponsegetToken()
gsinfo(AccessToken + tokengetAccessToken())gsinfo(AccessTokenExpiresIn + tokengetExpiresIn())gsinfo( RefreshToken + tokengetRefreshToken())
var response responseBody status
try
var restMessage = new sn_wsRESTMessageV2()restMessagesetHttpMethod(get)restMessagesetEndpoint(httpsnameless-dev-edmysalesforcecomservicesdata
rarr˓v390queryq=SELECT+FirstName+LastName+Company+MobilePhone+from+Lead)restMessagesetRequestHeader(Authorization Bearer + tokengetAccessToken())
response = restMessageexecute()responseBody = responsehaveError() responsegetErrorMessage() response
rarr˓getBody()status = responsegetStatusCode()
catch(ex) responseBody = ex
25
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
status = 500 finally
requestBody = restMessage restMessagegetRequestBody()null
gsinfo(Request Body + requestBody)gsinfo(Response + responseBody)gsinfo(HTTP Status + status)
26 Chapter 11 OAuth
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 12
Reference Qualifiers
121 Creating a Dynamic Qualifier
I decided to create a catalog item to request a parking space One feature I wanted was to only show parking spotsdepending on which type of spot you want to reserve (ie VIP Motorcycle Normal)
To accomplish that requirement I decided to go with a dynamic qualifier that changes depending on type selected
1211 The Script Include
This is probably up for debate but I decided to keep the same object format for my script include using Classcreate()and prototype
Script Include Fields
Name parkingByParkingTypeClient callable True
var parkingByParkingType = Classcreate()parkingByParkingTypeprototype =
initialize function()
getSpots function()
var result = []
var res = new GlideRecord(u_parking_spot)resaddQuery(u_assigned false)resaddQuery(u_type currentvariablesparking_type)resquery()
27
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
while ( resnext() ) resultpush(ressys_idtoString())
var au = new ArrayUtil()
return auunique(result)
type parkingByParkingType
The function of interest is the getSpots() function Itrsquos a basic query in the u_parking_spot table but with a DynamicQuery we have acccess to current which we can use to add to query In this example wersquore using the parking_typevariable which is a selection
1212 The Dyanmic Filter Option
Ref httpswwwpacktpubcommaptbookNetworking20and20Servers978178217421902ch02lvl1sec26Scripting20Reference20Qualifiers
122 Qualifier that uses multiple queries
getUserGroupsAsArray() just grabs all users groups and puts them into an arrayvar userGroups = getUserGroupsAsArray()
--------------------------------------------------- Here each query checks to see if queried group is in one of the userGroups array---------------------------------------------------var portfolioGR = new GlideRecord(pm_portfolio)var q = portfolioGRaddQuery(u_departmentu_ppm_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_group IN userGroups)qaddOrCondition(u_departmentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentparentu_ppm_agency_intake_group IN userGroups)qaddOrCondition(u_departmentu_customer_engagement_group IN userGroups)qaddOrCondition(u_departmentparentu_customer_engagement_group IN userGroups)portfolioGRquery()
var portfolioArray = []
while(portfolioGRnext()) portfolioArraypush(portfolioGRsys_idtoString())
unique() function takes out any duplicatesvar arrayUtil = new ArrayUtil()var cleanPortfolioArray = arrayUtilunique(portfolioArray)
return sys_idIN + cleanPortfolioArray
28 Chapter 12 Reference Qualifiers
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 13
RegEx
131 Replace with callback
Regex can be used for replacing a string but if you want to use the string still or store it you can use a callbackfunction
The code below will find a string store it in a table and replace it with the sys_id of the record
var body = textWithURLsvar newBody =
var trackGR = new GlideRecord(url_table)
Here we see the url variable will hold each matched string string The return string of each replace will replace the matched stringvar newBody = bodyreplace(hrefs=s[][^][]ig function
rarr˓createTracking(url)
trackGR = new GlideRecord(url_table)trackGRinitialize()trackGRu_email_message = currentsys_idtoString()var formattedUrl = urltoString()split([])[1]trackGRu_url_link = formattedUrlvar trackID = trackGRinsert()
return href=httpsdevXXXXXservice-nowcomnav_todouri=url_tabledosys_rarr˓id= + trackID +
)
textWithURLs = newBody
29
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
132 Example 2 replace ltltEMPLOYEEgtgt
var parsedForm = htmlFormreplace(ampltampltEMPLOYEENAMEampgtampgt|ltltEMPLOYEENAMEgtgtigrarr˓employeeGRname)parsedForm = parsedFormreplace(ampltampltEMPLOYEEFIRSTNAMEampgtampgt|ltrarr˓ltEMPLOYEEFIRSTNAMEgtgtig employeeGRfirst_name)parsedForm = parsedFormreplace(ampltampltDATEampgtampgt|ltltDATEgtgtig gsnowDateTime()rarr˓split( )[0])
30 Chapter 13 RegEx
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 14
REST Message v2
141 External Cart Orders
Therersquos three pieces I had to use to allow cart orders from an external source
1 Creating the staging table
2 Creating the business rule after insertion into the staging table
3 Setting up the REST Message
1411 Create the Staging Table
I created a table and named it Cart Order (u_cart_order) This will hold four fields used for calling theCart API to create an order more on that later
Column Label Type Max lengthReq_Id String 100Catalog Item String 40Errors String 500Variables String 3000
1412 Sending the REST Message
From within another ServiceNow Instance
This can be run however you would want but Irsquove only tested this using a background script I donrsquot seewhy it would fail anywhere else
var request = new sn_wsRESTMessageV2()requestsetEndpoint(httpsdev22614service-nowcomapinowtableu_cart_order)requestsetHttpMethod(POST)
31
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
Eg UserName=admin Password=admin for this code samplevar user = adminvar password = admin
requestsetBasicAuth(userpassword)requestsetRequestHeader(Acceptapplicationjson)requestsetRequestHeader(Content-Typeapplicationjson)requestsetRequestBody(u_catalog_itemBlackberry +
u_variablesoriginal^299-999-9991| +replacement^Yes)
var response = requestexecute()gslog(responsegetBody())
In the requestbody therersquos two key valuersquos to set up
bull u_catalog_item Name of the catalog item should be the value
bull u_variables The value should be a pipe | separated list of variables with the name of the variable the valueseparted by a caret ^
1413 Creating the Business Rule
When the REST message is sent it will populate the Cart Order table that we had created above Whatwe want to do is create a BEFORE business rule to be called on INSERT so it can go into the Cart APIand make an order depending on what was sent in the REST call
32 Chapter 14 REST Message v2
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 15
Sending Attachments via REST
151 Overview
This will allow a system to receive a base64 encoded string and set it to the attachment table
152 Staging Table
A table should be created that extends the Import Set Row table with the following added fields
Column label Type Max lengthattachment String 1000000name Stringticket number String 1000
153 Create a Transform Map
Name Source table Target tableAttachment Stage to Queue Attachment Staging Table ecc_queue
1531 Field Maps
Source field Target fieldu_attachment payloadu_name nameu_ticket_number source[Script] agent[Script] topic
33
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
Agent Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
Topic Scripts
answer = (function transformEntry(source)
Add your code herereturn AttachmentCreator return the value to be put into the target
rarr˓field
)(source)
154 Sending the REST Message
The rest message should be sent with the fields below
u_nameSomethingjpgimagejpegu_ticket_numberincident83bff1fddb2d220003ee793ebf961957u_attachmente490qugijelkabvrohatge4
155 Example Business Rule Script for Attachment
var target = new GlideRecord(sys_attachment)targetaddQuery(table_name incident)targetaddQuery(table_sys_id currentsys_id)targetquery()
while(targetnext()) var sa = new GlideSysAttachment()var binData = sagetBytes(target)var base64Data = GlideStringUtilbase64Encode(binData)
Send Attachmentsvar requestAttachment = new sn_wsRESTMessageV2()requestAttachmentsetEndpoint(httpsXXXXXservice-nowcomapinow
rarr˓importu_attachment_staging_table)requestAttachmentsetHttpMethod(POST)
requestAttachmentsetBasicAuth(userpassword)requestAttachmentsetRequestHeader(Acceptapplicationjson)requestAttachmentsetRequestHeader(Content-Typeapplicationjson)
34 Chapter 15 Sending Attachments via REST
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
var requestAttachmentJSONBody = createRequestBody(u_name targetfile_rarr˓name + + targetcontent_type)requestAttachmentJSONBody += addToRequestBody(u_ticket_number incident
rarr˓ + sysid)requestAttachmentJSONBody += addToRequestBody(u_attachment base64Data)requestAttachmentJSONBody += closeRequestBody()
requestAttachmentsetRequestBody(requestAttachmentJSONBody)
var responseAttachment = requestAttachmentexecute()
The createRequestBody() functions are just used to create a JSON Object with for example u_nameldquotargetinfordquo u_ticket_number ldquoincident39024903284rdquo
155 Example Business Rule Script for Attachment 35
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
36 Chapter 15 Sending Attachments via REST
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 16
Service Portal
161 Overview
This will discuss using Angular and coding widgets to create a Service Portal with as much if not more features asthe Content Management System
162 Understanding How Server Script Works
The Flow of Data from Servi-ceNow Docs
The Server Script on a widget is executed onLoad and can be used to transfer a data object from the server to theclient On the client this data object is very important for fleshing out your portal page
Letrsquos say you want a widget of vip users and their picture The server would send the data with that information andthe client receives that data object and then displays it the way you desire
datanames = []
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
37
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
while (userGRnext()) datanamespush(userGRnametoString())
Once the code reaches the bottom the data object will be sent So now you have an array of VIP names that you canuse
1621 The Client can send Data also
So letrsquos say you want to give users the ability to change what kind of users they want to see For example the userchooses to query for letrsquos say all ITIL users
On the client side code create an object literal called input and fill in the information the server would need For thisexample we can send the string ldquoitilrdquo in the input object Once we are ready we use serverupdate() to send the inputobject to the server
var c = thisvar input =
$scopeonItilButtonClick = function() inputbutton = itilcserverupdate()
After cserverupdate() the process then repeats sending whatever data object the server now has back to client andre-renders if anything changes
1622 Processing the input sent from client
The server client script gets processed in whole after a cserverupdate() so to prevent the original query from beingprocessed wersquoll have to wrap what we want in an if (input) statement The only difference from the first onLoadand the runs from the client is the appearance of the input object
datanames = []
if (input) var userGR = new GlideRecord(sys_user)userGRaddQuery(roles= + inputbutton)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
else
var userGR = new GlideRecord(sys_user)userGRaddQuery(vip true)userGRquery()
while (userGRnext()) datanamespush(userGRnametoString())
38 Chapter 16 Service Portal
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
The else statement here is defaulted to searching for vip When an input is sent to the server it will start a new querylooking for whatever role is in inputbutton
Code that you want to run on both onLoad and when a client re-renders just put them in the script normally Such asthe initialization of the datanames array on the first line
Warning Only data will get sent to the client from the server If you want to send input back you must put itback into the data object
if (input) datafoo = inputfoo
162 Understanding How Server Script Works 39
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
40 Chapter 16 Service Portal
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 17
Sphinx Shortcuts
171 Sphinx codes
code-block Javascript
var someCode = some more code
warning
Some warning block
41
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
42 Chapter 17 Sphinx Shortcuts
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 18
Syntax Editor
181 Location
System Definition gt Syntax Editor Macros
43
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
44 Chapter 18 Syntax Editor
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 19
Time Card Modifications
191 Generate Time Cards based on Resource Allocations
Currently timecards are only generated for the table planned_task and only for the current week
1911 Goal
bull Generate timecards when the current user is assigned as a resource allocation
bull Generate timecards for upcoming weeks (not just the current week)
1912 Script Include
The only script we need to edit is the TimeCardAjax script include Since this is OOB itrsquos best toinsert-and-stay then mark the original as inactive
The only OOB function we will be editing is ajaxFunction_generateTaskCards() the rest we will becreating ourselves
ajaxFunction_generateTaskCards function()get request infothisweekStart = this_getWeekStart()thisuser = thisgetParameter(sysparm_user)thisweekEnd = this_getWeekEnd()thisnewCards = [] list of cards createdthisexistingCards = this_getExistingCards()thisplannedTasks = this_getPlannedTasks()this_generateMissingCards(thisplannedTasks)this_generateMissingCards(thistasks)
added two functions to be run for Resource AllocationsthisresourceAllocations = this_getResourceAllocations()this_generateMissingAllocations()
45
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
this_buildResult()
This is the function that gets run initially when TimecardAjax is called What I added were two linesbetween this_generateMissingCards(thisplannedTasks) and this_buildResult()
Both functions should be self explanatory The _getResourceAllocation() grabs all resource allocationsfor the user and _generateMissingAllocations() will generate timecards if there are no timecards asso-ciated
1913 Unit Tests
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = 48b1d30ddb95a20003ee793ebf961942allocresource_plan = e3bc5091db19a20003ee793ebf961943var test = allocinsert()gslog(test)
var newTask = new GlideRecord(cert_follow_on_task)newTaskassigned_to = 0ac0a7f7db20220003ee793ebf961970newTaskshort_description = Unit Test 08171131
var taskId = newTaskinsert()gslog(taskID = + taskId)
var newRP = new GlideRecord(resource_plan)newRPtask = taskIdnewRPstart_date = 2015-01-01newRPend_date = 2019-01-01newRPuser_resource = 0ac0a7f7db20220003ee793ebf961970newRPresource_type = usernewRPplanned_hours = 0
var resourceId = newRPinsert()gslog(resourceID = + resourceId)
var alloc = new GlideRecord(resource_allocation)allocuser = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-05)allocstart_date = datevar date2 = new GlideDate()date2setValue(2016-11-23)allocend_date = date2allocrequested_hours = 30alloctask = taskIdallocresource_plan = resourceId
46 Chapter 19 Time Card Modifications
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
var allocationId = allocinsert()gslog(allocationdId = + allocationId)
var alloc2 = new GlideRecord(resource_allocation)alloc2user = 0ac0a7f7db20220003ee793ebf961970var date = new GlideDate()datesetValue(2016-11-16)alloc2start_date = datevar date2 = new GlideDate()date2setValue(2016-12-02)alloc2end_date = date2alloc2requested_hours = 30alloc2task = taskIdalloc2resource_plan = resourceId
allocationId = alloc2insert()gslog(allocationID2 = + allocationId)
191 Generate Time Cards based on Resource Allocations 47
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
48 Chapter 19 Time Card Modifications
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 20
UI Pages
201 Triggering on change for select box
To prevent using gel we can pass in the current value of the select box using thisvalue
2011 HTML
ltgevaluategtvar choiceList = new GlideChoiceList()choiceListadd( --None--)choiceListadd(123 OneTwoThree)choiceListadd(FourFiveSix 456)
ltgevaluategt
ltselect id=document_select name=document_select onchange=rarr˓myFunction(thisvalue)gtltgoptions choiceList=$choiceList choiceValue= gt
ltselectgt
2012 Client Script
function myFunction(val) alert(val)
49
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
202 Using a passed parameter in HTML field
2021 HTML
ltgevaluate var=jvar_document_arrayexpression=RPgetWindowProperties()get(sysparm_document_array) gt
ltscriptgtalert($jvar_document_array)
ltscriptgt
203 Using a passed parameter in the Client field
2031 Client script
if ($sysparm_checked_out == true) alert($sysparm_checked_out)
50 Chapter 20 UI Pages
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 21
Working With Variable Sets
211 Variable Iteration
Thanks to Andrew Sainz for finding this
var item = new GlideRecord(sc_req_item)itemaddQuery(sys_idcurrentsysapproval)itemquery()
if(itemnext()) for (var key in itemvariables)
var v = itemvariables[key]
if (v = ampamp vnil()) currentu_approval_summary +=vgetGlideObject()getQuestion()getLabel() +
+ vgetDisplayValue() + n
51
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
52 Chapter 21 Working With Variable Sets
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 22
Workflows
221 Canceling and Reopening Workflow
function server_cancel_business_case()Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Placed on hold by + gs
rarr˓getUser()name)new Workflow()deleteWorkflow(current)
currentu_ppm_bc_state = closed_cancelledcurrentupdate()actionsetRedirectURL(current)
Cancels all approvals for Business Case and delete workflownew WorkflowApprovalUtils()cancelAll(current Re-Opened by + gsgetUser())new Workflow()deleteWorkflow(current)
222 Sending in workflow values with StartFlow
UI Action Business Rule
var wf = new Workflow ( ) Get the workflow idvar wfId = wf getWorkflowFromName ( Print Screen ) var vars = varsu_task_sys_id = currentsys_idtoString()varsvariable2 = This is var2wf startFlow (wfId current Update vars )
Within Workflow Script
53
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
ServiceNow Documentation Documentation Release 001
var readValue = workflowinputsu_task_sys_idworkflowvariables_u_task_sys_id will also work
var projectTaskGR = new GlideRecord(pm_project_task)projectTaskGRget(sys_id readValue)projectTaskGRstate = 3projectTaskGRupdate()
54 Chapter 22 Workflows
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-
CHAPTER 23
Indices and tables
bull genindex
bull modindex
bull search
55
- Copying Data
-
- Worknotes
- Currency Fields
-
- CORS Error
-
- How to get around CORS Exception
-
- Date Time Servicenow
-
- Update Review Date
- Comparing Due Date with Start Date
- Comparing Months
- Comparing Dates when days doesnt matter (untested)
-
- Design Resources
-
- Icon Library
- Instance Style Guide
-
- Emails
-
- Parsing out Hidden Watermarks
-
- GlideAjax
-
- Returning multiple values
-
- Glide Conditionals
-
- Matching records using conditions
-
- Hiding non-readable Rows in List View
-
- Separating Readable Projects By Department
-
- Metrics
-
- Metric from Assignment Group to Close
-
- Modules
-
- Open new window from module
-
- OAuth
-
- Manual Oauth
-
- Reference Qualifiers
-
- Creating a Dynamic Qualifier
- Qualifier that uses multiple queries
-
- RegEx
-
- Replace with callback
- Example 2 replace ltltEMPLOYEEgtgt
-
- REST Message v2
-
- External Cart Orders
-
- Sending Attachments via REST
-
- Overview
- Staging Table
- Create a Transform Map
- Sending the REST Message
- Example Business Rule Script for Attachment
-
- Service Portal
-
- Overview
- Understanding How Server Script Works
-
- Sphinx Shortcuts
-
- Sphinx codes
-
- Syntax Editor
-
- Location
-
- Time Card Modifications
-
- Generate Time Cards based on Resource Allocations
-
- UI Pages
-
- Triggering on change for select box
- Using a passed parameter in HTML field
- Using a passed parameter in the Client field
-
- Working With Variable Sets
-
- Variable Iteration
-
- Workflows
-
- Canceling and Reopening Workflow
- Sending in workflow values with StartFlow
-
- Indices and tables
-