2

I'm try to build a little filter based on the ranking ( numeric value stored in a string ) , but I'm stuck with a part of the code.

Expected behaviour

When a User click on the select option the elements that doesn't match the value selected have to hide(not remove).

$(".notSearched").hide();

$("select").on("click", function() {
  let selectedValue = this.value;
  $('.card-wrap').each(function(selectedValue) {
    console.log("sei qua");

    if (selectedValue === "0") {
      return
    }
    let rate = $(".restoName").find(".ratePlace").text();
    let numRate = parseInt(rate);
    if (rate !== selectedValue || rate !== (selectedValue + 0.5)) {
      $(this).addClass("notSearched");
    }
  })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="columnsContainer">
  <div class="leftColumn">
    <div class="filterResearch">
      <select name="filter" id="searchFilter">
        <option value="all">Apply a filter</option>
        <option value="1">1 Star</option>
        <option value="2">2 Stars</option>
        <option value="3">3 Stars</option>
        <option value="4">4 Stars</option>
        <option value="5">5 Stars</option>
      </select>
    </div>
    <div id="map"></div>

    <div class="rightColumn" style="margin-top:50px;">

      //Cards down below
      <div class="card-grid">
        <div class="card-wrap" id="">
          <img src="https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg " class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga</p>
            <p class="ratePlace">Rating: 4,5</p>
          </div>
        </div>
        <div class="card-wrap" id=""><img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here2</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga222</p>
            <p class="ratePlace">Rating: 4,52</p>
          </div>
        </div>
        <div class="card-wrap" id=""><img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here3</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga333</p>
            <p class="ratePlace">Rating: 4,53</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

I have no errore in the console. Before the downvotes, I searched all the evening how to do, I will link here some links about it.

  1. https://codepen.io/jsartisan/pen/wKORYL
  2. https://www.w3schools.com/howto/howto_js_filter_lists.asp
  3. https://codepen.io/samyerkes/pen/Inaht
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Legeo
  • 784
  • 4
  • 20
  • 44

2 Answers2

1

There's several issues here:

  • Use the change event on select elements, not click
  • The outer instance of selectedValue is not available within the each() as you've used it in the argument list of the handler function, so it becomes the index of the current element instead. This breaks the logic.
  • The text() of .ratePlace is not an integer which can be parsed as it is prefixed with the text Rating:. Hence the output of parseInt is always NaN. To fix this you could put the rating value in its own data attribute to stop the confusion and need to parse the value
  • You can put the check of selectedValue in the event handler, not the each, that way you can avoid the loop entirely if it's not needed

You can also use the notSelected class in CSS to hide the content, and then use toggleClass() in jQuery to hide/show the elements as needed. With all that said, try this:

$("select").on("change", function() {
  let selectedValue = parseInt(this.value, 10) || 0;
  if (selectedValue === 0)
    return;

  $('.card-wrap').each(function() {
    let $cardWrap = $(this);
    let rate = $cardWrap.find(".ratePlace").data('rating');
    $cardWrap.toggleClass('notSearched', rate < selectedValue);
  })
});
.notSearched {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="columnsContainer">
  <div class="leftColumn">
    <div class="filterResearch">
      <select name="filter" id="searchFilter">
        <option value="all">Apply a filter</option>
        <option value="1">1 Star</option>
        <option value="2">2 Stars</option>
        <option value="3">3 Stars</option>
        <option value="4">4 Stars</option>
        <option value="5">5 Stars</option>
      </select>
    </div>
    <div id="map"></div>
    <div class="rightColumn" style="margin-top:50px;">
      <div class="card-grid">
        <div class="card-wrap">
          <img src="https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg " class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga</p>
            <p class="ratePlace" data-rating="1.5">Rating: 1,5</p>
          </div>
        </div>
        <div class="card-wrap">
          <img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here2</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga222</p>
            <p class="ratePlace" data-rating="3.52">Rating: 3,52</p>
          </div>
        </div>
        <div class="card-wrap">
          <img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here3</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga333</p>
            <p class="ratePlace" data-rating="4.53">Rating: 4,53</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Note that I changed some of the ratings to make the effect of changing the dropdown more obvious.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • I choose your answer because your code is shorter and, for me, easier to understand. Thanks for the lesson i really appreciate everything ( how i wrong to set the body of the html ) and the way you clearly explained all of my error. Thank you. You made my day. – Legeo Oct 11 '18 at 10:13
  • Just a little question, probably it's just a little bit off-this-topic, but this code has a strange behaviour if the cards are generated dynamically. If i set your last line `$cardWrap.toggleClass('notSearched', rate < selectedValue)` in this way `rate < selectedValue` the cards go away, but if i left the code in his original form it doesn't work. It's a problem due to [Event binding on dynamically created elements? ](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Legeo Oct 11 '18 at 10:33
  • 1
    The elements are selected when the `change` event fires on the select, so the fact they are dynamically created shouldn't make a difference. I'd suggest starting a new question with a clear example. – Rory McCrossan Oct 11 '18 at 10:38
1

First of all , the each function will return a callback function with two parameter first fr index and seconde the current looping element , so no need to pass the selected value in param , so it'll be overided by index ;

You can apply regular expression to cut off the real number then use the Math.round() , in order to extract the real number , then replace the comma (,) by dot (.) (js recognize real by dot not comma)

and then make comparison to show , or hide you elemet by adding a notSearched class dont forget to add in css the

.notSearched {
  display:none;
}

Below a working snippet : that show only by number of start you can edit the condition (> , < , <= etc ...)

$("select").on("click", function() {
  let selectedValue = this.value;
  if (selectedValue == "all") return;
  $('.card-wrap').each(function(index, element) {
    var text = $(element).find(".ratePlace").text();
    let number = text.match(/[0-9]*\,?[0-9]+/g);
    number = number[0].replace(",", ".");
    number = (Math.round(number));
    console.log(number, selectedValue ,   number >= selectedValue )
    number == selectedValue ? $(element).removeClass("notSearched") : $(element).addClass("notSearched");
  })
});
.notSearched {
  display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="columnsContainer">
  <div class="leftColumn">
    <div class="filterResearch">
      <select name="filter" id="searchFilter">
        <option value="all">Apply a filter</option>
        <option value="1">1 Star</option>
        <option value="2">2 Stars</option>
        <option value="3">3 Stars</option>
        <option value="4">4 Stars</option>
        <option value="5">5 Stars</option>
      </select>
    </div>
    <div id="map"></div>

    <div class="rightColumn" style="margin-top:50px;">

      //Cards down below
      <div class="card-grid">
        <div class="card-wrap" id="">
          <img src="https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg " class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga</p>
            <p class="ratePlace">Rating: 4,5</p>
          </div>
        </div>
        <div class="card-wrap" id=""><img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here2</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga222</p>
            <p class="ratePlace">Rating: 2,2</p>
          </div>
        </div>
        <div class="card-wrap" id=""><img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here2</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga222</p>
            <p class="ratePlace">Rating: 4,42</p>
          </div>
        </div>
        <div class="card-wrap" id=""><img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here2</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga222</p>
            <p class="ratePlace">Rating: 2,1</p>
          </div>
        </div>
        <div class="card-wrap" id=""><img src=" https://image.ibb.co/k4SSPK/Spinaci_Green_Dark_Blue.jpg" class="photo">
          <div class="restoName">
            <h3>Restaurant Name Here3</h3>
            <p class="restoAddress">In questo posto ci andrà l'indirizzo del ristorante in questione, sarà una stringa lunga333</p>
            <p class="ratePlace">Rating: 4,53</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52