Skip to content

Commit 3b8d029

Browse files
authored
Merge branch 'ServiceNowDevProgram:main' into main
2 parents a59cfcb + 2bf7d2a commit 3b8d029

File tree

38 files changed

+1621
-90
lines changed

38 files changed

+1621
-90
lines changed

Check Attachment

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
An onSubmit Client script that checks whether only one file is attached and also file type should be .doc, .pdf or .txt. Otherwise form will not be submitted and required error message will be displayed to user.
2+
3+
Note: Check this property - glide.attachment.extensions

CheckAttachmentFiletypr.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
function onSubmit() {
2+
var arr = [];
3+
var extension1 = '.txt';
4+
var extension2 = '.pdf';
5+
var extension3 = '.docx';
6+
var names = this.document.getElementsByClassName('get-attachment ng-binding ng-scope');
7+
for (var i = 0; i < names.length; i++) {
8+
var val = names[i].innerHTML;
9+
arr.push(val.toString());
10+
}
11+
12+
var countRequired = 1;
13+
if (window == null) {
14+
if (this.document.getElementsByClassName('get-attachment').length != countRequired) {
15+
g_form.addErrorMessage('You can add only one attachment');
16+
return false;
17+
}
18+
}
19+
20+
for (var j = 0; j < arr.length; j++) {
21+
if ((arr[j].indexOf(extension1) > -1) || (arr[j].indexOf(extension2) > -1) || (arr[j].indexOf(extension3) > -1)) {
22+
return true;
23+
} else {
24+
g_form.addErrorMessage('Unsupported file format. Please attach files with extensions .txt, .pdf, .doc');
25+
return false;
26+
}
27+
28+
}
29+
30+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Date Range Validation (Within 30 Days) in Client Side
2+
3+
This ServiceNow client script provides real-time date validation for form fields, ensuring users can only select dates within a specific 30-day window from today's date. The script runs automatically when a user changes a date field value, providing immediate feedback and preventing invalid date submissions.
4+
5+
The script validates that any date entered in a form field meets these criteria:
6+
Minimum Date: Today's date (no past dates allowed)
7+
Maximum Date: 30 days from today's date
8+
Real-time Validation: Instant feedback as users type or select dates
9+
User-friendly Errors: Clear error messages explaining the valid date range
10+
Automatic Field Clearing: Invalid dates are automatically cleared to prevent submission
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
2+
if (isLoading || newValue === '') {
3+
return;
4+
}
5+
6+
var todayDate = new Date();
7+
var futureDate = new Date();
8+
futureDate.setDate(futureDate.getDate() + 30);
9+
10+
var todayDateStr = formatDate(todayDate, g_user_date_format);
11+
var futureDateStr = formatDate(futureDate, g_user_date_format);
12+
13+
var selectedDateNum = getDateFromFormat(newValue, g_user_date_format);
14+
var todayDateNum = getDateFromFormat(todayDateStr, g_user_date_format);
15+
var futureDateNum = getDateFromFormat(futureDateStr, g_user_date_format);
16+
17+
if (selectedDateNum < todayDateNum || selectedDateNum > futureDateNum) {
18+
g_form.showFieldMsg(control, 'Date must be between today and 30 days from today', 'error');
19+
g_form.clearValue(control);
20+
} else {
21+
g_form.hideFieldMsg(control);
22+
}
23+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
An `onLoad` client script that validates required fields in specific ServiceNow form views.
2+
3+
This ServiceNow client script provides automatic validation of required form fields when users access specific form views. The script runs immediately when a form loads and checks that critical fields are populated, displaying user-friendly error messages for any missing required information. This ensures data completeness and improves form submission success rates by catching validation issues early in the user workflow.
4+
5+
What This Script Does:
6+
The onLoad client script performs comprehensive field validation with these key capabilities:
7+
View-Specific Validation: Only triggers validation when accessing a designated form view
8+
Multiple Field Support: Validates multiple required fields simultaneously in a single operation
9+
Smart Field Detection: Uses field labels (not technical names) in error messages for better user experience
10+
Consolidated Error Display: Shows all missing required fields in a single, clear error message
11+
Immediate Feedback: Provides instant validation results as soon as the form loads
12+
Non-Intrusive Design: Displays informational errors without blocking form interaction
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function onLoad(){
2+
var targetViewName = 'your_target_view_name';
3+
var requiredFields = ['field1', 'field2', 'field3'];
4+
5+
var currentViewName = g_form.getViewName();
6+
7+
if (currentViewName === targetViewName) {
8+
var emptyFields = [];
9+
10+
for (var i = 0; i < requiredFields.length; i++) {
11+
var fieldValue = g_form.getValue(requiredFields[i]);
12+
if (!fieldValue || fieldValue.trim() === '') {
13+
emptyFields.push(g_form.getLabelOf(requiredFields[i]));
14+
}
15+
}
16+
17+
if (emptyFields.length > 0) {
18+
var errorMessage = "The following required fields cannot be empty: " +
19+
emptyFields.join(', ');
20+
g_form.addErrorMessage(errorMessage);
21+
}
22+
}
23+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Form Dirty State Prevention
2+
3+
## Overview
4+
Detects form changes and warns users before navigating away or closing the form, preventing accidental data loss.
5+
6+
## What It Does
7+
- Tracks form field changes (dirty state)
8+
- Warns user before leaving unsaved form
9+
- Allows user to cancel navigation
10+
- Works with all form fields
11+
- Prevents accidental data loss
12+
- Clean, reusable pattern
13+
14+
## Use Cases
15+
- Complex multi-field forms
16+
- Long data entry forms
17+
- Forms with expensive operations
18+
- Critical data entry (financial, medical)
19+
- Any form where accidental exit would cause issues
20+
21+
## Files
22+
- `form_dirty_state_manager.js` - Client Script to manage form state
23+
24+
## How to Use
25+
26+
### Step 1: Create Client Script
27+
1. Go to **System Definition > Scripts** (any table)
28+
2. Create new Client Script
29+
3. Set **Type** to "onChange"
30+
4. Copy code from `form_dirty_state_manager.js`
31+
5. Set to run on any field
32+
33+
### Step 2: Add Navigation Handler
34+
1. Add to form's onLoad script:
35+
```javascript
36+
// Initialize dirty state tracking
37+
var formStateManager = new FormDirtyStateManager();
38+
```
39+
40+
### Step 3: Test
41+
1. Open form and make changes
42+
2. Try to navigate away without saving
43+
3. User sees warning dialog
44+
4. User can choose to stay or leave
45+
46+
## Example Usage
47+
```javascript
48+
// Automatically tracks all field changes
49+
// When user tries to close/navigate:
50+
// "You have unsaved changes. Do you want to leave?"
51+
// - Leave (discard changes)
52+
// - Stay (return to form)
53+
```
54+
55+
## Key Features
56+
- ✅ Detects any field change
57+
- ✅ Persistent across form interactions
58+
- ✅ Works with new records and updates
59+
- ✅ Ignores read-only fields
60+
- ✅ Resets after save
61+
- ✅ No performance impact
62+
63+
## Output Examples
64+
```
65+
User opens form and changes a field
66+
→ Form marked as "dirty"
67+
68+
User clicks close/back button
69+
→ Warning dialog appears: "You have unsaved changes"
70+
71+
User clicks Leave
72+
→ Form closes, changes discarded
73+
74+
User clicks Save then navigates
75+
→ No warning (form is clean)
76+
```
77+
78+
## Customization
79+
```javascript
80+
// Customize warning message
81+
var warningMessage = "Warning: You have unsaved changes!";
82+
83+
// Add specific field tracking
84+
g_form.addOnFieldChange('priority', myCustomHandler);
85+
86+
// Reset dirty flag after save
87+
g_form.save(); // Automatically triggers cleanup
88+
```
89+
90+
## Requirements
91+
- ServiceNow instance
92+
- Client Script access
93+
- Any table form
94+
95+
## Browser Support
96+
- Chrome, Firefox, Safari, Edge (all modern browsers)
97+
- Works with ServiceNow classic and modern UI
98+
99+
## Related APIs
100+
- [g_form API](https://docs.servicenow.com/bundle/sandiego-application-development/page/app-store/dev_apps/concept/c_FormAPI.html)
101+
- [Client Script Events](https://docs.servicenow.com/bundle/sandiego-application-development/page/app-store/dev_apps/concept/c_ClientScriptEvents.html)
102+
- [Form Field Changes](https://docs.servicenow.com/bundle/sandiego-application-development/page/app-store/dev_apps/concept/c_FieldChanges.html)
103+
104+
## Best Practices
105+
- Apply to important data entry forms
106+
- Test with real users
107+
- Consider accessibility for screen readers
108+
- Use with save shortcuts (Ctrl+S)
109+
- Combine with auto-save patterns
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Client Script: Form Dirty State Manager
2+
// Purpose: Track form changes and warn user before leaving with unsaved changes
3+
4+
var FormDirtyStateManager = Class.create();
5+
FormDirtyStateManager.prototype = {
6+
initialize: function() {
7+
this.isDirty = false;
8+
this.setupFieldChangeListeners();
9+
this.setupNavigationWarning();
10+
},
11+
12+
// Mark form as changed when any field is modified
13+
setupFieldChangeListeners: function() {
14+
var self = this;
15+
g_form.addOnFieldChange('*', function(control, oldValue, newValue, isLoading) {
16+
// Ignore system updates and form loads
17+
if (isLoading || oldValue === newValue) {
18+
return;
19+
}
20+
self.setDirty(true);
21+
});
22+
},
23+
24+
// Warn user before navigating away with unsaved changes
25+
setupNavigationWarning: function() {
26+
var self = this;
27+
28+
// Warn on form close attempt
29+
window.addEventListener('beforeunload', function(e) {
30+
if (self.isDirty && !g_form.isNewRecord()) {
31+
e.preventDefault();
32+
e.returnValue = 'You have unsaved changes. Do you want to leave?';
33+
return e.returnValue;
34+
}
35+
});
36+
37+
// Warn on GlideForm navigation
38+
g_form.addOnSave(function() {
39+
// Reset dirty flag after successful save
40+
self.setDirty(false);
41+
return true;
42+
});
43+
},
44+
45+
setDirty: function(isDirty) {
46+
this.isDirty = isDirty;
47+
if (isDirty) {
48+
// Optional: Show visual indicator
49+
document.title = '* ' + document.title.replace(/^\* /, '');
50+
gs.info('[Form State] Unsaved changes detected');
51+
}
52+
},
53+
54+
isDirtyState: function() {
55+
return this.isDirty;
56+
}
57+
};
58+
59+
// Initialize on form load
60+
var formDirtyState = new FormDirtyStateManager();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
ServiceNow Script: Find Oldest Open Incidents per Group
2+
This script leverages GlideAggregate to efficiently find the oldest active incident for each assignment group. This is a powerful tool for monitoring and reporting on potential service level agreement (SLA) risks and improving incident management processes.
3+
Overview
4+
The script performs the following actions:
5+
Initializes GlideAggregate: Creates an aggregate query on the incident table.
6+
Filters Active Incidents: Uses addActiveQuery() to restrict the search to only open (active) incidents.
7+
Aggregates by Minimum Date: Finds the minimum (MIN) opened_at date, which represents the oldest record.
8+
Groups by Assignment Group: Groups the results by the assignment_group to get a separate result for each team.
9+
Iterates and Logs: Loops through the query results and logs the assignment group and the opening date of its oldest open incident.
10+
How to use
11+
This script is intended to be used in a server-side context within a ServiceNow instance. Common use cases include:
12+
Scheduled Job: Run this script on a regular schedule (e.g., daily) to generate a report on aging incidents.
13+
Script Include: Incorporate the logic into a reusable function within a Script Include, allowing other scripts to call it.
14+
15+
Use code with caution.
16+
17+
Installation
18+
As a Scheduled Job
19+
Navigate to System Definition > Scheduled Jobs.
20+
Click New and select Automatically run a script of your choosing.
21+
Name the job (e.g., Find Oldest Open Incidents).
22+
Set your desired frequency and time.
23+
Paste the script into the Run this script field.
24+
Save and activate the job.
25+
As a Script Include
26+
Navigate to System Definition > Script Includes.
27+
Click New.
28+
Name it (e.g., IncidentHelper).
29+
API Name: global.IncidentHelper
30+
31+
32+
Customization
33+
Change the output: Modify the gs.info() line to instead write to a custom log, send an email, or create a report.
34+
Refine the query: Add more addQuery() statements to filter incidents by other criteria, such as priority or category.
35+
Change the aggregate: Use MAX instead of MIN to find the newest incident in each group.
36+
Get incident details: To get the actual incident record (e.g., its number), you would need to perform a secondary GlideRecord query based on the aggregated data.
37+
Dependencies
38+
This script uses standard ServiceNow APIs (GlideAggregate, gs). No external libraries are required.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var ga = new GlideAggregate('incident');
2+
ga.addActiveQuery();
3+
ga.addAggregate('MIN', 'opened_at');
4+
ga.groupBy('assignment_group');
5+
ga.query();
6+
7+
while (ga.next()) {
8+
var group = ga.assignment_group.getDisplayValue();
9+
var oldestIncidentDate = ga.getAggregate('MIN', 'opened_at');
10+
gs.info("Oldest open incident for " + group + " was created on: " + oldestIncidentDate);
11+
}

0 commit comments

Comments
 (0)