conditional fields in zendesk (Classic) -- deprecated

Many Zendesk customers have requested a way for custom drop-down lists to be able to show and hide elements based on certain conditions. Although not currently provided as a custom field type in Zendesk, you can create conditional drop-down lists yourself by creating a JavaScript widget.

The idea is simple but complex in implementation. Each layer adds to complexity so we recommend that you create no more than three layers. For example:

1. parent 1  
  a. child 1
    i. sub child 1
  b. child 2
    i. sub child 2
2. parent 2  
  a. child 3
    i. sub child 3
      a. child 4
      sub child 4

There are two ways of doing conditional fields. The first is if you have no required child fields, the second is if you do. The JavaScript code for each is described below.

For either option, you first need to create a custom drop-down field and then create a JavaScript widget, which controls the behavior (enables the conditional fields) when the field is used in your help desk.

Option 1: No required child fields

The first option is to show and hide the entire child field based on a selection in the parent field. Using this method, the child fields can only be optional, not required.

To build out the JavaScript code for this, you need the custom field ID of each field you want to hide. You can find your custom drop-down list ID here:

conditional_fields1.png

Here's the JavaScript code to create a conditional drop-down list with no required child fields. You can also find the code on github.

(function () {

/* This widget uses arrays to store the fields you which to show or hide based on a users selection
** Each field you wish to hide contains three fields that need to be hidden
** 1) The title which is a H3 HTML tag. This uses jQuery to search for the title so make one entry in the array like this h3:contains(Division)
** 2) THe description (which is optional) that is a <P> HTML Tag. Like the title we do a searh for words in the description like this p:contains(Which Division) so add that to the next element in the array
** 3) The last bit that need to be in the array is the selector for the field which is like  #ticket_fields_20389132 the number being the ID of the custom field.
**
** You need to create a array for each condition you wish to exist.
*/

var creative_request = ['h3:contains(Division)','p:contains(Which Division)','#ticket_fields_20389132','h3:contains(Phone Number)','#ticket_fields_20389182','h3:contains(Request Type)','p:contains(or On-going)','#ticket_fields_20388673','h3:contains(Contact Name)','#ticket_fields_20391371','h3:contains(Additional Notes)','p:contains(please provide justification)','#ticket_fields_20391376'];

var project_request = ['h3:contains(No Revenue)','p:contains(no revenue)','#ticket_fields_20392967','h3:contains(Websites)','p:contains(verticals does this project)','#ticket_fields_20392977','h3:contains(Channels)','p:contains(Identify any channel)','#ticket_fields_20392982','h3:contains(Other Departments)','p:contains(how other departments)','#ticket_fields_20392987','h3:contains(Status Tracking)','p:contains(stats tracking requirements)','#ticket_fields_20392992','h3:contains(Internal Platform)','p:contains(being built internally)','#ticket_fields_20395556','h3:contains(Reporting Requirements)','p:contains(specific reporting requirements)','#ticket_fields_20395561','h3:contains(Standard Ad Units)','p:contains(standard in page)','#ticket_fields_20395566','h3:contains(Wallpaper)','p:contains(if wall paper is)','#ticket_fields_20395571','h3:contains(Video)','p:contains(incorporating video)','#ticket_fields_20395576','h3:contains(Third Party)','p:contains(third party involvement)','#ticket_fields_20395581','h3:contains(Domain Name)','p:contains(DNS change)','#ticket_fields_20395586','h3:contains(Required Departments)','#ticket_fields_20395591','h3:contains(Technical Specs)','p:contains(Technical Specs)','#ticket_fields_20395596','h3:contains(Project Contact)','p:contains(Enter Contact Name)','#ticket_fields_20392048','h3:contains(Project type)','#ticket_fields_20392053','h3:contains(Project Name)','p:contains(Enter the project name)','#ticket_fields_20395381','h3:contains(Success Criteria)','p:contains(measure the success)','#ticket_fields_20392058','h3:contains(Sponsor Phone)','#ticket_fields_20392063','h3:contains(Sponsor Department)','#ticket_fields_20392068','h3:contains(Project Milestones)','p:contains(milestones for the project)','#ticket_fields_20392073','h3:contains(Nonprofit)','p:contains(is for charity or a nonprofit group)','#ticket_fields_20392078','h3:contains(Indirect Revenue)','p:contains(any indirect revenue)','#ticket_fields_20392083','h3:contains(Content Location)','p:contains(built internally or if it is a 3rd Party)','#ticket_fields_20392088','h3:contains(Intersitials)','p:contains(Identify if interstitials)','#ticket_fields_20392093','h3:contains(Sponsor email)','#ticket_fields_20395421','h3:contains(Is due date flexible)','#ticket_fields_20395426','h3:contains(Affected URL)','p:contains(URL of affected)','#ticket_fields_20392133','h3:contains(If the due date not flexible)','p:contains(An ad campaign running)','#ticket_fields_20395466','h3:contains(Project Background)','p:contains(The background of the Project)','#ticket_fields_20392932','h3:contains(Project Benefits)','p:contains(outline of what the benefits are)','#ticket_fields_20392937','h3:contains(Consumer Need)','p:contains(consumer will this project satisfy)','#ticket_fields_20392942','h3:contains(Estimated Revenue)','#ticket_fields_20395506','h3:contains(Project Objectives and Deliverables)','p:contains(specific objectives for the project)','#ticket_fields_20392947','h3:contains(Sponsors Name)','#ticket_fields_20392952','h3:contains(Sponsor location)','#ticket_fields_20392957'];

var date_fields = ['h3:contains(Date Required)','#ticket_fields_20389142','h3:contains(Requested date)','#ticket_fields_20388678'];  
var common_fields = ['h3:contains(Priority)','p:contains(Request priority)','#ticket_priority_id','h3:contains(Description)','p:contains(Thoroughly describe)','#comment_value'];

//the array the hides everything
var hideAll = [creative_request, project_request, date_fields, common_fields]

//condition fields for the end user request form make sure you change the field ID to yours.
$j(document).ready(function() {  

    //function to hide a array of arrays
       var hide = function(){
           $j.each(arguments, function(i, item){
               for(y = 0; y < item.length; y++){
                 for(x = 0; x < item[y].length; x++){ $j(item[y][x]).hide();}
               }
           }
               );
       }
       //function to show a array of arrays
       var show = function(){
              $j.each(arguments, function(i, item){
                  for(y = 0; y < item.length; y++){
                    for(x = 0; x < item[y].length; x++){ $j(item[y][x]).show();}
                  }
              }
                  );
       }

   //check to see if you are on the end users request page
   if(location.pathname === '/requests/new' || location.pathname === '/anonymous_requests/new') {
   //hide all the fields
   hide(hideAll);

      //monitor the dropdown field
      $j('#ticket_fields_20381732').change(function (){
         //grab the value of the dropdown
         var userSelection = $j('#ticket_fields_20381732').val();
         if(userSelection === 'project_request') {
             //hide all the fields
                hide(hideAll);
            //then show the array of fields you want to display
           var showArray =  [project_request, date_fields, common_fields];
           show(showArrat);
        }

          if(userSelection === 'creative_request'){
              //hide all the fields
                  hide(hideAll);
              //then show the array of fields you want to display
               var showArray = [creative_request, date_fields, common_fields];
               show(showArray);
        }
          if(userSelection !== 'creative_request' && userSelection !== 'project_request')  {
               //hide all the fields
                    hide(hideAll);
                //then show the array of fields you want to display
                 var showArray = [date_fields, common_fields]
                show(showArray);
       }

         });
    }

});

}());

