show record values in HTML field in backend, NOT SP NOT widgets

woodyfairley
Tera Guru

Hello Experts, I wish you all well.

I am using HTML fields in my form to allow users to add their content to the backend form similar to the "Build Terms and Conditions" UI Action and how it allows users to create records containing language blocks (terms and conditions for a contract) into the form itself in the backend. In the PDI the UI Action is named: "build_terms" on the table: "ast_contract".

They want to incorporate field values directly into their HTML content, but I do not know how to enable this directly within the HTML field, similar to a UI Macro.

I am doing this for them in the UI Macro language by using "$[current.field_name]" to display the field's value, but they want to replicate this same behavior in their HTML field content blocks so that a record's field value is inserted into the text when the setValue happens. I will continue my research and add a solution when I find it, but hoping one of you experts can show us the right way to do this. My initial psuedo-code is as follows:

The table I am using for the Service Descriptions (HTML-formatted user input):

0. USER IS ENTERING INFORMATION INTO A HTML FIELD AND WANTS TO REFER TO A FIELD VALUE IN THE AGREEMENT RECORD

1. var hotAgreement = new GlideRecord(agreement_table);

2. hotAgreement.get(g_form.getValue(agreement_reference_field_in_service_record);

3. USE HOTAGREEMENT FOR VALUES COLLECTION AND ASSIGNMENT IN HTML FIELD

4.

The table containing the contract/agreements (target for service descriptions)

1. USERS CLICK THE BUILD AGREEMENT TERMS CUSTOM UI ACTION, THIS PART WORKS

2. HTML CONTENT CONTAINS VALUES FROM THE AGREEMENT RECORD FIELDS, WANT TO DO THIS

Kind Regards,

Woody

15 REPLIES 15

woodyfairley
Tera Guru

Good news! I constructed a UI Action client script that replaces ${field_name} with the field's value in html fields on the form, enabling users to add customized formatted language incorporating field values into their contracts and agreements. My roadmap is to eventually use their html fields to produce a signed pdf dynamically from the record. But today, I want to release this UI Action, which has one remaining bug: I do not know how to iterate through an array loop to capture a series of g_scratchpad values harvested from the record. Has anyone done this before with success?

 

Found a workable solution: instead of using "g_scratchpad.hotFields[i]" use "g_scratchpad[hotFields[i]]" and this will iterate through the array's values while assigning the scratchpad values as desired. Thanks to Jon Barnes in the post below, about using scratchpad in a workflow. Solved: Re: Dynamic workflow scratchpad variable names - ServiceNow Community

 

The scratchpad variable are working (Display BR) and really only collect the Display Value for the user reference fields. I optimized the code and now it sporadically overwrites previous iterations, so I have to fix it, but here is the code for the UI Action (all client based scripting, so use console.log to add messages, view them in the browser console). Since it loops through all of the non-empty html fields, it can be clicked multiple times to ensure every placeholder is changed.

 

Best practice for this tool is to create a single html file with the placeholders for as many field values as required, then copy/paste the code into multiple agreements/contracts, then when it is time to sign, simply click the UI Action, confirming that the placeholders are replaced with the values, clicking multiple times if necessary, then clicking to save the record.

Kind Regards,

Woody

 

 

 

function insertFieldValues() {

    var hotFields = [];
    var refFields = [];
    var htmlFields = [];
    var dirtyFields = [];

    //Get all fields on the form
    var fields = g_form.getEditableFields();

    //Iterate through each field to check if it is visible, build arrays
    fields.forEach(function(field) {
        //Get the field type
        var fieldType = g_form.getControl(field).type;

        //Check if field is visible and if type does not contain 'html'
        if (g_form.isVisible(field) && g_form.getValue(field) != "" && !fieldType.includes('textarea')) {
            hotFields.push(field);
        }
        //Check if field is visible and if type contains 'html' aka 'textarea'
        if (fieldType.includes('textarea') && g_form.getValue(field) != "") {
            htmlFields.push(field);
        }
    });
	//Iterate through the html array
    htmlFields.forEach(function(field) {
        var htmlContent = g_form.getValue(field);
        var dirtyFieldCounter = 0;
		//Iterate through the non-html array for every html field
        for (var i = 0; i < hotFields.length; i++) {
            var fieldValue = g_form.getValue(hotFields[i]); //Grab the field value
			//Identiy reference fields, use display value instead of sysid
            if (fieldValue.length === 32) {
                var scratchFieldValue = g_scratchpad[hotFields[i]];
				fieldValue = scratchFieldValue;
				refFields.push(hotFields[i]);
            }
            //setting up for the regex replace action
            var fieldPlaceholder = '\\$\\{' + hotFields[i] + '\\}'; //Define the placeholder pattern
            if (htmlContent.indexOf(hotFields[i]) > -1) {
                var regex = new RegExp(fieldPlaceholder, 'g');
                var newHtmlContent = htmlContent.replace(regex, fieldValue);
                g_form.setValue(field, newHtmlContent);
                dirtyFieldCounter += 1;
            }
        }
        if (dirtyFieldCounter > 0) {
            dirtyFields.push(field);
        }
    });
	alert("Confirm changes, then click UPDATE or UPDATE AND STAY to save to the cloud.");
}