Working Example: Select Box Dependency Using jQuery

When using complex data structures in online forms you may need to enforce the data structure hierarchies on to the forms themselves. For example, let's say we have two data tables that implement a hierarchy. We have table A that holds the top level of the hierarchy and table B that holds the lower level, where each item is linked to an item in the top level. This could be a "one-to-many" reference, or even "many-to-many".
In the online form we will use two select boxes, one for each table. These could be either single or multiple choice select boxes.

The question is how to enforce these references between the tables' items in the form's select boxes?
We can do that using JavaScript or better yet, using jQuery.

First, we need to store the two tables' item in different arrays, each one with the relevant data fields.

var arrTableA = arrTableA || [
  {'TableAId' : '1', 'Name': 'Table A Item 1'},
  {'TableAId' : '2', 'Name': 'Table A Item 2'},
  {'TableAId' : '3', 'Name': 'Table A Item 3'}
];

var arrTableB = arrTableB || [
  {'TableBId' : 'a', 'Name': 'Table B Item a – belongs to Table A Item 1', 'TableAId': '1'},
  {'TableBId' : 'b', 'Name': 'Table B Item b – belongs to Table A Item 1', 'TableAId': '1'},
  {'TableBId' : 'c', 'Name': 'Table B Item c – belongs to Table A Item 2', 'TableAId': '2'},
  {'TableBId' : 'd', 'Name': 'Table B Item d – belongs to Table A Item 3', 'TableAId': '3'},
  {'TableBId' : 'e', 'Name': 'Table B Item e – belongs to Table A Item 3 and 2', 'TableAId': '2,3'}
];

Next, we will bind a new function to the top level select box change event:

// when the top level select box changes, do something...
$("#TableASelectBox").change(function() {
  // array to hold the top level selected values
  var topValues = [];
  $("#TableASelectBox option:selected").each(function() {
    topValues.push($(this).val());
  });

  // array to hold the lower level selected values
  var arrLowerValues = [];
  $("#TableBSelectBox option:selected").each(function() {
    arrLowerValues.push($(this).val());
  });

  // always keep the first lower level option (the "Select.." option)
  var firstLowerOption = $("#TableBSelectBox option").first();

  // empty the lower level select box
  $("#TableBSelectBox").empty();

  // append the first option
  $("#TableBSelectBox").append(firstLowerOption);

  // go over lower level array
  for (var i = 0; i // get the referenced top level Ids for the current low level item. we use an array to support multiple choices
    var arrTopValue = arrTableB[i].TableAId.split(',');
    // check if one of the low level item's top level reference Ids was selected in the top level select box
    var valExists = false;
    for (var k = 0; k =0) {
        valExists = true; // flag and exit loop
        break;
      }
    }

    // check if we found an existing value
    if (valExists) {
      // append the current value to the lower level select box with it's value, name and add the "selected" attribute if needed
      $("#TableBSelectBox").append(
        $("<option>")
          .val(arrTableB[i].TableBId)
          .text(arrTableB[i].Name)
          .prop("selected", $.inArray(arrTableB[i].TableBId,arrLowerValues)>=0)
      );
    }
  }
}).change(); // execute once when the page loads

As soon as the top level select box is changed, the function is being executed.
It takes all the top level selected items and saves the lower level selected items as well, for later use.
It always keeps the first lower level item option (the "Select...") regardless of the top level select box selection.
Then, the lower level select box is being emptied, the first option returned and it starts checking the references between the two tables.
If it finds a low level item that has a reference to the top level and that top level was selected, then it adds the lower level item back to the select box. When it does that, it also checks if this item was selected before and re-selects it if so.

This is a working example, so feel free to play with the select boxes above to see how their dependency works.
Comments are most welcomed...

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA

This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.

Image CAPTCHA