0

I found this code on Codepen, modified it a little bit, but don't know how to have the default list appear when the button is clicked again.

When the button is clicked, the list becomes alphabetical, but when it's clicked again, I want it to go back to default.

<ul id="test">
    <li>Sem lacinia quam venenatis vestibulum.</li>
    <li>Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</li>
    <li>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</li>
</ul>

<button id="button">Sort by Title</button>


(function($) {
    $(function() {
        $("button").click(function() {
            $("li", "#test").sort(function(a, b) {
                return $(a).text() > $(b).text();
            }).appendTo("#test");
            $("button").text("Sort by Default");
        });
    });
})(jQuery);
Weebs
  • 155
  • 2
  • 10
  • The sort function modify the order of the elements in the DOM, to be able to go back to the original, you'll have to create a copy of the list, previous to the sorting and replace the sorted one with it. – DIEGO CARRASCAL Apr 21 '17 at 13:16

4 Answers4

1

Assign positions for the initial state using jQuery's data() method:

$("li", "#test").each(function(idx) {
  $(this).data('position', idx);
});

If the button's text is "Sort by Default," sort based on the initial position. Otherwise, sort based on the text:

$("button").click(function() {
  $("li", "#test").sort(function(a, b) {
    if($("button").text() === "Sort by Default") {
      return $(a).data('position') - $(b).data('position');
    }
    else {  //Sort by Title
      return $(a).text() > $(b).text() ? 1 :
             $(a).text() < $(b).text() ? -1 :
             0
    }
  }).appendTo("#test");

Note that I've changed the "Sort by Title" algorithm. The code you borrowed returns only true or false in the sort() method, which doesn't guarantee a proper sort. Instead, the sort() method should return a number greater than 0 , 0, or less than 0, based on whether the first parameter is greather than, equal to, or less than the second parameter.

Finally, toggle the button's text when clicked:

  $(this).text(function(_, txt) {
    return txt === "Sort by Default" ? "Sort by Title" : "Sort by Default";
  });

Snippet:

$("li", "#test").each(function(idx) {
  $(this).data('position', idx);
});

$("button").click(function() {
  $("li", "#test").sort(function(a, b) {
    if($("button").text() === "Sort by Default") {
      return $(a).data('position') - $(b).data('position');
    }
    else {
      return $(a).text() > $(b).text() ? 1 :
             $(a).text() < $(b).text() ? -1 :
             0
    }
  }).appendTo("#test");

  $(this).text(function(_, txt) {
    return txt === "Sort by Default" ? "Sort by Title" : "Sort by Default";
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="test">
  <li>Sem lacinia quam venenatis vestibulum.</li>
  <li>Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</li>
  <li>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</li>
</ul>

<button id="button">Sort by Title</button>
Rick Hitchcock
  • 35,202
  • 5
  • 48
  • 79
  • Thank you for the example, Rick! The code works exactly as I wanted it to. Now I just need to apply this logic to another piece of coding. – Weebs Apr 21 '17 at 16:17
0

The old order needs to be saved somewhere for it to come back

you can use this

jquery sort list based on data attribute value

and add a boolean flag to toggle which function to use on button click, either set alphabetically and toggle the flag, or order using the data-position and toggle the flag

Community
  • 1
  • 1
0

There is no "default". Once the elements have been sorted, they are now in a new state. You can't "go back", but instead would need to re-sort them to some new state.

What is that new state? Given any other sort of these elements, how would you define the desired sort?

You might for example give them some data attributes. Something like this:

<ul id="test">
    <li data-sortDefault="0">Sem lacinia quam venenatis vestibulum.</li>
    <li data-sortDefault="1">Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</li>
    <li data-sortDefault="2">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</li>
</ul>

Then any time you sort them, you can always sort them again based on that default. So you might store the current sort state in a variable, and then re-sort based on the state of that variable. Something like:

(function($) {
    var sorted = false;
    $(function() {
        $("button").click(function() {
            if (sorted) {
                // new logic to sort by data property
                // ...
            } else {
                // existing logic to sort alphabetically
                $("li", "#test").sort(function(a, b) {
                    return $(a).text() > $(b).text();
                }).appendTo("#test");
                $("button").text("Sort by Default");
            }
            sorted = !sorted;
        });
    });
})(jQuery);

For sorting by the data property, I suspect the logic would be very similar. Just off the top of my head, it might look like this:

$("li", "#test").sort(function(a, b) {
    return $(a).data('sortDefault') > $(b).data('sortDefault'); // check data instead of text
}).appendTo("#test");
$("button").text("Sort");

You can probably re-factor a bit to make it a little cleaner, including perhaps taking advantage of a toggle() function instead of .click(). But the idea should be the same. There's no "default", you just need to be able to define how you want the elements sorted.

David
  • 208,112
  • 36
  • 198
  • 279
0

This is a way to do it... It will go back to the original order because it stores a copy of it.

    <HEAD>
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    </HEAD>
    <BODY>
        <ul id="test">
        <li>Sem lacinia quam venenatis vestibulum.</li>
        <li>Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</li>
        <li>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</li>
    </ul>

    <button id="button">Sort by Title</button>

    </BODY>

    <SCRIPT>
        let clickToggle = true;
        let original = $("#test").html(); // copy original state.
        //alert(original);
    (function($) {
        $(function() {
            $("button").click(function() {
                if(clickToggle){
                    $("li", "#test").sort(function(a, b) {
                        return $(a).text() > $(b).text();
                    }).appendTo("#test");
                    $("button").text("Sort by Default");
                    clickToggle = false;
                }
                else{
                    $("#test").html(original);
                    clickToggle = true;
                }
            });
        });
    })(jQuery);
    </SCRIPT>
DIEGO CARRASCAL
  • 1,999
  • 14
  • 16