Binita Gyawali
Binita Gyawali

Reputation: 256

Filter multiple data attributes in dropdown list

I have a dropdown list with multiple data attributes

<select class="op" id="b0">
  <option 
    value="1" 
    data-type="vehicle" 
    data-vtype="car" 
    data-model="bmw" 
    data-engine="1" 
    data-owner="1" 
    data-year="2009"
  >BMW2009 </option>
  
  <option 
    value="2" 
    data-type="vehicle" 
    data-vtype="bus" 
    data-model="jeep" 
    data-engine="2" 
    data-owner="4" 
    data-year="2006"
  >BMW2009 </option>
  
  <option 
    value="3" 
    data-type="boat" 
    data-vtype="boat1" 
    data-model="boat2" 
    data-engine="0" 
    data-owner="3" 
    data-year="2010"
  >BMW2009 </option>

There will be around 10k of the data, so I have dropdowns to filter the data

<select id="typeFilter">
  <option value="vehicle">Vehicle </option>
  <option value="Aeroplane">Aeroplane </option>
  <option value="Boat">Boat </option>
</select>

<select id="modelFilter">
  <option value="BMW">BMW </option>
  <option value="Jeep">Jeep </option>
  <option value="Boat2">Boat2 </option>
</select>

I want to filter by typeFilter and/or modelFilter. I used the following code

$('#modelFilter').on('change', function() {
  let mtype = $(this).find("option:selected").data("model");
  $("#b0").show();
  $("#b0 option[data-model]:not([data-model*='" + mtype + "'])").hide();
});

$('#typeFilter').on('change', function() {
  let ttype = $(this).find("option:selected").data("type");
  $("#b0").show();
  $("#b0 option[data-type]:not([data-type*='" + ttype + "'])").hide();
});

The method partially works, so when I select BMW, I can see only the option 3 list but for the multiple conditions with the same name it doesn't. Is there a simpler way to filter the multiple data attributes?

Upvotes: 0

Views: 275

Answers (2)

ikhvjs
ikhvjs

Reputation: 5977

First, the value of your filter select element is not matched with your dropdown because it is case-sensitive.

Second, you can use one single function to do your filtering.

Note: I add a option <option selected disabled>---select a option----</option> to force the user to trigger a change event.

$("#modelFilter").on("change", filter);
$("#typeFilter").on("change", filter);

function filter() {
  $("#b0 option").show();
  const typeFilterValue = $("#typeFilter").val();
  const modelFilterValue = $("#modelFilter").val();
  if(typeFilterValue!==null){
    $(`#b0 option:not([data-type='${typeFilterValue}'])`).hide();
  }
  if(modelFilterValue!==null){
   $(`#b0 option:not([data-model='${modelFilterValue}'])`).hide();
  }
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="op" id="b0">
  <option selected disabled>---select a option----</option>
  <option
    value="1"
    data-type="vehicle"
    data-vtype="car"
    data-model="bmw"
    data-engine="1"
    data-owner="1"
    data-year="2009"
  >
    BMW2009
  </option>
  <option
    value="2"
    data-type="vehicle"
    data-vtype="bus"
    data-model="jeep"
    data-engine="2"
    data-owner="4"
    data-year="2006"
  >
    Jeep
  </option>
  <option
    value="3"
    data-type="boat"
    data-vtype="boat1"
    data-model="boat2"
    data-engine="0"
    data-owner="3"
    data-year="2010"
  >
    Boat
  </option>
</select>
<select id="typeFilter">
  <option selected disabled>---select a option----</option>
  <option value="vehicle">Vehicle</option>
  <option value="Aeroplane">Aeroplane</option>
  <option value="Boat">Boat</option>
</select>
<select id="modelFilter">
  <option selected disabled>---select a option----</option>
  <option value="bmw">BMW</option>
  <option value="jeep">Jeep</option>
  <option value="boat2">Boat2</option>
</select>

Upvotes: 1

tuan nguyen
tuan nguyen

Reputation: 386

first you define a function,

function filter(){
   //show all data
   $("#b0 option").show();
   //check filter by model
   let mtype = $('#modelFilter').find("option:selected").data("model");
   if(mtype){
     $("#b0 option[data-model]:not([data-model*='" + mtype + "'])").hide();
   }
   //check filter by typeFilter
   let ttype = $('#typeFilter').find("option:selected").data("type");
   if(ttype){
    $("#b0 option[data-type]:not([data-type*='" + ttype + "'])").hide();
  }
}

then in each filter call this function,

$('#modelFilter,#typeFilter').on('change', function () {
   filter()
 })

Upvotes: 1

Related Questions