Zorgan
Zorgan

Reputation: 9123

Sort divs based on values of child elements

I would like to sort the .choice_result divs based on the value of their .score child value. So with my js below, the .choice_result with a .score inside of 100%, should be the first div and not the last. Here's the js:

<div class="poll poll_answered">
        <div class="poll_div">
            <h1><strong>Percentages</strong></h1>
            <div class="poll_results" style="display: block;">

            <div class="choice_result" data-choice_percent="0">
                <p class="choice_result_text">First<p>

                <div class="choice_result_width">
                </div>
                <span class="score">0%</span>

            </div>   


            <div class="choice_result" data-choice_percent="0">
                <p class="choice_result_text">Second<p>

                <div class="choice_result_width">
                </div>
                <span class="score">0%</span>

            </div>


            <div class="choice_result" data-choice_percent="100">
                <p class="choice_result_text">Third<p>

                <div class="choice_result_width">
                </div>
                <span class="score">100%</span>

            </div>
        </div>
</div>

How would I do this?

Upvotes: 1

Views: 1834

Answers (2)

tao
tao

Reputation: 90013

This is probably what you're looking for:

$('.poll_results.sort-by-score').each(function(){
  $(this).html(
    $(this).find('.choice_result').sort(function(a, b) {
      let dsa = parseInt($(a).find('.score').eq(0).text()),
          dsb = parseInt($(b).find('.score').eq(0).text());
      return (dsa > dsb ? -1 : (dsa < dsb) ? 1 : 0);
    })
  );  
});

$('.poll_results.sort-by-score').each(function(){
  $(this).html(
    $(this).find('.choice_result').sort(function(a, b) {
      let dsa = parseInt($(a).find('.score').eq(0).text()),
          dsb = parseInt($(b).find('.score').eq(0).text());
      return (dsa > dsb ? -1 : (dsa < dsb) ? 1 : 0);
    })
  );  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="poll poll_answered">
  <div class="poll_div">
    <h1><strong>Percentages</strong></h1>
    <div class="poll_results sort-by-score" style="display: block;">

      <div class="choice_result" data-choice_percent="0">
        <p class="choice_result_text">First
        <p>
            <div class="choice_result_width"></div>
            <span class="score">0%</span>
      </div>


      <div class="choice_result" data-choice_percent="0">
        <p class="choice_result_text">Second
        <p>
            <div class="choice_result_width"></div>
            <span class="score">0%</span>

      </div>

      <div class="choice_result" data-choice_percent="100">
        <p class="choice_result_text">Third
        <p>

            <div class="choice_result_width"></div>
            <span class="score">100%</span>

      </div>
    </div>
  </div>
</div>
<div class="poll poll_answered">
  <div class="poll_div">
    <h1><strong>Not sorted percentages</strong></h1>
    <div class="poll_results" style="display: block;">

      <div class="choice_result" data-choice_percent="0">
        <p class="choice_result_text">First
        <p>
            <div class="choice_result_width"></div>
            <span class="score">0%</span>
      </div>


      <div class="choice_result" data-choice_percent="0">
        <p class="choice_result_text">Second
        <p>
            <div class="choice_result_width"></div>
            <span class="score">0%</span>

      </div>

      <div class="choice_result" data-choice_percent="100">
        <p class="choice_result_text">Third
        <p>

            <div class="choice_result_width"></div>
            <span class="score">100%</span>

      </div>
    </div>
  </div>
</div>

It will reorder .choice_results based on text() value from .score in each .poll_results.sort-by-score instances on your page.

Important note: This solution assumes .choice_result are the only children of .poll_results, as in your question.

Upvotes: 4

ibrahim mahrir
ibrahim mahrir

Reputation: 31682

$(".choice_result").sort(function(a, b) {
  a = parseFloat($(".score", a).text()); // get the value of .score element inside a
  b = parseFloat($(".score", b).text()); // get the value of .score element inside b
  return b - a;                          // sort descendently
}).appendTo(".poll_results");
.choice_result {
  border: 1px solid red;
  margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="poll poll_answered">
  <div class="poll_div">
    <h1><strong>Percentages</strong></h1>
    <div class="poll_results" style="display: block;">
      <div class="choice_result" data-choice_percent="0">
        <p class="choice_result_text">First
          <p>
            <div class="choice_result_width">
            </div>
            <span class="score">30%</span>
      </div>
      <div class="choice_result" data-choice_percent="0">
        <p class="choice_result_text">Second
          <p>
            <div class="choice_result_width">
            </div>
            <span class="score">0%</span>
      </div>
      <div class="choice_result" data-choice_percent="100">
        <p class="choice_result_text">Third
          <p>
            <div class="choice_result_width">
            </div>
            <span class="score">100%</span>
      </div>
    </div>
  </div>

Explanation:

Get all the .choice_result elements ($(".choice_result")). Then sort using .sort function, for each two elements a and b, get the .score element of each ($(".score", a or b)) then get the text using .text function and parse the number before % using parseFloat, then return a negative number if a should be before b, a positive one otherwise (b - a). After sorting, reappend the elements back to their container (appendTo(".poll_results")).

Upvotes: 3

Related Questions