How do I dynamically add values to a list?

Charles Q
Kilo Contributor

I have a customer that is requesting a field be add to a table to store multiple values, that are not sourced from ServiceNow. Meaning they cannot be stored in another table and reference, the person wants to be able to type them in, but view them as a list.

This is a request for a group of legal people, and the field is already restricted to members of this group, so I would not be creating unfettered writing to this list, but the values are not know, and are created somewhere else. Short of integrating to this system and brining in the values, how can I make the list "open" to the user adding values when needed?

Thanks,

Charles

1 ACCEPTED SOLUTION

Brad Bowman
Kilo Patron
Kilo Patron

Lacking a 'Dynamic List' setting, here's the smoothest way for this to work.  This is how it would look - 2 new fields on the form with an icon to the right of the second field.

find_real_file.png

Through a bit of instruction, or additional on-screen text, what the customer would do is enter a new choice value then click the icon.  They'll either get an alert back that the choice already exists, or it has been added to the list, where they'll be able to search for it or type ahead to see the results.  Here's how to make that happen.

1) The List field starts with some values on the Choices related list, or not if they're starting from scratch without an idea of what some common choices should be.  On the Reference Specification tab, set the Reference to the sys_choice table, then add the Reference qual condition Element is <<name of this list field>> AND Table is <<the name of the table you created the field on>>.

2) The second new field is a String field.  In the Advanced view of the Dictionary Entry, in the Attributes field, put something like this

field_decorations=list_field_update_choices

where the value to the right of the = is the name of a UI Macro that you're about to create.

3) Create a UI Macro with that name, and this XML - substituting your table and field names where noted

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
	<a onclick='updateList()'>
	<span	  
            aria-label="${HTML:gs.getMessage('Update List Field Choices')}"
            title="${gs.getMessage('Update List Field Choices')}"
            alt="${gs.getMessage('Update List Field Choices')}"
		>
		<img id ="luicon"  src="text-info.svg"/>
		</span>
	</a>
 <script> 
	 function updateList(){
	   var listfield = 'u_list';//replace with the name of your List field
	   var tablename = 'u_bkb';//replace with the name of the table you created the List field on
	   var choicetext = g_form.getValue('u_test');//replace with the name of your String field
	 
	   var choiceGR = new GlideRecord('sys_choice');
	   //first check to make sure the choice doesn't already exist
	   choiceGR.addQuery('name', tablename);
	   choiceGR.addQuery('element', listfield);
	   choiceGR.addQuery('value', choicetext);
	   choiceGR.query();
	   if(choiceGR.next()){
	     alert('Choice already exists on List');
	     return;
	   }
       else{
	     //choice not found so create a new one
	     choiceGR.initialize();
	     choiceGR.name = tablename;
	     choiceGR.element = listfield;
	     choiceGR.language = 'en';
	     choiceGR.label = choicetext;
	     choiceGR.value = choicetext;
	     choiceGR.insert();
	     alert('Choice added to List');
	     g_form.clearValue('u_test');//replace with the name of your String field
	   }
	 }
  </script>
	
</j:jelly>

Also note the 3 places near the top of the xml where you can set the icon hover-over text to whatever you'd like, and you can change the src of the img to one that is already in, or you add to, the System UI -> Images list.  You'll also see the 2 alerts that you can customize.

View solution in original post

4 REPLIES 4

Brad Bowman
Kilo Patron
Kilo Patron

Hi Charles,

This is interesting.  I'm thinking on a way this might work, but want to confirm that you are talking about a field, not a Catalog Item variable, and this needs to be the type of List where multiple values can be selected, and this is happening on a form in the native UI, not CMS or Service Portal, and if they don't see a value to select they want to add it, then presumable also select it, and see it again as an available choice the next time the list field is presented.

Charles Q
Kilo Contributor

Hi Brad,

This is a field on a cmdb table. When adding a new field, the type is "List."

I hope this helps.

Charles

Brad Bowman
Kilo Patron
Kilo Patron

Lacking a 'Dynamic List' setting, here's the smoothest way for this to work.  This is how it would look - 2 new fields on the form with an icon to the right of the second field.

find_real_file.png

Through a bit of instruction, or additional on-screen text, what the customer would do is enter a new choice value then click the icon.  They'll either get an alert back that the choice already exists, or it has been added to the list, where they'll be able to search for it or type ahead to see the results.  Here's how to make that happen.

1) The List field starts with some values on the Choices related list, or not if they're starting from scratch without an idea of what some common choices should be.  On the Reference Specification tab, set the Reference to the sys_choice table, then add the Reference qual condition Element is <<name of this list field>> AND Table is <<the name of the table you created the field on>>.

2) The second new field is a String field.  In the Advanced view of the Dictionary Entry, in the Attributes field, put something like this

field_decorations=list_field_update_choices

where the value to the right of the = is the name of a UI Macro that you're about to create.

3) Create a UI Macro with that name, and this XML - substituting your table and field names where noted

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
	<a onclick='updateList()'>
	<span	  
            aria-label="${HTML:gs.getMessage('Update List Field Choices')}"
            title="${gs.getMessage('Update List Field Choices')}"
            alt="${gs.getMessage('Update List Field Choices')}"
		>
		<img id ="luicon"  src="text-info.svg"/>
		</span>
	</a>
 <script> 
	 function updateList(){
	   var listfield = 'u_list';//replace with the name of your List field
	   var tablename = 'u_bkb';//replace with the name of the table you created the List field on
	   var choicetext = g_form.getValue('u_test');//replace with the name of your String field
	 
	   var choiceGR = new GlideRecord('sys_choice');
	   //first check to make sure the choice doesn't already exist
	   choiceGR.addQuery('name', tablename);
	   choiceGR.addQuery('element', listfield);
	   choiceGR.addQuery('value', choicetext);
	   choiceGR.query();
	   if(choiceGR.next()){
	     alert('Choice already exists on List');
	     return;
	   }
       else{
	     //choice not found so create a new one
	     choiceGR.initialize();
	     choiceGR.name = tablename;
	     choiceGR.element = listfield;
	     choiceGR.language = 'en';
	     choiceGR.label = choicetext;
	     choiceGR.value = choicetext;
	     choiceGR.insert();
	     alert('Choice added to List');
	     g_form.clearValue('u_test');//replace with the name of your String field
	   }
	 }
  </script>
	
</j:jelly>

Also note the 3 places near the top of the xml where you can set the icon hover-over text to whatever you'd like, and you can change the src of the img to one that is already in, or you add to, the System UI -> Images list.  You'll also see the 2 alerts that you can customize.

@Brad Bowman ...Thanks for this great detail. I marked it as the correct answer because it will do what I was asking in the original post. After further requirements gathering from the customer, we will just have a longer text field, where they will separate by ";" while we awaiting for the upgrade of their system. When that occurs, we will create an inbound integration to ServiceNow, add these values to a custom table, and then build the list off of the table.