Interested in a ServiceNow event built for developers? Registration for now[dev]26 is officially open!

is there any way to get all visible fields and visible variables on the form using a business rule

Alon Grod
Tera Expert


Hi,

I have a task record that being created using a record producer.

Is there any way to get all visible fields and all visible variables on the form using a business rule.
The goal is to make a pdf file and attach it to the record that will contains all visible fields and visible variables and there corresponding values

8 REPLIES 8

mohithreddy
Mega Contributor

A business rule runs server-side and has no concept of "visible on the form" - visibility comes from the view/section layout, ACLs and client-side UI policies. The closest server-side definition is: fields in the form section layout, readable by the user, and non-empty. Variables are separate.

 

1) Fields on the form view - read the section layout:

 

function getViewFields(tableName, viewName) {

  var out = [];

  var sec = new GlideRecord('sys_ui_section');

  sec.addQuery('name', tableName);

  sec.addQuery('view.name', viewName || 'Default view');

  sec.query();

  while (sec.next()) {

    var el = new GlideRecord('sys_ui_element');

    el.addQuery('sys_ui_section', sec.getUniqueValue());

    el.addNotNullQuery('element');

    el.orderBy('position');

    el.query();

    while (el.next()) out.push(el.getValue('element'));

  }

  return out;

}

 

2) In the rule, resolve label/value and respect read access:

 

var rows = [];

var fields = getViewFields(current.getTableName(), 'Default view');

for (var i = 0; i < fields.length; i++) {

  var ge = current.getElement(fields[i]);

  if (!ge || !ge.canRead()) continue;

  var val = current.getDisplayValue(fields[i]);

  if (!val) continue;

  rows.push({label: ge.getLabel(), value: val});

}

 

If layout does not matter, just loop current.getFields() with canRead() and nil() checks.

 

3) Record producer variables: mapped ones are already fields. Unmapped ones live in question_answer against the created record:

 

var qa = new GlideRecord('question_answer');

qa.addQuery('table_name', current.getTableName());

qa.addQuery('table_sys_id', current.getUniqueValue());

qa.query();

while (qa.next()) rows.push({label: qa.question.getDisplayValue(), value: qa.getDisplayValue('value')});

 

Skip Label/Container/HTML variable types.

 

4) PDF: build HTML from rows and convert/attach with sn_pdfgeneratorutils.PDFGenerationAPI (or GlideDocumentV2 on older releases). Do it in an async business rule so the record and its question_answer rows are committed.

 

Caveat: fields hidden only by a UI policy or client script cannot be detected server-side. If that matters, collect the list client-side by looping g_form.getFieldNames() with g_form.isVisible(), pass it in via a hidden field or GlideAjax, and have the rule use that list.

Rafael Batistot
Kilo Patron

Hi @Alon Grod 

 

As far as i know no, because Business Rules run entirely on the server and have no awareness of client-side form layouts or visibility.

 

You must use a client-side script (such as an ⁠onSubmit⁠ script using ⁠g_form.isVisible()⁠) to gather visible fields and pass them to the server.

 

If this response was helpful, please mark it as Helpful and, if applicable, as Correct.
This helps other users find accurate and useful information more easily

ajmalmuhamm
Tera Contributor

Hey @Alon Grod ,

 

 

Yes, you can achieve this, but there is an important distinction: a Business Rule runs server-side, so it cannot directly know which fields are visually visible on the user's form. Visibility controlled by UI Policies, Client Scripts, or form configuration is a client-side concept.

For the record fields, you can use getElements() / getFields() to iterate through the fields on the record. ServiceNow's GlideRecord.getElements() returns the fields available on the GlideRecord.

For the Record Producer variables, you can access them through current.variables. ServiceNow also provides current.variables.getElements() to iterate through the variables associated with the record, including their labels and values.

For example:

 

 
// Record fields
var fields = current.getElements();

for (var i = 0; i < fields.size(); i++) {
    var field = fields.get(i);

    gs.info(
        field.getLabel() + ' = ' +
        field.getDisplayValue()
    );
}

// Record Producer variables
var variables = current.variables.getElements();

for (var j = 0; j < variables.length; j++) {
    var variable = variables[j];

    gs.info(
        variable.getLabel() + ' = ' +
        variable.getQuestion().getValue()
    );
}
 
 

However, I wouldn't recommend trying to determine "visible" fields from the Business Rule. If you need the PDF to represent exactly what the user saw on the Record Producer, you should base the PDF generation on the Record Producer/variable configuration, rather than the resulting task form.

A cleaner architecture would be:

Record Producer → Task created → After Business Rule/Flow → Generate document → Attach PDF

You can build the PDF content from:

  • Task fields you want to include
  • Record Producer variables
  • Variable labels
  • Display values
  • Conditional logic for variables that were actually answered

Also, ServiceNow provides GlideSPScriptable.getRecordVariables() specifically for retrieving Service Catalog variables associated with records created through a Record Producer.

So, yes, dynamically collecting the fields and variables is possible, but "visible on the form" cannot reliably be determined by a server-side Business Rule because UI Policies and Client Scripts aren't evaluated there.

For a PDF requirement, I'd recommend creating a Script Include/utility that builds a field-variable data structure, then passing that to your PDF/document generation logic. This will be much easier to maintain than putting all the PDF logic directly inside the Business Rule.

vaishali231
Kilo Sage

Hey @Alon Grod 

 Business Rule runs server-side, it cannot directly determine whether a field or Record Producer variable was visible on the user's form.you can use client side  APIs g_form.isVisible() 

For  task fields using current.getElements() and the Record Producer variables using:

var variables = current.variables.getElements();

for (var i = 0; i < variables.length; i++) {

    gs.info(variables[i].getLabel() + ' = ' + variables[i].getValue());

}

 

For  PDF to contain exactly what was visible to the user at submission time, the better approach is to capture the visible fields/variables on the client side and store them .

Then the Business Rule can read that data, generate the PDF, and attach it to the task.

*************************************************************************************************************************************

If this response helps, please mark it as Accept as Solution and Helpful.

Doing so helps others in the community and encourages me to keep contributing.

Regards

Vaishali Singh
Linkedin - https://www.linkedin.com/in/vaishali-singh-2273361bb