You then build out arrays of the fields that you want to show or hide. When showing or hiding a field, there are two mandatory elements of the field and one optional that are needed in the array. The two mandatory are Title and custom field ID. The optional element is the ticket field description.

conditional_fields2.png

To hide the correct title or description, the jQuery function ‘contains:’ is used (as you can see in the code example above). To hide the title, the array includes ‘h3:contains(Division)’, which hides all titles that contain the word 'Division'. Hiding the description is done the same way: ‘p:contains(Which Division)’. To hide the field itself, use the format ‘#ticket_fields_ID’ (for example '#ticket_fields_20389142').

After you build out the arrays in the widget, you hide all the elements in the arrays using for loops and then start to monitor changes on the parent ticket field. Once the user has made a selection, you grab the value and use if statements to show or hide the elements.

20120229-nxw8rtxmuydpip4c8uhk78a527.jpg


Option 2: Required child fields

The other way to do condition fields is to rewrite the drop-down list options based on the selection in the parent field. The benefit to using this method is the child fields can be required. You still need to get the custom ticket field ID and build arrays, but the arrays will be the titles and values that you want to display when an option is selected in the parent field.

Here's the JavaScript code to create conditional fields with required child fields. You can also find the code on github.

(function () {  
    /*create the various options you want to display
    **each array needs to be built out with even number of members
    **in a tag, title format.
    */
    var option1 = ['epic','Epic','story','Story'];
    var option2 = ['problem','Problem','task','Task'];
    var option3 = ['question','Question','incident', 'Incident'];
    var fieldOption1 = ['teeth', 'Teeth', 'gums','Gums' ]
    var fieldOption2 = ['molar', 'Molar', 'tonge', 'Tounge']

    //this builds the dropdown list
    Buildoptions = {
        selected: function(value, name){
            return '<option value="'+value+'" selected="selected">'+name+'</option>';
        },
        notselected: function(value, name){
            return '<option value="'+value+'">'+name+'</option>';
        },
        clear: function(){
            return '<option value=""></option>';
        }
    }
    //goes through the selected array and builds the options
    var makeSelection = function(theField, theArray) {
            for ( x = 0; x < theArray.length; x = x + 2) { console.log('makeing select ' + theArray)
                $j(''+ theField +'').append(Buildoptions.notselected(theArray[x], theArray[x + 1]));
            }
        }

        //default options when page 1st loads
        $j("select#ticket_fields_20111097").html(Buildoptions.clear());
        makeSelection('select#ticket_fields_20111097',option3);
        //watch the root field for changes
        $j('#ticket_fields_109934').change( function(endUserselect){
            //grab the value of the dropdown
            var userSelection = $j('#ticket_fields_109934').val();
            if( userSelection === 'teeth') {
                $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                makeSelection('select#ticket_fields_20111097',option2);
            }
            if ( userSelection === 'gums' ) {
                $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                makeSelection('select#ticket_fields_20111097',option1);
            }
            if ( userSelection === 'tonge'){
                $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                makeSelection('select#ticket_fields_20111097',option3);
            }
            if ( userSelection === 'molar'){
                $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                makeSelection('select#ticket_fields_20111097',option1);
            }
        });
        $j('select#ticket_group_id').change( function(agentSelect){
            //grab the value of the dropdown
            var userSelection = $j('select#ticket_group_id').val();
            console.log('in change' + userSelection);
            if( userSelection === '48491') {
                $j("select#ticket_fields_109934").html(Buildoptions.clear());
                makeSelection('select#ticket_fields_109934',fieldOption2);
            } else if ( userSelection === '81995' ) {
                $j("select#ticket_fields_109934").html(Buildoptions.clear());
                 makeSelection('select#ticket_fields_109934',fieldOption1);
            }
        });

    if(location.pathname.indexOf('tickets') >= 1) {
        $j('select#ticket_fields_109934').html(Buildoptions.clear());
        //default options when page 1st loads
        console.log(document.location.pathname);
        $j.getJSON(document.location.pathname, function(ticketData){
                console.log('ticket groupid ' + ticketData.group_id);

                $j.each(ticketData.ticket_field_entries, function(i, item){
                   if ( item.ticket_field_id === 109934) {
                        if( item.value === 'teeth' ) {
                            $j('select#ticket_group_id').val('81995');
                            $j('select#ticket_group_id').change();
                            $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                            makeSelection('select#ticket_fields_20111097',option2);
                        }
                        if ( item.value === 'gums'){
                            $j('select#ticket_group_id').val('81995');
                            $j('select#ticket_group_id').change();
                            $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                            makeSelection('select#ticket_fields_20111097',option1);
                        }
                        if ( item.value === 'molar'){
                            $j('select#ticket_group_id').val('48491');
                            $j('select#ticket_group_id').change();
                            $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                            makeSelection('select#ticket_fields_20111097',option1);
                        }
                        if ( item.value === 'tonge'){
                            $j('select#ticket_group_id').val('48491');
                            $j('select#ticket_group_id').change();
                            $j("select#ticket_fields_20111097").html(Buildoptions.clear());
                            makeSelection('select#ticket_fields_20111097',option3);
                        }
                        $j('#ticket_fields_109934').val(item.value)
                   }
                   if ( item.ticket_field_id === 20111097) {
                       console.log('20111097 ' + item.value)
                       $j('#ticket_fields_20111097').val(item.value)
                      }

                });
           }
        );
    }
}());

To create the various options you want to display, each array needs to be built out with an even number of members in a tag and title format.

conditional_fields4.png

The first thing you have to do is figure out what your default options are going to be. The following function clears all the values and rebuilds itself with the default values.

conditional_fields5.png

Then, you just watch the parent ticket field for changes and then, based on the user's selection, call the build function with the correct array.

conditional_fields6.png