Normalization/Duplicate in Table Search From Catalog Task Variable Input

Okeefe
Tera Contributor

Hello, I'm currently working on modifying a Script Include and Client Script that takes input from a catalog task variable and searches a table for duplicates. My current implementation works for exact matches but I need help making it more flexible. I want it to handle cases where variations of the same input—like "test model" and "testmodel" are both treated as duplicates if "Test Model" exists on the table. My current code only performs an exact search and doesn't include any normalization. I need guidance on how to modify it so that both variations trigger an error if they already exist in the table. This is my current code: 

 

Script Include: 

 

 

var CheckDuplicateDeviceModel = Class.create();
CheckDuplicateDeviceModel.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    checkDeviceExists: function() {
        var deviceName = this.getParameter('sysparm_device_model');

        if (!deviceName) {
            return 'false'; 
        }
        deviceName = deviceName.trim().toLowerCase();

        var gr = new GlideRecord('cmdb_hardware_product_model');
        gr.addQuery('name', deviceName);
        gr.query();

        if (gr.next()) {
            return 'true';
        }
        return 'false'; 
    }
});

 

 

 

Catalog Client Script: 

 

 

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue.trim() === '') {
        return;
    }
    g_form.clearMessages();

    var ajax = new GlideAjax('CheckDuplicateDeviceModel');
    ajax.addParam('sysparm_name', 'checkDeviceExists');
    ajax.addParam('sysparm_device_model', newValue);
    ajax.getXMLAnswer(function(response) {
        if (response === 'true') { 
            g_form.addErrorMessage('This Model Already Exists. Please enter a unique model.');
            g_form.showFieldMsg('device_model', 'This Model Already Exists.', 'error');
            g_form.setReadOnly('state', true);
            g_form.setValue('u_duplicate_model', 'true');
        } else {
            g_form.setReadOnly('state', false);
            g_form.setValue('u_duplicate_model', 'false');
        }
    });
}

 

 

1 ACCEPTED SOLUTION

You could try adding some gs.info lines in the Script Include to find out where it's going wrong.  I was testing my approach within a Fix Script with a static string value, so it must not like performing the string actions on the value from the getParameter.  You can try doing that part in the client before passing it to the SI:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue.trim() === '') {
        return;
    }
    g_form.clearMessages();

    var deviceName = newValue.toString().toLowerCase().replace(/\s+/g, '');
    alert(deviceName);
    var ajax = new GlideAjax('CheckDuplicateDeviceModel');
    ajax.addParam('sysparm_name', 'checkDeviceExists');
    ajax.addParam('sysparm_device_model', deviceName);
    ajax.getXMLAnswer(function(response) {
        if (response === 'true') { 
            g_form.addErrorMessage('This Model Already Exists. Please enter a unique model.');
            g_form.showFieldMsg('device_model', 'This Model Already Exists.', 'error');
            g_form.setReadOnly('state', true);
            g_form.setValue('u_duplicate_model', 'true');
        } else {
            g_form.setReadOnly('state', false);
            g_form.setValue('u_duplicate_model', 'false');
        }
    });
}
var CheckDuplicateDeviceModel = Class.create();
CheckDuplicateDeviceModel.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    checkDeviceExists: function() {
        var deviceName = this.getParameter('sysparm_device_model');

        if (!deviceName) {
            return 'false'; 
        }
        
        var gr = new GlideRecord('cmdb_hardware_product_model');
        gr.query();
        while (gr.next()) {
            if (gr.name.toString().toLowerCase().replace(/\s+/g, '') == deviceName) {
	            return 'true';
            }
        }
        return 'false'; 
    }
});

View solution in original post

4 REPLIES 4

Brad Bowman
Kilo Patron
Kilo Patron

addQuery lines in GlideRecords already perform case-insensitive searches, so you would get the same results without the toLowerCase in the Script Include.  Here's an approach to removing white space and converting case in an if statement:

var CheckDuplicateDeviceModel = Class.create();
CheckDuplicateDeviceModel.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    checkDeviceExists: function() {
        var deviceName = this.getParameter('sysparm_device_model');

        if (!deviceName) {
            return 'false'; 
        }
        
        var gr = new GlideRecord('cmdb_hardware_product_model');
        gr.query();
        while (gr.next()) {
            if (gr.name.toString().toLowerCase().replace(/\s+/g, '') == deviceName.toString().toLowerCase().replace(/\s+/g, '')) {
	            return 'true';
            }
        }
        return 'false'; 
    }
});

Hi Brad, 

Thank you for the response. After trying your script include it stopped the duplicate functionality entirely. I debugged a bit and realized the AJAX response back to the client script is null which is what is causing it to stop working. Do you have any ideas of what could be causing this null behavior? 

You could try adding some gs.info lines in the Script Include to find out where it's going wrong.  I was testing my approach within a Fix Script with a static string value, so it must not like performing the string actions on the value from the getParameter.  You can try doing that part in the client before passing it to the SI:

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue.trim() === '') {
        return;
    }
    g_form.clearMessages();

    var deviceName = newValue.toString().toLowerCase().replace(/\s+/g, '');
    alert(deviceName);
    var ajax = new GlideAjax('CheckDuplicateDeviceModel');
    ajax.addParam('sysparm_name', 'checkDeviceExists');
    ajax.addParam('sysparm_device_model', deviceName);
    ajax.getXMLAnswer(function(response) {
        if (response === 'true') { 
            g_form.addErrorMessage('This Model Already Exists. Please enter a unique model.');
            g_form.showFieldMsg('device_model', 'This Model Already Exists.', 'error');
            g_form.setReadOnly('state', true);
            g_form.setValue('u_duplicate_model', 'true');
        } else {
            g_form.setReadOnly('state', false);
            g_form.setValue('u_duplicate_model', 'false');
        }
    });
}
var CheckDuplicateDeviceModel = Class.create();
CheckDuplicateDeviceModel.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    checkDeviceExists: function() {
        var deviceName = this.getParameter('sysparm_device_model');

        if (!deviceName) {
            return 'false'; 
        }
        
        var gr = new GlideRecord('cmdb_hardware_product_model');
        gr.query();
        while (gr.next()) {
            if (gr.name.toString().toLowerCase().replace(/\s+/g, '') == deviceName) {
	            return 'true';
            }
        }
        return 'false'; 
    }
});

Thank you for all the help, that worked.