How to automatically populate the subcategory field if there is only one available choice depending on category

masella
Giga Contributor

Hi,

 

I have a category and subcategory dependency. I need to create a client side client script that automatically populates the subcategory field if there is only 1 option based on the category that was selected.

 

See my code below - I know the getRow() function is not valid in a client side client script. Any other suggestions?

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if (isLoading || newValue == '') {

          return;

    }

 

    var vCat = g_form.getValue('u_category');

    var vSubcat = new GlideRecord ('sys_choice');

    vSubcat.addQuery('name', 'u_hr_cases');

    vSubcat.addQuery('dependent_value', vCat);

    vSubcat.query();

 

      if (vSubcat.getRowCount() == 1){

              g_form.setValue('u_subcategory', vSubcat.label);

      }

}      

1 ACCEPTED SOLUTION

Jim Coyne
Kilo Patron

You can do it completely client-side with the following onChange script:



function onChange(control, oldValue, newValue, isLoading, isTemplate) {


  if (isLoading || newValue == '') {


      return;


  }



  setTimeout(function(){


      try {


          var subCategory = $("incident.subcategory");


          if (subCategory.length == 2) {           //"-- None --" + another


              subCategory.selectedIndex = "1";   //index starts at 0


              g_form.setValue("subcategory", subCategory.value);     //mark field as changed


          }


      } catch(err) {}


  },500);     //half-second wait


}



This example works on the Incident table, setting the Subcategory based on a change to the Category field.   You can see it running in demo021 at the moment (select "Test" as the Category).   The script waits for half a second then checks the number of entries in the Subcategory drop down.   It automatically selects the one option if there are just 2 available ("-- None --" + another).   The g_form.setValue call is used to make sure the field is marked as changed with the little green bar.



I don't really like the half-second wait, but it was the best I could come up with at the moment.   Maybe someone else knows a better hook into knowing when the Subcategrory field has been repopulated.


View solution in original post

10 REPLIES 10

Thanks David for your input, it helped me achieve the end result.



Cheers


Anthony


Probably the half-second wait.   I mentioned I didn't really like it and you are probably seeing why.



The script is probably "running", but not "working" because the data has not been updated within the half-second time period.   Just to test it out, try setting it to 2 seconds or so to see if it works all the time.   Unfortunately the longer wait makes it a little less desirable as a solution though.   Need to figure out a way to run it after Subcategory is populated so it runs all the time at the proper time.



Try this script out in your development instance - it will show a message at the top of the form each time it runs and another if it sets the field:



function onChange(control, oldValue, newValue, isLoading, isTemplate) {


  if (isLoading || newValue == '') {


      return;


  }



  g_form.addInfoMessage('Running autoselect function');


  setTimeout(function(){


      try {


          var subCategory = $("incident.subcategory");


          if (subCategory.length == 2) {           //"-- None --" + another


              subCategory.selectedIndex = "1";   //index starts at 0


              g_form.setValue("subcategory", subCategory.value);   //mark field as changed


              g_form.addInfoMessage('Did my job!');


          }


      } catch(err) {}


  },2000);   //2-second wait


}


Thanks again for your work on this: I've gone for the following solution which is working well.



function onChange(control, oldValue, newValue, isLoading, isTemplate) {  


          if (isLoading || newValue == '') {  


              return;  


          }


     


    function populateSubCat(){


    var vCat = g_form.getValue('u_category');


    g_form.setValue('u_subcategory', '');


    var vSubcat = new GlideRecord ('sys_choice');


    vSubcat.addQuery('name', 'u_table');


    vSubcat.addQuery('dependent_value', vCat);


    vSubcat.query();


     


      if (vSubcat.next() && vSubcat.hasNext() == false )   {


                    g_form.setValue('u_subcategory', vSubcat.label);


                   


              }


      }


      populateSubCat();


}


Subhajit1
Giga Guru

Hi Anthony,


You can alternately use an UI Policy and set the value on the subcategory field using the script option available on the UI Policy.


david_legrand
Kilo Sage

An asynchronous client-server call will be better for performance perspective.


A GlideRecord + if (.next()) and if .hasNext() == false, that means the GlideRecord has only one element and it's even faster than glideaggregate