ag_1812
ag_1812

Reputation: 159

Depended multi-selected boxes

The code I use is mostly from this answer https://stackoverflow.com/a/29624809/9481131

Ongoing code:

HTML

        <label style="font-weight: bold">Choose the literary genres</label>

          <select name="genre" id="genre" multiple>
            <option value="all">All genres</option>
            <option value="classic">Classic</option>
            <option value="romance">Romance</option>
            <option value="sciencefiction">Science fiction</option>
          </select>

        <label style="font-weight: bold">Choose the books</label>
          <select disabled="disabled" class="subcat" id="book" name="book" multiple>
            <option value>All books</option>
            <!-- Classic books -->
            <optgroup data-rel="classic">
              <option value="classic_book_1">classic book 1</option>
              <option value="classic_book_2">classic book 2</option>
              <option value="classic_book_3">classic book 3</option>
            </optgroup>
            <!-- Romance books-->
            <optgroup data-rel="romance">
              <option value="romance_book_1">romance book 1</option>
              <option value="romance_book_2">romance book 2</option>
              <option value="romance_book_3">romance book 3</option>
            </optgroup>
            <!-- Science fiction books-->
            <optgroup data-rel="sciencefiction">
              <option value="sciencefiction_book_1">science fiction book 1</option>
              <option value="sciencefiction_book_2">science fiction book 2</option>
              <option value="sciencefiction_book_3">science fiction book 3</option>
            </optgroup>
          </select>

Javascript

<script>
$(function(){
    
    var $cat = $("#genre"),
        $subcat = $("#book");
    
    var optgroups = {};
    
    $subcat.each(function(i,v){
        var $e = $(v);
        var _id = $e.attr("id");
            optgroups[_id] = {};
            $e.find("optgroup").each(function(){
        var _r = $(this).data("rel");
        $(this).find("option").addClass("is-dyn");
        optgroups[_id][_r] = $(this).html();
            });
    });
    $subcat.find("optgroup").remove();
    
    var _lastRel;
    $cat.on("change",function(){
        var _rel = $(this).val();
        if(_lastRel === _rel) return true;
        _lastRel = _rel;
        $subcat.find("option").attr("style","");
        $subcat.val("");
        $subcat.find(".is-dyn").remove();
        if(!_rel) return $subcat.prop("disabled",true);
        $subcat.each(function(){
            var $el = $(this);
          var _id = $el.attr("id");
          $el.append(optgroups[_id][_rel]);
        });
        $subcat.prop("disabled",false);
    });
    
});
</script>

See fiddle here: http://jsfiddle.net/53tL7jhf/

To summarize, I have two select boxes (with the possibility of multi-select in each box). The data from second select box depend on data selected in first box.

What I want:

  1. Then "All genres" is selected in the first box, the second box show all books. Like this:
    |----------------------------|--------------------|
    | Choose the literary genres |  Choose the books  |
    |----------------------------|--------------------|
    |    All genres (SELECTED)   |      All books     |
    |----------------------------|--------------------|
    |                            |    classic book 1  |
    |----------------------------|--------------------|
    |                            |    classic book 2  |
    |----------------------------|--------------------|
    |                            |    classic book 3  |
    |----------------------------|--------------------|
    |                            |    romance book 1  |
    |----------------------------|--------------------|
    |                            |    romance book 2  |
    |----------------------------|--------------------|
    |                            |    romance book 3  |
    |----------------------------|--------------------|
    |                            | sci fiction book 1 |
    |----------------------------|--------------------|
    |                            | sci fiction book 2 |
    |----------------------------|--------------------|
    |                            |         etc.       |
    |----------------------------|--------------------|
  1. Then more than one genre is selected in the first box, the second box show the books from all selected genres. Like this:
|----------------------------|--------------------|
| Choose the literary genres |  Choose the books  |
|----------------------------|--------------------|
|       Classic (SELECTED)   |      All books     |
|----------------------------|--------------------|
| Science fiction (SELECTED) |    classic book 1  |
|----------------------------|--------------------|
|                            |    classic book 2  |
|----------------------------|--------------------|
|                            |    classic book 3  |
|----------------------------|--------------------|
|                            | sci fiction book 1 |
|----------------------------|--------------------|
|                            | sci fiction book 2 |
|----------------------------|--------------------|
|                            | sci fiction book 3 |
|----------------------------|--------------------|

Thanks in advance for any help.

Upvotes: 1

Views: 71

Answers (1)

Swati
Swati

Reputation: 28522

As , you have use mutliple in your select-box so the value returning is in array .If you will do console.log($(this).val()) output coming is in (array) i.e :[..].So , currently your code just take one value not other .Instead you can use each loop again to iterate that array value as well.

Demo code :

$(function() {

  var $cat = $("#genre"),
    $subcat = $("#book");

  var optgroups = {};

  $subcat.each(function(i, v) {
    var $e = $(v);
    var _id = $e.attr("id");
    optgroups[_id] = {};
    $e.find("optgroup").each(function() {
      var _r = $(this).data("rel");
      $(this).find("option").addClass("is-dyn");
      optgroups[_id][_r] = $(this).html();
    });
  });
  $subcat.find("optgroup").remove();
  var _lastRel;
  $cat.on("change", function() {
    var _rel = $(this).val();
    if (_lastRel === _rel) return true;
    _lastRel = _rel;
    $subcat.find("option").attr("style", "");
    $subcat.val("");
    $subcat.find(".is-dyn").remove();
    if (!_rel) return $subcat.prop("disabled", true);
    $subcat.each(function() {
      var $el = $(this);
      var _id = $el.attr("id");
      //if arrray contains all option
      if (_rel.indexOf("all") > -1) {
      //loop though options
        $("#genre option").each(function() {
        //append options in other selects
          $el.append(optgroups[_id][$(this).val()]);
        })
      } else {
        //loop through values got from selctbox
        $(_rel).each(function(index, value) {
          $el.append(optgroups[_id][value]); //passs that value
        }) //close
      }

    });
    $subcat.prop("disabled", false);
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label style="font-weight: bold">Choose the literary genres</label>

<select name="genre" id="genre" multiple>
  <option value="all">All genres</option>
  <option value="classic">Classic</option>
  <option value="romance">Romance</option>
  <option value="sciencefiction">Science fiction</option>
</select>

<label style="font-weight: bold">Choose the books</label>
<select disabled="disabled" class="subcat" id="book" name="book" multiple>
  <option value>All books</option>
  <!-- Home Ware -->
  <optgroup data-rel="classic">
    <option value="classic_book_1">classic book 1</option>
    <option value="classic_book_2">classic book 2</option>
    <option value="classic_book_3">classic book 3</option>
  </optgroup>
  <!-- Education -->
  <optgroup data-rel="romance">
    <option value="romance_book_1">romance book 1</option>
    <option value="romance_book_2">romance book 2</option>
    <option value="romance_book_3">romance book 3</option>
  </optgroup>
  <!-- Books -->
  <optgroup data-rel="sciencefiction">
    <option value="sciencefiction_book_1">science fiction book 1</option>
    <option value="sciencefiction_book_2">science fiction book 2</option>
    <option value="sciencefiction_book_3">science fiction book 3</option>
  </optgroup>
</select>

Upvotes: 1

Related Questions