hiding the subcatgory with respect to category in client script

Dushyant Siroh
Tera Expert
function onLoad() {
//Type appropriate comment here, and begin script below
var category = g_form.getvalue('category');
if(category == 'Database'){
g_form.removeOption('subcategory', 'Oracle');

}
 
please check this code where this issue ?
 
}
1 ACCEPTED SOLUTION

Robbie
Kilo Patron
Kilo Patron

Hi @Dushyant Siroh,

 

The first of obvious issues I see with the above script are case related - for example the method of getValue() - getvalue() does not exist and will throw an error.

Additionally, please note at the scripting layer, the script evaluates the actual stored value and not the display value. (database and oracle). 

 

However, fundamentally there's more to consider. Firstly, you would not want this only onLoad as what happens if the value is changed after the page has loaded? Should the value still be available - assume not.

Therefore you'd need an onChange script which (would also run onLoad). But wait, there's more sadly... as Subcategory is set up as a dependent field to Category, the values won't be loaded on the Subcategory until after the onChange or onLoad event - so this still won't work.

 

But don't worry, this is a common scenario and something ServiceNow have an article for. Check the below link.

I've also copy and pasted it just in case links break in the future (as they do over time).

 

To help others (and for me to gain recognition for my efforts), please mark this response correct by clicking on Accept as Solution and/or Kudos.




Thanks, Robbie

 

SN Article: https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB1641021

 

Summary

Not Able To Remove An Option Using Client Scripts When There Is A Dependent Field. How To Do That?

Scenario:

  • 1. You have an incident record
  • 2. On that, you have a category field
    • With values, like: Software, Hardware, Network
  • 3. You have a subcategory field that is dependent of the category field
    • Software: (Email / Operating System)
    • Hardware: (CPU / Desk / Keyboard)
    • Network: (DHCP / DNS / VPN)
  • 4. You need to remove a value from the subcategory when a specific category is selected
    • Remove subcategory email option when software category is selected

 

When you use a dependent field, this cannot be done and the reason for that is because the client scripts are called first and the dependent logic is in place after that moving all the values back into the field.

 

Instructions

You can use this workaround:

 

1. Create a script include to simulate the dependent values with:

Active: Checked

Client callable: Checked

Protection policy: None

Script:

var fetchChoiceValues = Class.create();
fetchChoiceValues.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	fetch: function() {
		var results = [],
		lang = gs.getSession().getUser().getLanguage(),
		choiceTable = 'sys_choice',
		tgtFld = this.getParameter( 'sysparm_tgt_fld' ),
		tgtTbl = this.getParameter( 'sysparm_tgt_tbl' ),
		dpnVal = this.getParameter( 'sysparm_dpn_val' ) || false;

		// Fetch choice records (this script assumes the choice table is sys_choice)
		var gr = new GlideRecord( choiceTable );
		gr.addEncodedQuery( 'name=' + tgtTbl + '^element=' + tgtFld + '^inactive=false^language=' + lang );
		
		// Optional dependent value
		if ( dpnVal )
			gr.addQuery( 'dependent_value', dpnVal );

		gr.orderBy( 'sequence' );
		gr.orderBy( 'label' );
		gr.query();

		while( gr.next() ) {
			results.push( { 
				label: gr.label.toString(),
				value: gr.value.toString(),
				seq:   gr.sequence.toString()
			});
		}

		var resp = this.newItem( 'result' );
		resp.setAttribute( 'choices', JSON.stringify( results ));
	},

    type: 'fetchChoiceValues'
});

 

2. Create a onLoad client script to load the data with

Isolate script: Checked

Table: incident

Active: Checked

Global: Checked

Type: onLoad

UI Type: All

Script:

