Skip to content

Commit 3f83b05

Browse files
authored
Merge branch 'ServiceNowDevProgram:main' into main
2 parents a81b541 + e7aa2f9 commit 3f83b05

File tree

21 files changed

+1958
-0
lines changed

21 files changed

+1958
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This project introduces a collaboration feature for Service Catalog requests, allowing multiple users to contribute to a single request. It’s ideal for scenarios like team onboarding, shared resource provisioning, or cross-functional workflows.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var CollaboratorHandler = Class.create();
2+
CollaboratorHandler.prototype = Object.extendsObject(AbstractAjaxProcessor, {
3+
addCollaborators: function() {
4+
var requestId = this.getParameter('sysparm_request_id');
5+
var users = this.getParameter('sysparm_users').split(',');
6+
7+
users.forEach(function(userId) {
8+
var gr = new GlideRecord('x_your_scope_collaborators');
9+
gr.initialize();
10+
gr.request = requestId;
11+
gr.collaborator = userId;
12+
gr.status = 'Pending';
13+
gr.insert();
14+
});
15+
16+
return 'Collaborators added successfully';
17+
}
18+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function onSubmit() {
2+
var collaborators = g_form.getValue('collaborators'); // Multi-user reference field
3+
if (collaborators) {
4+
var ga = new GlideAjax('CollaboratorHandler');
5+
ga.addParam('sysparm_name', 'addCollaborators');
6+
ga.addParam('sysparm_request_id', g_form.getUniqueValue());
7+
ga.addParam('sysparm_users', collaborators);
8+
ga.getXMLAnswer(function(response) {
9+
alert('Collaborators added: ' + response);
10+
});
11+
}
12+
return true;
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function($scope, $http) {
2+
$scope.approve = function(sysId) {
3+
$http.post('/api/x_your_scope/collab_action', {
4+
action: 'approve',
5+
sys_id: sysId
6+
}).then(function(response) {
7+
$scope.server.update();
8+
});
9+
};
10+
11+
$scope.reject = function(sysId) {
12+
$http.post('/api/x_your_scope/collab_action', {
13+
action: 'reject',
14+
sys_id: sysId
15+
}).then(function(response) {
16+
$scope.server.update();
17+
});
18+
};
19+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
(function() {
2+
var collabs = [];
3+
var gr = new GlideRecord('x_your_scope_collaborators');
4+
gr.addQuery('request', $sp.getParameter('request_id'));
5+
gr.query();
6+
while (gr.next()) {
7+
collabs.push({
8+
sys_id: gr.getUniqueValue(),
9+
name: gr.collaborator.name.toString(),
10+
status: gr.status.toString(),
11+
comments: gr.comments.toString()
12+
});
13+
}
14+
data.collaborators = collabs;
15+
})();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Sets the field value to the formatted percentage string (e.g., 45 becomes 45.00%).
2+
3+
Retrieves the current value of the field.
4+
Removes any existing % symbol to avoid duplication.
5+
Validates the input to ensure it's a number.
6+
Converts the value to a float.
7+
Formats it to two decimal places and appends a % symbol.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*Sets the field value to the formatted percentage string (e.g., 45 becomes 45.00%).
2+
3+
Retrieves the current value of the field.
4+
Removes any existing % symbol to avoid duplication.
5+
Validates the input to ensure it's a number.
6+
Converts the value to a float.
7+
Formats it to two decimal places and appends a % symbol. */
8+
9+
10+
function onChange(control, oldValue, newValue, isLoading) {
11+
if (isLoading || newValue == '') {
12+
return;
13+
}
14+
15+
function formatPercent(value) {
16+
if (value === null || value === undefined || value === '' || isNaN(value)) {
17+
return "";
18+
}
19+
var num = parseFloat(value);
20+
if (isNaN(num))
21+
return "";
22+
return num.toFixed(2) + "%";
23+
}
24+
var des_amount = g_form.getValue("<variable_name>").replace("%","");
25+
26+
g_form.setValue("<variable_name>", formatPercent(des_amount));
27+
28+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
🧩 Readme : Client Script: Auto Priority Update Based on Impact and Urgency
2+
📘 Overview
3+
4+
This client script automatically updates the Priority field on the Incident form whenever the Impact or Urgency value changes.
5+
It follows the ITIL standard mapping to ensure the correct priority is always set automatically, improving data accuracy and efficiency for service desk agents.
6+
7+
⚙️ Script Details
8+
Field Value
9+
Name Auto Priority Update based on Impact and Urgency
10+
Type onChange
11+
Applies to Table Incident
12+
Applies on Fields impact, urgency
13+
UI Type All (Classic, Mobile, Workspace)
14+
Active ✅ Yes
15+
Condition Leave blank
16+
💻 Script Code
17+
// ==========================================================================
18+
// Script Name: Auto Priority Update based on Impact and Urgency
19+
// Table: Incident
20+
// Type: onChange | Fields: impact, urgency
21+
// UI Type: All
22+
// Version: 2025 Production Ready
23+
// ==========================================================================
24+
25+
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
26+
// Skip execution if form is loading or field is empty
27+
if (isLoading || newValue == '') {
28+
return;
29+
}
30+
31+
// Get Impact and Urgency values
32+
var impact = g_form.getValue('impact');
33+
var urgency = g_form.getValue('urgency');
34+
35+
// Define Priority Matrix (ITIL standard)
36+
var priorityMatrix = {
37+
'1': { '1': '1', '2': '2', '3': '3' },
38+
'2': { '1': '2', '2': '3', '3': '4' },
39+
'3': { '1': '3', '2': '4', '3': '5' }
40+
};
41+
42+
// Find the new Priority
43+
var newPriority = priorityMatrix[impact]?.[urgency];
44+
45+
// Update the Priority field if valid
46+
if (newPriority) {
47+
if (g_form.getValue('priority') != newPriority) {
48+
g_form.setValue('priority', newPriority);
49+
g_form.showFieldMsg('priority', 'Priority auto-updated based on Impact and Urgency', 'info');
50+
}
51+
} else {
52+
// Optional: Clear Priority if invalid combination is selected
53+
g_form.clearValue('priority');
54+
g_form.showFieldMsg('priority', 'Invalid Impact/Urgency combination — priority cleared', 'error');
55+
}
56+
}
57+
58+
🧠 How It Works
59+
60+
The script runs automatically when Impact or Urgency changes.
61+
It checks the ITIL-based matrix to determine the correct Priority.
62+
If a valid combination is found, the Priority field updates automatically.
63+
A small info message appears to confirm the update.
64+
65+
🔢 ITIL Mapping Table
66+
Impact Urgency Resulting Priority
67+
1 (High) 1 (High) 1 (Critical)
68+
1 2 2
69+
1 3 3
70+
2 1 2
71+
2 2 3
72+
2 3 4
73+
3 1 3
74+
3 2 4
75+
3 3 5
76+
✅ Benefits
77+
78+
Automatically enforces ITIL priority standards
79+
Reduces manual effort and user errors
80+
Ensures consistency in priority calculation
81+
Compatible with Classic UI, Next Experience, and Agent Workspace
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//Auto Priority Update based on Impact and Urgency
2+
3+
// ==========================================================================
4+
// Script Name: Auto Priority Update based on Impact and Urgency
5+
// Table: Incident (or any Task-based table)
6+
// Type: onChange | Fields: impact, urgency
7+
// UI Type: All
8+
// ==========================================================================
9+
10+
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
11+
// Prevent the script from running when the form loads or when the field is empty
12+
if (isLoading || newValue == '') {
13+
return;
14+
}
15+
16+
// ----------------------------------------------------------------------
17+
// Step 1: Fetch field values from the form
18+
// ----------------------------------------------------------------------
19+
var impact = g_form.getValue('impact'); // e.g., 1 - High, 2 - Medium, 3 - Low
20+
var urgency = g_form.getValue('urgency'); // e.g., 1 - High, 2 - Medium, 3 - Low
21+
22+
// ----------------------------------------------------------------------
23+
// Step 2: Define the ITIL-based Priority Matrix
24+
// ----------------------------------------------------------------------
25+
// Each row represents "Impact", and each column represents "Urgency"
26+
// The resulting value sets the "Priority"
27+
var priorityMatrix = {
28+
'1': { '1': '1', '2': '2', '3': '3' }, // Impact = High
29+
'2': { '1': '2', '2': '3', '3': '4' }, // Impact = Medium
30+
'3': { '1': '3', '2': '4', '3': '5' } // Impact = Low
31+
};
32+
33+
// ----------------------------------------------------------------------
34+
// Step 3: Determine the new priority based on selected Impact/Urgency
35+
// ----------------------------------------------------------------------
36+
var newPriority = priorityMatrix[impact]?.[urgency]; // optional chaining prevents errors
37+
38+
// ----------------------------------------------------------------------
39+
// Step 4: Update the Priority field and inform the user
40+
// ----------------------------------------------------------------------
41+
if (newPriority) {
42+
// Only update if priority is different from current value
43+
if (g_form.getValue('priority') != newPriority) {
44+
g_form.setValue('priority', newPriority);
45+
46+
// Show message (works in both Classic UI and Next Experience)
47+
g_form.showFieldMsg('priority', 'Priority auto-updated based on Impact and Urgency', 'info');
48+
}
49+
} else {
50+
// Optional: clear priority if invalid combination is selected
51+
g_form.clearValue('priority');
52+
g_form.showFieldMsg('priority', 'Invalid Impact/Urgency combination — priority cleared', 'error');
53+
}
54+
55+
// ----------------------------------------------------------------------
56+
// End of Script
57+
// ----------------------------------------------------------------------
58+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
🧩 Readme: Prevent Rejection Without Comments – Client Script
2+
📘 Overview
3+
4+
This Client Script enforces that approvers must enter comments before rejecting a record in the Approval [sysapproval_approver] table.
5+
It ensures accountability, audit readiness, and clear justification for rejection decisions.
6+
7+
🧠 Use Case
8+
Field Details
9+
Table sysapproval_approver
10+
Type Client Script – onSubmit
11+
Purpose Prevent users from rejecting approvals without comments
12+
Business Value Ensures transparency and proper audit trail in approval workflows
13+
⚙️ Configuration Steps
14+
15+
Navigate to System Definition → Client Scripts.
16+
17+
Click New.
18+
19+
Fill the form as follows:
20+
21+
Field Value
22+
Name Prevent Rejection Without Comments
23+
Table sysapproval_approver
24+
UI Type All
25+
Type onSubmit
26+
Active ✅
27+
Applies on Update
28+
29+
Paste the following script in the Script field.
30+
31+
💻 Script
32+
function onSubmit() {
33+
// Get the current state value of the approval record
34+
var state = g_form.getValue('state');
35+
36+
// Get the comments entered by the approver
37+
var comments = g_form.getValue('comments');
38+
39+
// Check if the approver is trying to REJECT the record
40+
// The out-of-box (OOB) value for rejection in sysapproval_approver is "rejected"
41+
// If state is 'rejected' and comments are empty, stop the submission
42+
if (state == 'rejected' && !comments) {
43+
44+
// Display an error message to the user
45+
g_form.addErrorMessage('Please provide comments before rejecting the approval.');
46+
47+
// Prevent the form from being submitted (block save/update)
48+
return false;
49+
}
50+
51+
// Allow the form submission if validation passes
52+
return true;
53+
}
54+
55+
🧪 Example Scenario
56+
Field Value
57+
Approver John Doe
58+
State Rejected
59+
Comments (empty)
60+
61+
User Action: Clicks Update
62+
System Response: Shows error message —
63+
64+
“Please provide comments before rejecting the approval.”
65+
Record submission is blocked until comments are provided.
66+
67+
✅ Expected Outcome
68+
🚫 Prevents rejection without comments
69+
⚠️ Displays user-friendly validation message
70+
📝 Ensures that every rejection has a reason logged for compliance
71+
72+

0 commit comments

Comments
 (0)