Skip to content

Commit 5056cb6

Browse files
authored
Merge branch 'ServiceNowDevProgram:main' into user-impersonation-activity-logger
2 parents cd2c541 + 45dfc4b commit 5056cb6

File tree

22 files changed

+1379
-49
lines changed

22 files changed

+1379
-49
lines changed
97.6 KB
Loading
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
Bulk Update Worknotes
3+
4+
Script Type: UI Action, Table: incident, List banner button: True, Client: True, Show update: True, OnClick: functionName()
5+
6+
Script Type: UI Page Category: General
7+
8+
Goal: To update the worknotes for multiple tickets in a single view
9+
10+
Walk through of code: So in the incident List view we do have a list banner button called "Bulk Updates" so that was the UI Action configured with the script which has used the GlideModel API to call the UI page which is responsible to get the multiple tickets and worknotes value and then update to the respective ticket and store in the worknotes in journal entry. For this the HTML part in the UI page is configured with two fields, one for the multiple list of tickets, and then the worknotes field, and one submit button to save that into the table.
11+
And the Processing Script is used to get each ticket number and then check the valid tickets and query the respective table, and then update the worknotes of each respective ticket if it is valid. Otherwise, it won't update.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Table: incident, List banner button: True, Client: True, Show update: True, OnClick: bulkupdate()
2+
3+
function bulkupdate() {
4+
var modalT = new GlideModal("BulkUpdate", false, 1200);
5+
modalT.setTitle("Bulk Update Worknotes");
6+
modalT.render();
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function bulkupdate() {
2+
document.getElementById("spinner-btn").style.display = "block";
3+
document.getElementById("submit-btn").style.display = "none";
4+
5+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
3+
<j2:set var="jvar_hide_response_time" value="true" />
4+
<html lang="en">
5+
6+
<head>
7+
<meta charset="utf-8" />
8+
<meta name="viewport" content="width=device-width, initial-scale=1" />
9+
10+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" />
11+
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css" />
12+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" />
13+
14+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
15+
16+
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
17+
<script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
18+
<script src="https://cdn.datatables.net/1.13.7/js/dataTables.bootstrap5.min.js"></script>
19+
</head>
20+
21+
<body>
22+
<!-- Alert Message -->
23+
<div id="primary-message" style="display:none;" class="alert alert-primary" role="alert">
24+
25+
</div>
26+
<div id="error-message" style="display:none;" class="alert alert-danger" role="alert">
27+
Error - An error has occurred when trying to update Work Notes.
28+
</div>
29+
<div id="warning-message-invalid-entry" style="display:none;" class="alert alert-warning" role="alert">
30+
Warning - Invalid list of Incident Tickets or Work Note field. Please try again.
31+
</div>
32+
<div id="warning-message-invalid-tickets-valid-entry" style="display:none;" class="alert alert-warning" role="alert">
33+
34+
</div>
35+
36+
<!-- Bulk Update Work Notes Form -->
37+
<div id="form-div" class="container mt-3">
38+
39+
<g:ui_form>
40+
<div class="mb-3 mt-3">
41+
<label class="text-lg" for="ticket_list">Incident Ticket List</label>
42+
<input type="text" class="form-control text-sm" id="ticket_list" placeholder="Enter list of Incident Tickets, separated by commas. (Example: INC001001, INC001002, ...)" name="ticket_list" required="true" />
43+
</div>
44+
<div class="mb-3">
45+
<label class="text-lg" for="work_note_to_apply">Work Note to Apply</label>
46+
<textarea type="text" class="form-control text-sm" id="work_note_to_apply" placeholder="Enter work note to apply here." name="work_note_to_apply" required="true" rows="6" />
47+
</div>
48+
<div class="d-grid gap-2 col-6 mx-auto">
49+
<button id="submit-btn" class="btn btn-primary btn-lg text-lg" onclick="bulkupdate()">Submit</button>
50+
<button id="spinner-btn" style="display:none" class="btn btn-primary btn-lg text-lg" type="button" disabled="true">
51+
<span class="spinner-border spinner-border-lg me-2" role="status" aria-hidden="true"></span>
52+
Loading...
53+
</button>
54+
</div>
55+
</g:ui_form>
56+
57+
58+
</div>
59+
</body>
60+
<style>
61+
textarea {
62+
resize: none;
63+
}
64+
65+
.text-lg {
66+
//font-size: 1.125rem;
67+
font-size: large;
68+
line-height: 1.75rem;
69+
}
70+
71+
.text-md {
72+
//font-size: 1rem;
73+
font-size: medium;
74+
line-height: 1.5rem;
75+
}
76+
77+
.text-sm {
78+
//font-size: .75rem;
79+
font-size: small;
80+
line-height: 1rem;
81+
}
82+
83+
.text-xs {
84+
//font-size: .75rem;
85+
font-size: smaller;
86+
line-height: 1rem;
87+
}
88+
</style>
89+
90+
</html>
91+
</j:jelly>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// gs.info("Ticket List :"+ticket_list);
2+
3+
// Sepetation of ticket based on the comma.
4+
var ticketlist = ticket_list;
5+
var formatted_ticket_list = ticketlist.split(/[ ,]+/).filter(Boolean);
6+
var valid_ticket_list = [];
7+
var invalid_ticket_list = [];
8+
9+
10+
// Checks the first ten Incident ticket into an array which start with INC
11+
for (var i = 0; i < formatted_ticket_list.length; i++) {
12+
if (formatted_ticket_list[i].startsWith('INC')) {
13+
if (formatted_ticket_list[i].length == 10)
14+
valid_ticket_list.push(formatted_ticket_list[i]);
15+
else {
16+
invalid_ticket_list.push(formatted_ticket_list[i]);
17+
}
18+
} else {
19+
invalid_ticket_list.push(formatted_ticket_list[i]);
20+
}
21+
}
22+
23+
// Looping into each ticket to update the worknotes based on the table
24+
for (var k = 0; k < valid_ticket_list.length; k++) {
25+
var gr_inc = new GlideRecordSecure('incident');
26+
gr_inc.addQuery('number', valid_ticket_list[k]);
27+
gr_inc.query();
28+
29+
if (gr_inc._next()) {
30+
gr_inc['work_notes'] = work_note_to_apply;
31+
gr_inc.update();
32+
} else {
33+
//If the ticket number was not found, add to Invalid Ticket List
34+
invalid_ticket_list.push(valid_ticket_list[k]);
35+
}
36+
}
37+
56.4 KB
Loading
127 KB
Loading
14.8 KB
Loading
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# GlideRecord Performance Optimization Techniques
2+
3+
This collection provides advanced techniques for optimizing GlideRecord queries and database operations in ServiceNow.
4+
5+
## Overview
6+
7+
Performance optimization is crucial for maintaining responsive ServiceNow applications, especially when dealing with large datasets or complex queries. These snippets demonstrate best practices for efficient GlideRecord usage.
8+
9+
## Key Performance Principles
10+
11+
- **Minimize Database Roundtrips**: Use efficient query patterns
12+
- **Proper Indexing**: Leverage indexed fields in queries
13+
- **Batch Operations**: Process multiple records efficiently
14+
- **Query Optimization**: Use appropriate query methods
15+
- **Memory Management**: Handle large datasets responsibly
16+
17+
## Snippets Included
18+
19+
1. **optimized_batch_processing.js** - Efficient batch processing techniques
20+
2. **indexed_field_queries.js** - Leveraging database indexes
21+
3. **chunked_data_processing.js** - Processing large datasets in chunks
22+
4. **query_performance_comparison.js** - Performance comparison examples
23+
5. **memory_efficient_operations.js** - Memory-conscious GlideRecord usage
24+
25+
## Performance Monitoring
26+
27+
Always measure performance using:
28+
- `gs.log()` with timestamps for execution time
29+
- Database query metrics in Developer Tools
30+
- Performance Analytics for production monitoring
31+
32+
## Best Practices Summary
33+
34+
1. Always query on indexed fields when possible
35+
2. Use `setLimit()` for large result sets
36+
3. Avoid using `getRowCount()` on large tables
37+
4. Use `chooseWindow()` for pagination
38+
5. Consider using `GlideAggregate` for statistical queries
39+
6. Implement proper error handling and logging
40+
41+
## Related Documentation
42+
43+
- [ServiceNow GlideRecord API Documentation](https://developer.servicenow.com/dev.do#!/reference/api/tokyo/server/no-namespace/c_GlideRecordScopedAPI)
44+
- [Query Performance Best Practices](https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/managing-data/concept/query-performance.html)

0 commit comments

Comments
 (0)