- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2025 06:27 PM
Dear experts,
I am trying to create a UI Policy script function that will limit the field start_at in metric definition to can only choose the first of each month and if not it will clear the value and prompt and error box. For example, 1st of June, 1st of September and etc. But I think currently my script is not working properly. Any advise or help on this?
function onCondition() {
var startDate = g_form.getValue('start_at');
if (startDate) {
var dateObj = new Date(startDate);
var dayOfMonth = dateObj.getDate();
if (dayOfMonth !== 1) {
g_form.showErrorBox('start_at', "Date should be the first of the month");
} else {
g_form.hideErrorBox('start_at');
}
} else {
g_form.hideErrorBox('start_at');
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2025 07:44 PM
So I changed the client script and also the script include
Client Script:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
if (g_scratchpad.scoreExists) {
g_form.setReadOnly("start_at", true);
}
return;
}
var ga = new GlideAjax('GRCMetricAjax');
ga.addParam('sysparm_name', 'isStartDateValid');
ga.addParam('sysparm_startDate', g_form.getValue('start_at'));
ga.getXMLAnswer(function(answer) {
if (answer == "false") {
// Clear the value first
g_form.clearValue('start_at');
// Then show the error after a short delay
setTimeout(function() {
g_form.showErrorBox('start_at', "Start date must be in the future and must be the first day of a month.");
}, 200); // 200ms delay ensures error box stays visible
} else {
g_form.hideErrorBox('start_at');
}
});
}
Script Include:
var GRCMetricAjax = Class.create();
GRCMetricAjax.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
updateMetricFields: function() {
var metricDefSysID = this.getParameter('sysparm_metric_defn');
var fieldsObj = {
'metricDefTable': '',
'sysId': '',
'aggregateField': '',
'referenceField': '',
'criteria': '',
'name': '',
'description': '',
'table': '',
'type': '',
'category': '',
'confidentialConfig': {
'isConfidential': '',
'allowedUsers': '',
'allowedGroups': ''
}
};
var mdefGR = new GlideRecordSecure('sn_grc_metric_base_definition');
mdefGR.get(metricDefSysID);
var tableName = "";
if (mdefGR.isValidRecord()) {
tableName = mdefGR.sys_class_name.toString();
fieldsObj['metricDefTable'] = tableName;
var metricDefGR = new GlideRecordSecure(tableName);
metricDefGR.get(metricDefSysID);
if (metricDefGR.isValidRecord()) {
fieldsObj['description'] = String(metricDefGR.description);
fieldsObj['name'] = String(metricDefGR.name);
fieldsObj['sysId'] = metricDefSysID;
if (tableName == "sn_grc_metric_definition") {
var table = String(metricDefGR.reference_table);
fieldsObj['table'] = table;
var aggregationField = String(metricDefGR.field);
var referenceField = String(metricDefGR.reference_field);
fieldsObj['criteria'] = String(metricDefGR.criteria);
fieldsObj['type'] = String(metricDefGR.type);
fieldsObj['category'] = String(metricDefGR.category);
fieldsObj['aggregateField'] = new GRCMetric().getFieldDisplayValue(table, aggregationField);
fieldsObj['referenceField'] = new GRCMetric().getFieldDisplayValue(table, referenceField);
}
var confidentialConfig = {
'isConfidential': String(metricDefGR.is_confidential),
'allowedUsers': String(metricDefGR.confidential_users),
'allowedGroups': String(metricDefGR.confidential_user_groups)
};
fieldsObj['confidentialConfig'] = confidentialConfig;
}
}
return JSON.stringify(fieldsObj);
},
fetchMetricDefClass: function() {
var classValue = '';
var metricDefSysID = this.getParameter('sysparm_metric_defn');
if (metricDefSysID == '') return '';
classValue = this.getMetricDefClass(metricDefSysID);
return classValue;
},
getMetricDefClass: function(mdId) {
var classValue = '';
var metricDefGR = new GlideRecordSecure('sn_grc_metric_base_definition');
metricDefGR.get(mdId);
if (metricDefGR.isValidRecord()) {
classValue = metricDefGR.getValue('metric_class');
}
return classValue;
},
isStartDateValid: function() {
var startDate = this.getParameter('sysparm_startDate');
if (!startDate) return 'false';
var startAt = new GlideDate();
startAt.setDisplayValue(startDate);
var presentDate = new GlideDateTime().getLocalDate();
// Check 1: Date must be in the future
if (startAt.before(presentDate)) {
return 'false';
}
// Check 2: Date must be the 1st of the month
var day = parseInt(startAt.getDayOfMonthLocalTime(), 10); // GlideDate gives this method
if (day !== 1) {
return 'false';
}
return 'true';
},
getChoicesOfFrequency: function() {
var choices = GlideChoiceList.getChoiceList(MetricConstants.TABLE.BASE_METRIC_DEFINITION, "frequency");
var frequencyChoiceObj = {};
for (var i = 0; i < choices.getSize(); i++) {
frequencyChoiceObj[choices.getChoice(i).getValue()] = choices.getChoice(i).getLabel();
}
return JSON.stringify(frequencyChoiceObj);
},
type: 'GRCMetricAjax'
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2025 07:06 PM
Hello @ChuanYanF
Try this script:
function onCondition() {
var startDate = g_form.getValue('start_at');
if (startDate) {
// Parse the date safely
var parts = startDate.split('-');
// var year = parseInt(parts[0], 10);
// var month = parseInt(parts[1], 10) - 1; // month is 0-based
var day = parseInt(parts[2], 10);
if (day !== 1) {
g_form.clearValue('start_at');
g_form.showErrorBox('start_at', "Please select the 1st of a month only.");
} else {
g_form.hideErrorBox('start_at');
}
} else {
g_form.hideErrorBox('start_at');
}
}
Hope this helps!
"If you found my answer helpful, please like and mark it as an "accepted solution". It helps future readers to locate the solution easily and supports the community!"
Thank You
Juhi Poddar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2025 07:44 PM
So I changed the client script and also the script include
Client Script:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
if (g_scratchpad.scoreExists) {
g_form.setReadOnly("start_at", true);
}
return;
}
var ga = new GlideAjax('GRCMetricAjax');
ga.addParam('sysparm_name', 'isStartDateValid');
ga.addParam('sysparm_startDate', g_form.getValue('start_at'));
ga.getXMLAnswer(function(answer) {
if (answer == "false") {
// Clear the value first
g_form.clearValue('start_at');
// Then show the error after a short delay
setTimeout(function() {
g_form.showErrorBox('start_at', "Start date must be in the future and must be the first day of a month.");
}, 200); // 200ms delay ensures error box stays visible
} else {
g_form.hideErrorBox('start_at');
}
});
}
Script Include:
var GRCMetricAjax = Class.create();
GRCMetricAjax.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
updateMetricFields: function() {
var metricDefSysID = this.getParameter('sysparm_metric_defn');
var fieldsObj = {
'metricDefTable': '',
'sysId': '',
'aggregateField': '',
'referenceField': '',
'criteria': '',
'name': '',
'description': '',
'table': '',
'type': '',
'category': '',
'confidentialConfig': {
'isConfidential': '',
'allowedUsers': '',
'allowedGroups': ''
}
};
var mdefGR = new GlideRecordSecure('sn_grc_metric_base_definition');
mdefGR.get(metricDefSysID);
var tableName = "";
if (mdefGR.isValidRecord()) {
tableName = mdefGR.sys_class_name.toString();
fieldsObj['metricDefTable'] = tableName;
var metricDefGR = new GlideRecordSecure(tableName);
metricDefGR.get(metricDefSysID);
if (metricDefGR.isValidRecord()) {
fieldsObj['description'] = String(metricDefGR.description);
fieldsObj['name'] = String(metricDefGR.name);
fieldsObj['sysId'] = metricDefSysID;
if (tableName == "sn_grc_metric_definition") {
var table = String(metricDefGR.reference_table);
fieldsObj['table'] = table;
var aggregationField = String(metricDefGR.field);
var referenceField = String(metricDefGR.reference_field);
fieldsObj['criteria'] = String(metricDefGR.criteria);
fieldsObj['type'] = String(metricDefGR.type);
fieldsObj['category'] = String(metricDefGR.category);
fieldsObj['aggregateField'] = new GRCMetric().getFieldDisplayValue(table, aggregationField);
fieldsObj['referenceField'] = new GRCMetric().getFieldDisplayValue(table, referenceField);
}
var confidentialConfig = {
'isConfidential': String(metricDefGR.is_confidential),
'allowedUsers': String(metricDefGR.confidential_users),
'allowedGroups': String(metricDefGR.confidential_user_groups)
};
fieldsObj['confidentialConfig'] = confidentialConfig;
}
}
return JSON.stringify(fieldsObj);
},
fetchMetricDefClass: function() {
var classValue = '';
var metricDefSysID = this.getParameter('sysparm_metric_defn');
if (metricDefSysID == '') return '';
classValue = this.getMetricDefClass(metricDefSysID);
return classValue;
},
getMetricDefClass: function(mdId) {
var classValue = '';
var metricDefGR = new GlideRecordSecure('sn_grc_metric_base_definition');
metricDefGR.get(mdId);
if (metricDefGR.isValidRecord()) {
classValue = metricDefGR.getValue('metric_class');
}
return classValue;
},
isStartDateValid: function() {
var startDate = this.getParameter('sysparm_startDate');
if (!startDate) return 'false';
var startAt = new GlideDate();
startAt.setDisplayValue(startDate);
var presentDate = new GlideDateTime().getLocalDate();
// Check 1: Date must be in the future
if (startAt.before(presentDate)) {
return 'false';
}
// Check 2: Date must be the 1st of the month
var day = parseInt(startAt.getDayOfMonthLocalTime(), 10); // GlideDate gives this method
if (day !== 1) {
return 'false';
}
return 'true';
},
getChoicesOfFrequency: function() {
var choices = GlideChoiceList.getChoiceList(MetricConstants.TABLE.BASE_METRIC_DEFINITION, "frequency");
var frequencyChoiceObj = {};
for (var i = 0; i < choices.getSize(); i++) {
frequencyChoiceObj[choices.getChoice(i).getValue()] = choices.getChoice(i).getLabel();
}
return JSON.stringify(frequencyChoiceObj);
},
type: 'GRCMetricAjax'
});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-20-2025 08:33 PM
Hi @ChuanYanF ,
instead of GlideAjax approach
Try this
as you have to get info from the server just for validation
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
if (g_scratchpad.scoreExists) {
g_form.setReadOnly("start_at", true);
}
return;
}
var dateIndex = g_user_date_format.indexOf('dd');
if (parseInt(newValue.slice(dateIndex, dateIndex + 2)) > 1) {
g_form.clearValue('start_at');
// Then show the error after a short delay
setTimeout(function() {
g_form.showErrorBox('start_at', "Start date must be in the future and must be the first day of a month.");
}, 200); // 200ms delay ensures error box stays visible
} else {
g_form.hideErrorBox('start_at');
}
}
Please mark my answer as helpful/correct if it resolves your query.
Regards,
Chaitanya