Igor Bismark
Igor Bismark

Reputation: 11

Search filter using multiple dropdowns with JavaScript

Here is the thing: I created this menu with 7 dropdowns menus and some options in each dropdowns, and I want to filter the divs that gonna be shown according to the values in the dropdowns. I don't know how to relate de classes in the divs and the dropdown values to make this filter work. I've been on it for a few days, if someone knows how to do it and help me :')

(In JavaScript a put inside the function a for that remove one div when onclick, just to test, in reality I want to display only the divs that have the values on the filter, and hide the others, and if the value is empty show all)

HTML:

    <!--Search dropdown-->
<div>
    <select name="" id="type">
        <option selected value="">All type</option>
        <option value="house">house</option>
        <option value="apartament">Apartament</option>
        <option value="farm">farm</option>
        <option value="land">land</option>
    </select>
</div>
<div>
    <select name="" id="city">
        <option selected value="">All cities</option>
        <option value="city1">city1</option>
        <option value="city2">city2</option>
        <option value="city3">city3</option>
    </select>
</div>
<div>
    <select name="" id="district">
        <option selected value="">District</option>
        <option value="district1">district1</option>
        <option value="district2">district2</option>
        <option value="disctrict3">disctrict3</option>
    </select>
</div>
<div>
    <select name="" id="price">
        <option selected value="">Price</option>
        <option value="30">$ 30.000 to $ 80.000</option>
        <option value="80">$ 80.000 to $ 150.000</option>
        <option value="150">$ 150.000 to $ 300.000</option>
        <option value="300">$ 300.000 or more</option>
    </select>
</div>
<div>
    <select name="" id="room">
        <option selected value="">Room</option>
        <option value="1-r">1</option>
        <option value="2-r">2</option>
        <option value="3-r">3</option>
        <option value="4-r">4 or more</option>
    </select>
</div>
<div>
    <select name="" id="garage">
        <option selected value="">Garage</option>
        <option value="1-g">1</option>
        <option value="2-g">2</option>
        <option value="3-g">3</option>
        <option value="4-g">4 or more</option>
    </select>
</div>
<div>
    <select name="" id="bath">
        <option selected value="">baths</option>
        <option value="1-b">1</option>
        <option value="2-b">2</option>
        <option value="3-b">3</option>
        <option value="4-b">4 or more</option>
    </select>
</div>
<div>
    <button type="button" id="searchFilter" onclick="getSelectedValue()">Search property</button>   
</div>    

<!--Cards-->
<div class="cards">
    <div class="city1 1-b 1-r 1-g"> <!--Here is the classes according to the filter-->
        <h2>155 Center<br/>City1</a></h2>
        <span> Sell | $ 120.000</span>
        <h4>Area</h4>
        <span>340m</span>
        <h4>Room</h4>
        <span>2</span>
        <h4>Bath</h4>
        <span>2</span>
        <h4>Garage</h4>
        <span>1</span> 
    </div>

    <div class="city2 2-b 2-r 2-g"> <!--Here is the classes according to the filter-->
        <h2>155 Center<br/>City3</a></h2>
        <span> Sell | $ 120.000</span>
        <h4>Area</h4>
        <span>340m</span>
        <h4>Room</h4>
        <span>2</span>
        <h4>Bath</h4>
        <span>2</span>
        <h4>Garage</h4>
        <span>1</span> 
    </div>

    <div class="city3 3-b 3-r 3-g"> <!--Here is the classes according to the filter-->
        <h2>155 Center<br/>City3</a></h2>
        <span> Sell | $ 120.000</span>
        <h4>Area</h4>
        <span>340m</span>
        <h4>Room</h4>
        <span>2</span>
        <h4>Bath</h4>
        <span>2</span>
        <h4>Garage</h4>
        <span>1</span> 
    </div>
</div>

JavaScript:

    //capture dropdown values
