The Verbose Log

Now Bending: Tables and Fields

August 03, 2020

Get Field Type

There are a lot of things that you can do with a GlideRecord object without ever actually querying for anything or inserting a record.

If you would like to get the type of a field regardless of if a field exists on a starting table or not you can use a GlideElement without ever performing a single query.

//┌─────────────────────────────────────────────────────────────
//! @getColumnType
//! Get a single field type
//└─────────────────────────────────────────────────────────────
getColumnType: function (table, field) {
    if (!table || !field) {
        return null;
    }

    var gr = new GlideRecord(table),
        ge = gr.getElement(field),
        type = ge.toString() != null ? ge.getED().getInternalType() : null;

    return {
        value: type,
        display_value: type,
    };
}

It may not be completely clear, but all we had to do was create a new GlideRecord object and include the table parameter. From here we can call getElement for the field in question and then check to make sure that GlideElement actually exists.

With that out of the way all we have to do is perform ge.getED().getInternalType() to return a field type.

Example

//┌─────────────────────────────────────────────────────────────
//! For example
//└─────────────────────────────────────────────────────────────
this.getColumnType('incident', 'caller.first_name');

//┌─────────────────────────────────────────────────────────────
//! Will return
//└─────────────────────────────────────────────────────────────
{
    value: 'string',
	display_value: 'string'
}

By avoiding the need to perform a query, we got the information we needed without taxing the system and can move on to more important things.

Get Field Label

This works very similarly to getColumnType in that you don’t even need to perform a query or an insert of a GlideRecord to get the information you need. Even if a field needs to be dot-walked to.

//┌─────────────────────────────────────────────────────────────
//! @getColumnLabel
//! Get a single field column label
//└─────────────────────────────────────────────────────────────
getColumnLabel: function (table, field) {
    if (!table || !field) {
        return null;
    }

    var gr = new GlideRecord(table),
        ge = gr.getElement(field),
        label = ge.toString() != null ? ge.getLabel() : null;

    return {
        value: label,
        display_value: label,
    };
}

By once again accessing the GlideRecord and then acquiring the GlideElement for a field you can easily access the function getLabel().

Never stress out about finding the label of a field again. By adding these types of simple functions to a reusable script include you can save yourself a lot of trouble and effort.

Example

//┌─────────────────────────────────────────────────────────────
//! For example
//└─────────────────────────────────────────────────────────────
this.getColumnLabel('incident', 'caller.first_name');

//┌─────────────────────────────────────────────────────────────
//! Will return
//└─────────────────────────────────────────────────────────────
{
    value: 'First Name',
    display_value: 'First Name'
}

Get Field Choices

This next function will require quite a bit more logic than the previous two solutions, but you can still access a fields choice list without ever actually performing a single query. This can be a real life-saver when end users need to access a fields choice list but don’t have read access to the sys_choice table.

Before wasting time and resources we will need to add some checks to ensure that the field is either a string or a choice field. We can also account for true/false fields if we want to pre-define two options for true (1) and false (0).

For whatever reason, when we use GlideRecord this time around, we still don’t have to query for a record, but we do have to run gr.initialize() to propagate some properties on the GlideRecord object.

//┌─────────────────────────────────────────────────────────────
//! @getColumnChoices
//! Get a single field column choices
//└─────────────────────────────────────────────────────────────
getColumnChoices: function (table, field) {
    if (!table || !field) {
        return null;
    }

    var gr = new GlideRecord(table),
        choiceValues,
        choiceLabel,
        choices = [],
        type = this.getColumnType(table, field);

    if (type.value != 'string' && type.value != 'choice' && type.value != 'boolean') {
        return [];
    }

    if (type.value == 'boolean') {
        return [
            { value: '1', label: 'True' },
            { value: '0', label: 'False' },
        ];
    }

    gr.initialize();

    choiceValues = gr[field].getChoices();

    choiceValues.forEach(function (choice) {
        gr[field] = choice;
        choiceLabel = gr[field].getChoiceValue();

        choices.push({
            value: choice,
            label: choiceLabel,
        });
    });

    return choices;
}

After using gr.initialize(); you can easily access the field on that record and run the getChoices function. This will provide you with an object you can iterate over to get each choice’s label and value.

By iterating over that object with the forEach command we are essentially looping through all of the choices and filling our own empty array with regular JavaScript objects that contain both the choice value and choice labels.

Example

//┌─────────────────────────────────────────────────────────────
//! For example
//└─────────────────────────────────────────────────────────────
this.getColumnChoices('incident', 'state');

//┌─────────────────────────────────────────────────────────────
//! Will return
//└─────────────────────────────────────────────────────────────
[
    {
        value: 1,
        display_value: 'New'
    }, {
        value: 2,
        display_value: 'In Progress'
    }, {
        value: 3,
        display_value: 'On Hold'
    } ...
]

There you have, we avoided performing any queries or inserts of a GlideRecord and we don’t need read access to the sys_choice table.

Future

There are many more snippets of code that can be reused over and over. As time goes on I will continue to update this list and provide even more simple solutions for stupidly annoying problems.