Need help on my UI Policy script for the start_at field in metric definition to limit day to be 1st

ChuanYanF
Tera Guru

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');
    }
}

 

1 ACCEPTED SOLUTION

ChuanYanF
Tera Guru

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'
});

View solution in original post

3 REPLIES 3

Juhi Poddar
Kilo Patron

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

ChuanYanF
Tera Guru

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'
});

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