document.getElementById('searchFilter').onclick = function getSelectValue(){

var typeValue = document.getElementById("type").value;
console.log(typeValue)
var cityValue = document.getElementById("city").value;
console.log(cityValue)
var districtValue = document.getElementById("district").value;
console.log(districtValue)
var priceValue = document.getElementById("price").value;
console.log(priceValue)
var roomValue = document.getElementById("room").value;
console.log(roomValue)
var garageValue = document.getElementById("garage").value;
console.log(garageValue)
var bathValue = document.getElementById("bath").value;
console.log(bathValue)


//hide card with certain class
var x = document.getElementsByClassName('city1');
var i;
for (i = 0; i < x.length; i++) {
    x[i].style.display = 'none';
}
document.getElementsByClassName('cards')[0].style.display = 'flex'
}

Upvotes: 1

Views: 1525

Answers (2)

Igor Bismark
Igor Bismark

Reputation: 11

I ended up doing this search filter using PHP with MySQL and Ajax. I was trying to do it in the wrong way before, probably would make the page really slow.

I did like in this example here: https://www.phpzag.com/demo/product-search-filter-with-ajax-php-mysql/

Thanks for the answer and sorry for the ignorance. Living and learning!

Upvotes: 0

Phaelax z
Phaelax z

Reputation: 2009

While I think the way you're going about this is a terrible idea, for the sake of learning purposes I've made up a small example for you. Hopefully without having to alter too much of your existing structure. Been awhile since I did anything like this without using jQuery but here goes!

Take the data for all your properties and put them into an object array. This will help facilitate the filtering by using the Array.prototype.filter() function. Now with an array containing only the objects that have passed the search criteria, build the visual elements. Each object will be displayed as a "card", it's own DIV. Each card is then added to the parent DIV, the card container called "cards".

https://jsfiddle.net/phaelax/9dnfpj87/

This is only one method to achieve what you want. Another method would be to display everything and use data attributes on each card. Grab all the cards and simply hide the ones that don't match the search parameters. This prevents manipulating the DOM so much and may be preferable.

HTML:

<div>
  <label>
      City:
      <select name="" id="city">
          <option selected value=""></option>
          <option value="city 1">City 1</option>
          <option value="city 2">City 2</option>
          <option value="city 3">City 3</option>
      </select>
    </label>
    
    <label>
      Area:
      <select name="" id="area">
          <option selected value=""></option>
          <option value="300">&#60;= 300</option>
          <option value="350">&#60;= 350</option>
          <option value="400">&#60;= 400</option>
      </select>
    </label>
</div>

<div>
    <button type="button" id="searchFilter" onclick="getSelectedValue()">Search property</button>   
</div>    

<!--Cards-->
<div id="cards">
   
</div>

JS:

// The data of your various items to display
var properties = [{city:"city 1", price:120000, area:300, room:2, bath:2, garage:1},{city:"city 2", price:120000, area:340, room:3, bath:2, garage:1},{city:"city 3", price:120000, area:375, room:2, bath:2, garage:1}];



//capture dropdown values
document.getElementById('searchFilter').onclick = function getSelectValue() {

    // Get the dropdown values
  var cityValue = document.getElementById("city").value;
    var areaSize = parseInt(document.getElementById("area").value);
  
  // Empty the existing data
  cardContainer = document.getElementById("cards");
  while (cardContainer.firstChild){ 
    cardContainer.removeChild(cardContainer.firstChild);
  }
  

    // Filter out the data, retrieve an array of only the objects that
  // that meet our search criteria
  filteredProperties = properties.filter(e => {

    if (cityValue !== "" && e.city !== cityValue)
      return false;

    if (!isNaN(areaSize) && e.area > areaSize)
      return false;

    return true;
  });

  
  
    // Loop through filtered objects and build the elements to display
  filteredProperties.forEach(e => {
  
    // Each property is contained with a "card"
    var card = document.createElement("DIV"); // create the card div element
    card.classList.add("card");  // add some style

        // Loop through each value in the object and build elements
    for (var key in e){
        var propHeading = document.createElement("h2");
      propHeading.innerHTML = key;
      
      var propValue = document.createElement("span");
      propValue.innerHTML = e[key];
      
      // Append the values to the card element
      card.appendChild(propHeading);
      card.appendChild(propValue);
    }
    
    // Add this new card to the cards container
    document.getElementById("cards").appendChild(card);

  });

}

CSS:

.card {border:1px solid black;display:inline-block;margin:10px;width:150px;}

Upvotes: 2

Related Questions