Select 2 Custom Match - Include Children of Parent Match

Select2 example whereby if an item is matched in the search, its children will still return, regardless of whether they meet the search criteria or not

by Adam Berry

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.min.js"></script>
<!DOCTYPE html>
<html>
  <head>
  </head>

  <body style="margin:50px">
    <strong>Search: </strong>
    <input class="select2" id="NestedOptGroups" placeholder="Select Location" style="width:250px;" />
  </body>
</html>

JavaScript

$(document).ready(function() {
  function matcher(term, text, opt) {
    var $option = $(opt),
      $optgroup = $option.parent('optgroup'),
      label = $optgroup.attr('label');

    term = term.toUpperCase();
    text = text.toUpperCase();

    //Match Parents
    if (text.indexOf(term) > -1 ||
      (label !== undefined &&
        label.toUpperCase().indexOf(term) > -1)) {
      return true;
    }

    //Match Children (If Required)
    if (opt.parents !== undefined) {
      for (var i = 0; i < opt.parents.length; i++) {
        if (opt.parents[i].toUpperCase().indexOf(term) > -1) {
          console.log("hi");
          return true;
        }
      }
    }

    return false;
  }

  var json = JSON.parse('[{"text":"England","children":[{"text":"Greater Manchester","id":"c1c1","parents":["England"]}]},		{"text":"Ireland","children":[{"text":"Cork","id":"c2c1","parents":["Ireland"],"children":[{"text":"Douglas","id":"c2c1c1","parents":["Ireland","Cork"]}]},{"text":"Clare","id":"c2c2","parents":["Ireland"]}]}]');

  $('#NestedOptGroups').select2({
    matcher: matcher,
    data: json
  });
});