Script Includes
GlideAjax Utility with Multiple Functions
A comprehensive Script Include demonstrating multiple client-callable functions in a single utility class.
var AjaxUtils = Class.create();
AjaxUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
/**
* Validate if a value exists in a table field
* Useful for duplicate checking before submission
*/
checkDuplicate: function() {
var table = this.getParameter('sysparm_table');
var field = this.getParameter('sysparm_field');
var value = this.getParameter('sysparm_value');
var excludeId = this.getParameter('sysparm_exclude_id'); // For updates
if (!table || !field || !value) {
return JSON.stringify({error: 'Missing required parameters'});
}
var gr = new GlideRecord(table);
gr.addQuery(field, value);
// Exclude current record when checking for update
if (excludeId) {
gr.addQuery('sys_id', '!=', excludeId);
}
gr.query();
var result = {
isDuplicate: gr.hasNext(),
count: gr.getRowCount()
};
return JSON.stringify(result);
},
/**
* Get formatted user information
*/
getUserInfo: function() {
var userId = this.getParameter('sysparm_user_id') || gs.getUserID();
var grUser = new GlideRecord('sys_user');
if (!grUser.get(userId)) {
return JSON.stringify({error: 'User not found'});
}
var userInfo = {
sys_id: grUser.sys_id.toString(),
name: grUser.name.toString(),
email: grUser.email.toString(),
phone: grUser.phone.toString(),
title: grUser.title.toString(),
department: grUser.department.getDisplayValue(),
location: grUser.location.getDisplayValue(),
manager: grUser.manager.getDisplayValue(),
manager_email: grUser.manager.email.toString(),
vip: grUser.vip.toString() === 'true',
active: grUser.active.toString() === 'true'
};
return JSON.stringify(userInfo);
},
/**
* Get available assignment groups for a category
*/
getAssignmentGroups: function() {
var category = this.getParameter('sysparm_category');
var activeOnly = this.getParameter('sysparm_active_only') === 'true';
var groups = [];
var grGroup = new GlideRecord('sys_user_group');
if (category) {
grGroup.addQuery('u_category', category);
}
if (activeOnly) {
grGroup.addQuery('active', 'true');
}
grGroup.orderBy('name');
grGroup.query();
while (grGroup.next()) {
groups.push({
sys_id: grGroup.sys_id.toString(),
name: grGroup.name.toString(),
description: grGroup.description.toString(),
manager: grGroup.manager.getDisplayValue(),
email: grGroup.email.toString()
});
}
return JSON.stringify({groups: groups, count: groups.length});
},
/**
* Calculate business days between two dates
*/
calculateBusinessDays: function() {
var startDate = this.getParameter('sysparm_start_date');
var endDate = this.getParameter('sysparm_end_date');
var scheduleId = this.getParameter('sysparm_schedule') || '8-5 weekdays excluding holidays';
if (!startDate || !endDate) {
return JSON.stringify({error: 'Start and end dates required'});
}
var schedule = new GlideSchedule(scheduleId);
var start = new GlideDateTime(startDate);
var end = new GlideDateTime(endDate);
var duration = schedule.duration(start, end);
var businessDays = duration.getByFormat('dd');
var businessHours = duration.getByFormat('HH');
return JSON.stringify({
businessDays: businessDays,
businessHours: businessHours,
totalSeconds: duration.getNumericValue()
});
},
/**
* Validate field value against business rules
*/
validateField: function() {
var table = this.getParameter('sysparm_table');
var field = this.getParameter('sysparm_field');
var value = this.getParameter('sysparm_value');
var result = {
valid: true,
message: '',
suggestions: []
};
// Example validations
if (field === 'email') {
var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(value)) {
result.valid = false;
result.message = 'Invalid email format';
}
}
if (field === 'phone') {
// Remove non-numeric characters
var digitsOnly = value.replace(/\D/g, '');
if (digitsOnly.length < 10) {
result.valid = false;
result.message = 'Phone number must have at least 10 digits';
}
}
if (field === 'short_description') {
if (value.length < 10) {
result.valid = false;
result.message = 'Description too short (minimum 10 characters)';
}
// Check for common words to suggest better descriptions
var vagueWords = ['issue', 'problem', 'error', 'help'];
var hasVagueWords = vagueWords.some(function(word) {
return value.toLowerCase().indexOf(word) !== -1;
});
if (hasVagueWords) {
result.suggestions.push('Be more specific about the issue');
}
}
return JSON.stringify(result);
},
/**
* Search records with fuzzy matching
*/
searchRecords: function() {
var table = this.getParameter('sysparm_table');
var searchTerm = this.getParameter('sysparm_search_term');
var searchFields = this.getParameter('sysparm_fields'); // Comma-separated
var maxResults = parseInt(this.getParameter('sysparm_max_results') || '10');
if (!table || !searchTerm) {
return JSON.stringify({error: 'Table and search term required'});
}
var fields = searchFields ? searchFields.split(',') : ['name', 'number'];
var results = [];
var gr = new GlideRecord(table);
// Build OR query for multiple fields
var qc = gr.addQuery(fields[0], 'CONTAINS', searchTerm);
for (var i = 1; i < fields.length; i++) {
qc.addOrCondition(fields[i], 'CONTAINS', searchTerm);
}
gr.setLimit(maxResults);
gr.query();
while (gr.next()) {
var record = {
sys_id: gr.sys_id.toString(),
display_value: gr.getDisplayValue()
};
// Add requested fields
fields.forEach(function(field) {
if (gr.isValidField(field)) {
record[field] = gr.getValue(field);
}
});
results.push(record);
}
return JSON.stringify({
results: results,
count: results.length,
searchTerm: searchTerm
});
},
type: 'AjaxUtils'
});How to use it
1. Create a new Script Include named 'AjaxUtils' 2. Check 'Client callable' checkbox 3. Set 'Extends' to 'AbstractAjaxProcessor' 4. Copy the code above 5. Call from Client Scripts using GlideAjax: var ga = new GlideAjax('AjaxUtils'); ga.addParam('sysparm_name', 'checkDuplicate'); ga.addParam('sysparm_table', 'incident'); ga.addParam('sysparm_field', 'number'); ga.addParam('sysparm_value', 'INC0001'); ga.getXMLAnswer(callback);
Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.