Skip to content

Commit a105610

Browse files
authored
Merge branch 'main' into hacktoberfest2025-contribution
2 parents 8cbd557 + c990397 commit a105610

File tree

68 files changed

+2292
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2292
-18
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function onChange(control, oldValue, newValue, isLoading) {
2+
if (isLoading) {
3+
return;
4+
}
5+
6+
var maxChars = 100;//count of charaters
7+
var currentLength = newValue.length;
8+
9+
// Clear previous messages
10+
g_form.clearMessages();
11+
12+
// Show info message
13+
g_form.addInfoMessage('Character count: ' + currentLength + ' / ' + maxChars);
14+
15+
if (currentLength > maxChars) {
16+
// Show error message
17+
g_form.addErrorMessage('Character limit exceeded! Please shorten your text.');
18+
g_form.showFieldMsg('short_description', 'Too many characters!', 'error');
19+
20+
// Make field mandatory to block submission
21+
g_form.setMandatory('short_description', true);
22+
} else {
23+
// Remove mandatory if valid
24+
g_form.setMandatory('short_description', false);
25+
}
26+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This onChange Catalog Client Script displays the current character count for a text field and enforces a maximum limit by showing error messages and making the field mandatory to prevent form submission when exceeded.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
**User Location Validator**
2+
This script restricts form submissions based on the physical location of the user. The current location is obtained using the browser’s geolocation API (latitude and longitude), and is then compared against the user's assigned business location stored in ServiceNow.
3+
4+
**How It Works**
5+
- The **server-side Script Include**(UserLocationUtils.js) fetches the assigned business location’s latitude, longitude, and name for the logged-in user.
6+
- The **client-side script**(User Location Validator.js) uses the browser API to obtain the current latitude and longitude of the user at form submission.
7+
- It calculates the distance between these two points using the **Haversine formula**, which accounts for the spherical shape of the Earth.
8+
- The key constant `earthRadiusKm = 6371` defines the Earth's radius in kilometers and is essential for accurate distance calculation.
9+
- If the user’s current location is outside the predefined radius (default 10 km), the form submission is blocked with an error message showing the distance and allowed location.
10+
- If the user is within range, a confirmation info message is displayed and the submission proceeds.
11+
12+
**Sample Output**
13+
- **Success:** "Location validated successfully within range of Headquarters."
14+
- **Failure:** "You are 15.23 km away from your registered location: Headquarters."
15+
16+
**Usage Notes**
17+
- Requires user consent for geolocation access in the browser.
18+
- The script uses descriptive variable names for clarity and maintainability.
19+
- Suitable for scenarios requiring geo-fencing compliance or location-based workflow restrictions.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function onSubmit() {
2+
// Check if the browser supports geolocation
3+
if ("geolocation" in navigator) {
4+
// Request current user position
5+
navigator.geolocation.getCurrentPosition(function(position) {
6+
var currentLatitude = position.coords.latitude; // Current user latitude
7+
var currentLongitude = position.coords.longitude; // Current user longitude
8+
9+
// Allowed business location coordinates fetched from server
10+
var allowedLatitude = locData.latitude;
11+
var allowedLongitude = locData.longitude;
12+
var locationName = locData.name;
13+
14+
// Earth's radius in kilometers - constant used in distance calculation formula
15+
var earthRadiusKm = 6371;
16+
17+
// Convert degree differences to radians
18+
var deltaLatitude = (currentLatitude - allowedLatitude) * Math.PI / 180;
19+
var deltaLongitude = (currentLongitude - allowedLongitude) * Math.PI / 180;
20+
21+
// Haversine formula components
22+
var a = Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) +
23+
Math.cos(allowedLatitude * Math.PI / 180) *
24+
Math.cos(currentLatitude * Math.PI / 180) *
25+
Math.sin(deltaLongitude / 2) * Math.sin(deltaLongitude / 2);
26+
27+
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
28+
29+
// Calculate distance in kilometers between current and allowed locations
30+
var distanceKm = earthRadiusKm * c;
31+
32+
// Check if user's current distance exceeds tolerance (e.g., 10 km)
33+
if (distanceKm > 10) {
34+
alert("You are " + distanceKm.toFixed(2) + " km away from your registered location: " + locationName);
35+
g_form.addErrorMessage("Location validation failed: Submission outside the allowed radius.");
36+
return false; // Cancel form submission
37+
} else {
38+
g_form.addInfoMessage("Location validated successfully within range of " + locationName);
39+
return true; // Allow form submission
40+
}
41+
}, function(error) {
42+
alert("Geolocation error: " + error.message);
43+
return false; // Stop submission if geolocation fails
44+
});
45+
46+
// Prevent form submission while waiting for async geolocation result
47+
return false;
48+
} else {
49+
g_form.addErrorMessage("Geolocation is not supported by your browser.");
50+
return false; // Block if geolocation API unsupported
51+
}
52+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
var UserLocationUtils = Class.create();
2+
UserLocationUtils.prototype = {
3+
initialize: function() {
4+
5+
},
6+
getUserLocationCoords: function() {
7+
var user = gs.getUser();
8+
var loc = user.getRecord().location;
9+
if (loc) {
10+
var locGR = new GlideRecord('cmn_location');
11+
if (locGR.get(loc))
12+
return {
13+
latitude: parseFloat(locGR.latitude),
14+
longitude: parseFloat(locGR.longitude),
15+
name: locGR.name.toString()
16+
};
17+
}
18+
return null;
19+
},
20+
21+
type: 'UserLocationUtils'
22+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
This solution dynamically provides users with real-time feedback on the length of a text input field (like short_description or a single-line text variable).
2+
It immediately displays a character count beneath the field and uses visual cues to indicate when a pre-defined character limit has been reached or exceeded.
3+
4+
This is a vital User Experience (UX) enhancement that helps agents and users write concise, actionable information, leading to improved data quality and better integration reliability.
5+
6+
Name Live_Character_Counter_ShortDesc_OnLoad
7+
Table : Custom Table or Incident
8+
Type onChange
9+
Field : Description
10+
UI Type All
11+
Isolate Script false
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
2+
3+
var FIELD_NAME = 'short_description';
4+
var MAX_CHARS = 100;
5+
var currentLength = newValue.length;
6+
var counterId = FIELD_NAME + '_counter_label';
7+
if (typeof g_form.getControl(FIELD_NAME) !== 'undefined' && !document.getElementById(counterId)) {
8+
var controlElement = g_form.getControl(FIELD_NAME);
9+
var counterLabel = document.createElement('div');
10+
counterLabel.setAttribute('id', counterId);
11+
counterLabel.style.fontSize = '85%';
12+
counterLabel.style.marginTop = '2px';
13+
controlElement.parentNode.insertBefore(counterLabel, controlElement.nextSibling);
14+
}
15+
var counterElement = document.getElementById(counterId);
16+
17+
if (counterElement) {
18+
var remaining = MAX_CHARS - currentLength;
19+
20+
21+
counterElement.innerHTML = 'Characters remaining: ' + remaining + ' (Max: ' + MAX_CHARS + ')';
22+
23+
// Apply red color if the limit is exceeded
24+
if (remaining < 0) {
25+
counterElement.style.color = 'red';
26+
} else {
27+
// Revert color if back within limits
28+
counterElement.style.color = 'inherit';
29+
}
30+
}
31+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Table: Time Worked [task_time_worked]
2+
Type: onsubmit
3+
4+
#Objective :
5+
Ensure that time entries (represented by the work_date field) are not submitted after 8:00 PM CST on two key dates:
6+
The 16th of the month and The last day of the month
7+
If a user tries to submit time for a current or past date after the cut-off time, the submission is blocked and a clear error message is displayed.
8+
9+
#Business Scenario
10+
Imagine a consulting firm where employees log billable hours against customer cases. There are internal controls in place that lock the timekeeping system after a certain cut-off time to ensure accurate payroll and billing.
11+
12+
The finance department requires that:
13+
On the 16th and last day of each month, submissions must be in before 8:00 PM CST.
14+
If employees miss the deadline, they can only log time for future dates (not today or the past).
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
function onSubmit() {
2+
// Cutoff time for submission in CST.
3+
var cutoffTime = "20:00:00";
4+
5+
// Get the current date and time in CST
6+
var currentDate = new Date();
7+
var currentCSTDate = new Date(
8+
currentDate.toLocaleString("en-US", {
9+
timeZone: "America/Chicago"
10+
})
11+
);
12+
13+
// Get time from current CST date
14+
var currentCSTTime = currentCSTDate.toTimeString().substring(0, 8);
15+
16+
// Get last day of the month
17+
var dayOfMonth = currentCSTDate.getDate();
18+
var lastDayOfMonth = new Date(
19+
currentCSTDate.getFullYear(),
20+
currentCSTDate.getMonth() + 1,
21+
0
22+
).getDate();
23+
24+
if ((dayOfMonth === 16 || dayOfMonth === lastDayOfMonth) && currentCSTTime > cutoffTime) {
25+
var workDate = g_form.getValue("work_date");
26+
27+
if (workDate) {
28+
var formattedWorkDate = new Date(workDate + "T00:00:00");
29+
// If work_date is on or before current date, block submission
30+
if (formattedWorkDate <= currentCSTDate) {
31+
g_form.addErrorMessage(
32+
"The time period closed for time submission at 8:00 PM CST. Time must be billed in the next time period." + ": " + lastDayOfMonth
33+
);
34+
return false;
35+
}
36+
}
37+
}
38+
return true;
39+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Table: sn_customerservice_case
2+
Type: OnChange
3+
Field: Priority
4+
5+
Use Case:
6+
Make additional comments mandatory on priority change for the case table.

0 commit comments

Comments
 (0)