function onLoad() {
	// Fetch the field choices from the server
	var ga = new GlideAjax( 'fetchChoiceValues' );
	ga.addParam( 'sysparm_name', 'fetch' );
	ga.addParam( 'sysparm_tgt_fld', 'subcategory' );
	ga.addParam( 'sysparm_tgt_tbl', 'incident'    );
	ga.addParam( 'sysparm_dpn_val', ( g_form.getValue( 'category' ) || 'inquiry' ));

	ga.getXML( function( res ) {
		// Parse the server response
		var result = res.responseXML.getElementsByTagName( 'result' );
		var choices = JSON.parse( result[0].getAttribute( 'choices' ));

		// Clear the existing choices
		g_form.clearOptions( 'subcategory' );

		// Populate the new choices
		for ( var i = 0, cl = choices.length; i < cl; ++i )
			g_form.addOption( 'subcategory', choices[i].value, choices[i].label );
	});
}

 

3. Create an onChange client script to handed the logic to remove the entry when the category is selected with

Isolate script: Checked

Active: Checked

Table: incident

Global: Checked

Type: onChange

UI Type: All

Field name: Category

Script:

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

	// Fetch the field choices from the server
	var ga = new GlideAjax( 'fetchChoiceValues' );
	ga.addParam( 'sysparm_name', 'fetch' );
	ga.addParam( 'sysparm_tgt_fld', 'subcategory' );
	ga.addParam( 'sysparm_tgt_tbl', 'incident'    );
	ga.addParam( 'sysparm_dpn_val', newValue      );

	ga.getXML( function( res ) {
		// Parse the server response
		var result = res.responseXML.getElementsByTagName( 'result' );
		var choices = JSON.parse( result[0].getAttribute( 'choices' ));

		// Clear the existing choices
		g_form.clearOptions( 'subcategory' );

		// Populate the new choices
		for ( var i = 0, cl = choices.length; i < cl; ++i )
			g_form.addOption( 'subcategory', choices[i].value, choices[i].label );

		// Now we can remove the email option
		if ( newValue === "software" )
			g_form.removeOption( 'subcategory', 'email' );
	});
}

 

View solution in original post

8 REPLIES 8

@Sandeep Rajput  i already fix it but not working, i think error is different  we can't achieve this requirement with this way 

@Dushyant Siroh This script triggers onLoad. Hence will only work for the first time when the form loads. Are you under the impression that the option will get removed as soon as you change the category to 'database' on the form then for that you need an onChange script as follows.

 

 

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

    //Type appropriate comment here, and begin script below
    var category = g_form.getValue('category');
    if (category == 'database') {
        g_form.removeOption('subcategory', 'oracle');
    }

}

 

Robbie
Kilo Patron
Kilo Patron

Hi @Dushyant Siroh,

 

The first of obvious issues I see with the above script are case related - for example the method of getValue() - getvalue() does not exist and will throw an error.

Additionally, please note at the scripting layer, the script evaluates the actual stored value and not the display value. (database and oracle). 

 

However, fundamentally there's more to consider. Firstly, you would not want this only onLoad as what happens if the value is changed after the page has loaded? Should the value still be available - assume not.

Therefore you'd need an onChange script which (would also run onLoad). But wait, there's more sadly... as Subcategory is set up as a dependent field to Category, the values won't be loaded on the Subcategory until after the onChange or onLoad event - so this still won't work.

 

But don't worry, this is a common scenario and something ServiceNow have an article for. Check the below link.

I've also copy and pasted it just in case links break in the future (as they do over time).

 

To help others (and for me to gain recognition for my efforts), please mark this response correct by clicking on Accept as Solution and/or Kudos.




Thanks, Robbie

 

SN Article: https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB1641021

 

Summary

Not Able To Remove An Option Using Client Scripts When There Is A Dependent Field. How To Do That?

Scenario:

  • 1. You have an incident record
  • 2. On that, you have a category field
    • With values, like: Software, Hardware, Network
  • 3. You have a subcategory field that is dependent of the category field
    • Software: (Email / Operating System)
    • Hardware: (CPU / Desk / Keyboard)
    • Network: (DHCP / DNS / VPN)
  • 4. You need to remove a value from the subcategory when a specific category is selected
    • Remove subcategory email option when software category is selected

 

