Make field read-only based on dot-walking field

ChadLee4
Tera Contributor

Is it possible to make a field read-only if a checkbox on a dot-walking field is checked?

 

For example, I have a custom table in which records are associated to a user record (via a reference field). If that user record is inactive, I want to make the fields on the custom form to be read only. 

 

Is this possible? Would I have to do it from the user record or the custom form?

1 ACCEPTED SOLUTION

Edvin-Karalius
Tera Guru

Looks like the previous solutions did not consider reverting back the fields after they have been set to readonly.

Unfortunately you can't use the g_form.getEditableFields()
twice after you have locked the fields. so you will have to define your own array of fields that you would like to affect by this script.

here is my solution with .getReference()

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }
	
	//Add fields here
	var fieldsToControl = [
		'description',
		'short_description',
		'state'
	];

    g_form.getReference('assigned_to', function(e) {
		fieldsToControl.forEach(function(field){
			g_form.setReadOnly(field, e.active === 'false');
		});
    });
}

As a demo i used the "assigned_to" field as the reference field and the "active" field on the user as the checkbox.
Feel free to change those two in the code.

Now if you don't want to use getReference because it's not recommended by SN.
You can now use GlideRecord inside of client script.
Only downside is, if the user viewing the ticket does not have read permissions on your target gr table. they won't be able to do the query.

Here is the GlideRecord solution for client script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading) return;
    
	var gr = new GlideRecord('sys_user');
	
	if(!newValue ||! gr.get(newValue)) return;
	
	//Add fields to control here
	var fieldsToControl = [
		'description',
		'short_description',
		'state'
	];
	
	setFieldState(fieldsToControl, gr.getValue('active') === 'false');
	
    function setFieldState(fieldsArr, readOnly){
		fieldsArr.forEach(function(field){
			g_form.setReadOnly(field, readOnly);
		});
	}
}

I also added a bonus here to unlock the fields again if the reference field is cleared/is empty.

Here is a demo video:

chrome_75NqqTZ0u9.gif







 

View solution in original post

6 REPLIES 6

Tushar
Kilo Sage
Kilo Sage

Hi ,

 

correction -

 

Script Include

 

var getUserDetail = Class.create();
getUserDetail.prototype = {
initialize: function(request, response) {
},

// Function to check if the user is active
isUserActive: function(sysId) {
var user = new GlideRecord('sys_user');
if (user.get(sysId)) {
return user.active == 'true'; // Assuming active field is a boolean (true/false) field
}
return false; // Return false if user record is not found
},

type: 'getUserDetail'
};

 

 

client script -

 

function onLoad() {
var ga = new GlideAjax('getUserDetail');
ga.addParam('sysparm_name', 'isUserActive');
ga.addParam('sysparm_user', g_form.getValue('user'));
ga.getXMLAnswer(returnAjaxResponse);
}

function returnAjaxResponse(response) {
if (response == 'true') {
// User is active, fields remain editable
} else {
// User is inactive, make fields read-only
var fields = g_form.getEditableFields();
for (var x = 0; x < fields.length; x++) {
g_form.setReadOnly(fields[x], true);
}
}
}

 

 

 

 

Mark as correct and helpful if it solved your query.

Regards,
Tushar

 

Ravi Chandra_K
Kilo Patron
Kilo Patron

Hello @ChadLee4 

Greetings!

dot walking on client script is not possible. You will have to write GlideAjax script include 

and call it in your client script.

You can use the below onLoadclient script to make the form read only when user is inactivate.

script include:

isUserActive: function(){

var user = this.getParameter('sysparm_user');

var gr = new GlideRecord('sys_user');

gr.addQuery('sys_id', user);

gr.addActiveQuery();

gr.query();

return gr.hasNext();

}

 

onLoad Client Script 

function onLoad() {

  //Type appropriate comment here, and begin script below

var ga = new GlideAjax('getUserDetail');

ga.addParam('sysparm_name', 'isUserActive');

ga.addParam('sysparm_user', g_form.getValue('user');

ga.getXMLAnswer(returnAjaxResponse);

function returnAjaxResponse(response);

if(!response){

  {

  var fields = g_form.getEditableFields();

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

  g_form.setReadOnly(fields[x], true);

  }

  }

}

Help others to find a correct solution by marking the appropriate response as correct answer and helpful!!

 

Kind Regards,

Ravi Chandra.

Ravi Chandra_K
Kilo Patron
Kilo Patron

Hello @ChadLee4 

Greetings!

Any feedback on my reply? were you able to do this?

Please mark the answer as corrsct solution and helpful based on Impact.

Kind Regards,

Ravi Chandra.

mattystern
Kilo Sage

Hi @ChadLee4 

 

Here's a solution using an onChange client script and getReference. You need to set "Variable Name" to the name of your reference field and also can change values based on your form. I think you might also need to check the "Isolate Script" box.

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

	var b = g_form.getReference('person', callback); //name of your reference field

	function callback(b) {
		if(b.active=='false'){ //b can be dot walked to any field on person's reference
		var fields = g_form.getEditableFields();
		for (var x=0; x<fields.length;x++){
			g_form.setReadOnly(fields[x], true);
		}
		}
	}

}

 Hope this helps!

-Matt