How to build cascading menus?

Amy Hicox
Tera Contributor

I'm new to ServiceNow but certainly not ticket system development and javascript. I have tried to do my due diligence but I'm having a hard time finding my way. Please kindly redirect me to a more appropriate forum if I'm in the wrong place.

I need to build a cascading menu across three reference fields, such that when a value is changed on one field, appropriate option values are set on the other two. I (think) my problem is that I don't know how to dereference the reference field for the qualification on the other two fields.

some background. I have three tables

 

  1. Center
    • 'center' field contains a string and is visible
      (this is the top level of the cascading menu)
  2. Building
    • 'center' field is a string (this a foreign key linking the building record to the parent 'Center' record)
    • 'building' field contains a string and is visible 
  3. Room
    1. 'center' field is a string (foreign key)
    2. 'building' field is a string (foreign key)
    3. 'room' field is a string and is visible

there is also a fourth table (LineItem) with three reference fields: 'center', 'building' and 'room' each respectively pointing at the tables listed above.

on the 'center' field I have a simple reference qualification of active: true, and this renders a dropdown list of the visible 'center' field on the Center table where active: true and works as expected. cool.

Now, when the user selects a value on 'center' I need the options on the 'building' field to be the list of rows on the Building form where the 'center' field matches the selected value and active:true. in the reference qualification on the 'building' field I have "Center is same as Center" with the reference key set to 'center' (see attached screenshot). 

As far as I can tell this simply does not work. Maybe because the 'center' field does not actually contain the string value but the sys_id? This is what I was trying to address via the 'reference key' but setting that seems to make no difference at all. Or maybe there's some system call I need to be making on 'center' value change to signal the 'building' field to refresh its reference query?

My second thought was that since changing the value of the 'center' field happens in the client, that maybe I needed to set up a server-side include via the abstractAjaxProcessor extension and call it from a client script.

So I set that all up and verified that I can call the server-side function from the client script, get the JSON back with the list of buildings and parse it successfully. I thought at that point I could use g_form.addOption() to just add the options (either the string values of "building" or the sys_id of the Building record -- I've tried both) but this *also* does not seem to work.

cascading menu values on fields is like -- super duper basic -- right? Every ticket system in existence on any platform will have to deal with this need. It can't be this hard. I have certainly missed something obvious.

please point me in the right direction y'all!

3 REPLIES 3

Roshnee Dash
Tera Guru

Hi @Amy Hicox 
Make sure you have these tables with this type of column and also verify with your backend names(it may veries)

  • Center (with a field: name and type string)
  • Building (with fields: name, center â†’ reference to Center)
  • Room (with fields: name, building â†’ reference to Building (field type reference) , Center -> reference to Center(field type reference))
  • LineItem (with fields: center ->center table, building -> building  table, room  -> room table) field type reference

Create Reference Qualifiers

For building field:

  1. Go to System Definition > Dictionary.
  2. Search for the building field on the LineItem table.
  3. Open it and scroll to Reference Specification.
  4. In Reference qualifier, choose "Advanced".
  5. Paste this script: 
javascript: 'u_center=' + current.u_center​

For room field:

  1. Do the same steps as above.
  2. Use this script: 
javascript: 'u_building='+current.u_building+'^u_center='+current.u_center;​

Add Client Scripts

If You want  to  refresh the dependent fields when the parent field changes.
CS on Change of field Center:

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

  // Clear dependent fields
  g_form.setValue('u_building', '');
  g_form.setValue('u_room', '');
}

CS on change of building:

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

  // Clear room when building changes
  g_form.setValue('u_room', '');
}

 

Your feedback makes the community stronger! If you found this helpful, marking it as the correct answer helps others.
Stay awesome,
Roshnee Dash

@Roshnee Dash thank you so much for the response!

 

I'm trying this out but not having much luck.
I suspect I've not entered the javascript reference qual's correctly (maybe forum post formatting is fouling up the snippets you posted?)

should it literally be the 'javascript' keyword followed by a string constructor like this?

javascript: 'u_center=' + current.u_center

(see attached screenshot)

Also is the functionality you're referencing here documented somewhere so I can look into the details?

For instance is the column name 'name' reserved? If so what is the meaning/intent of this field?

 

For that matter, current.u_<field> -- is this a way of dereferencing a reference field to get the value of the visible column on the referenced row? 

I'm sure I'm missing something. There appears to be a ton of documentation on docs.servicenow.com and it is somewhat useful for finding specifics about API functions that I already know exist through the training courses I've been able to take, but there doesn't appear to be any kind of "front door"  that gives you "ok this is how this system works, here's the syntax, here's the reserved words, here's how the relational model in the DB works, etc?"

  1. RoshneeDash_1-1753849389904.png

     

  2. RoshneeDash_2-1753849412500.png

     

    • For Building
      nameu_name
      centeru_center
  3.  
  4. RoshneeDash_3-1753849421538.png

     

    • For Room
    • nameu_name
      buildingu_building
      Centeru_center
  5. RoshneeDash_4-1753849431536.png

     

  6. RoshneeDash_5-1753849441068.png

     

  7. RoshneeDash_6-1753849449454.png

     

 

 

Your feedback makes the community stronger! If you found this helpful, marking it as the correct answer helps others.
Stay awesome,
Roshnee Dash