When you use a dependent field, this cannot be done and the reason for that is because the client scripts are called first and the dependent logic is in place after that moving all the values back into the field.

 

Instructions

You can use this workaround:

 

1. Create a script include to simulate the dependent values with:

Active: Checked

Client callable: Checked

Protection policy: None

Script:

var fetchChoiceValues = Class.create();
fetchChoiceValues.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	fetch: function() {
		var results = [],
		lang = gs.getSession().getUser().getLanguage(),
		choiceTable = 'sys_choice',
		tgtFld = this.getParameter( 'sysparm_tgt_fld' ),
		tgtTbl = this.getParameter( 'sysparm_tgt_tbl' ),
		dpnVal = this.getParameter( 'sysparm_dpn_val' ) || false;

		// Fetch choice records (this script assumes the choice table is sys_choice)
		var gr = new GlideRecord( choiceTable );
		gr.addEncodedQuery( 'name=' + tgtTbl + '^element=' + tgtFld + '^inactive=false^language=' + lang );
		
		// Optional dependent value
		if ( dpnVal )
			gr.addQuery( 'dependent_value', dpnVal );

		gr.orderBy( 'sequence' );
		gr.orderBy( 'label' );
		gr.query();

		while( gr.next() ) {
			results.push( { 
				label: gr.label.toString(),
				value: gr.value.toString(),
				seq:   gr.sequence.toString()
			});
		}

		var resp = this.newItem( 'result' );
		resp.setAttribute( 'choices', JSON.stringify( results ));
	},

    type: 'fetchChoiceValues'
});

 

2. Create a onLoad client script to load the data with

Isolate script: Checked

Table: incident

Active: Checked

Global: Checked

Type: onLoad

UI Type: All

Script:

function onLoad() {
	// Fetch the field choices from the server
	var ga = new GlideAjax( 'fetchChoiceValues' );
	ga.addParam( 'sysparm_name', 'fetch' );
	ga.addParam( 'sysparm_tgt_fld', 'subcategory' );
	ga.addParam( 'sysparm_tgt_tbl', 'incident'    );
	ga.addParam( 'sysparm_dpn_val', ( g_form.getValue( 'category' ) || 'inquiry' ));

	ga.getXML( function( res ) {
		// Parse the server response
		var result = res.responseXML.getElementsByTagName( 'result' );
		var choices = JSON.parse( result[0].getAttribute( 'choices' ));

		// Clear the existing choices
		g_form.clearOptions( 'subcategory' );

		// Populate the new choices
		for ( var i = 0, cl = choices.length; i < cl; ++i )
			g_form.addOption( 'subcategory', choices[i].value, choices[i].label );
	});
}

 

3. Create an onChange client script to handed the logic to remove the entry when the category is selected with

Isolate script: Checked

Active: Checked

Table: incident

Global: Checked

Type: onChange

UI Type: All

Field name: Category

Script:

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

	// Fetch the field choices from the server
	var ga = new GlideAjax( 'fetchChoiceValues' );
	ga.addParam( 'sysparm_name', 'fetch' );
	ga.addParam( 'sysparm_tgt_fld', 'subcategory' );
	ga.addParam( 'sysparm_tgt_tbl', 'incident'    );
	ga.addParam( 'sysparm_dpn_val', newValue      );

	ga.getXML( function( res ) {
		// Parse the server response
		var result = res.responseXML.getElementsByTagName( 'result' );
		var choices = JSON.parse( result[0].getAttribute( 'choices' ));

		// Clear the existing choices
		g_form.clearOptions( 'subcategory' );

		// Populate the new choices
		for ( var i = 0, cl = choices.length; i < cl; ++i )
			g_form.addOption( 'subcategory', choices[i].value, choices[i].label );

		// Now we can remove the email option
		if ( newValue === "software" )
			g_form.removeOption( 'subcategory', 'email' );
	});
}

 

@Robbie Thankyou So Much Dear