Sort div order alphabetically based on contents

Sort div order alphabetically based on contents.

Hi all

I have a simple page here to explain my question.

http://www.ttmt.org.uk/sort/

It’s a group of divs that each have a letter.

Is it possible to rearrange the div’s so they are alphabetically in order - A,B,C,D

I haven’t attempted any code yet but is posible to add a reference to the div’s into an array and then order the array based on the letter in the div - that sounds crazy but i can’t think of any other way of doing this.

Thanks in advane for any help.



<!DOCTYPE html>
<html lang="en">

	<head>	
		<meta charset="UTF-8">

		<!--jQuery-->
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

		<!--css-->
		<link rel="stylesheet" href="css/styles.css" />

		<style type="text/css">
      body{
        background: #eee;
        font-family: sans-serif;
      }

      .box{
        background: red;
        height: 200px;
        width: 200px;
      }
      .box h1{
        color: white;
        font-size: 3.5em;
        text-align: center;
      }

		</style>

		<title>Title of the document</title>
	</head>

<body>

  <div class="wrap">

    <div class="box one">
      <h1>B<h1>
    </div>

    <div class="box two">
      <h1>A<h1>
    </div>

    <div class="box three">
      <h1>D<h1>
    </div>

    <div class="box four">
      <h1>C<h1>
    </div>

  </div>

	<script>
	
	  $(function(){
	
	    var order = [];
	
	
	
	  })
	
	</script>
</body>

</html>


OK so I’ve got a bit further but I’m struck again.

http://www.ttmt.org.uk/sort-1/

I’ve got it working alphabetically so the div are reordered in the correct order - A,B,C,D

My problem now is I want to also reordred the div numerically, the div with the highest number at the top

I have a separate button to reorder by number and I used the same type of functions as the alphabetically reordering.

Can anyone see why the reordering by number doesn’t work.


<!DOCTYPE html>
<html lang="en">

	<head>	
		<meta charset="UTF-8">
  
		<!--jQuery-->
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
  
		<!--css-->
  
		<style type="text/css">
      body{
        background: #eee;
        font-family: sans-serif;
      }
      
      .box{
        background: red;
        height: 200px;
        width: 200px;
      }
      .box h1{
        color: white;
        font-size: 3.5em;
        text-align: center;
      }
      
      .box h2{
        color: black;
        font-size: 2.5em;
        text-align: center;
      }
		</style>
    
		<title>Title of the document</title>
	</head>
  
<body>
  
  <div class="wrap">
    
    <button id="alphBnt">Alphabetical</button>
    
    <button id="numBnt">Numerical</button>
    
    <div class="box one">
      <h1>B<h1>
      <h2>10.35</h2>  
    </div>
    
    <div class="box two">
      <h1>A<h1>
      <h2>100.05</h2>
    </div>
    
    <div class="box three">
      <h1>D<h1>
      <h2>200</h2>  
    </div>
    
    <div class="box four">
      <h1>C<h1>
      <h2>5,510.25</h2>
    </div>
      
  </div>  

	<script>
	  
	  $(function(){
	    
	    var alpha = [];
	    var number = [];
	    
	    $('.box').each(function(){
	      
	      var alphaArr = [];
	      var numArr = [];
	      
	      alphaArr.push($('h1', this).text());
	      alphaArr.push($(this));
	      alpha.push(alphaArr);
	      alpha.sort();
	      
	      numArr.push($('h2', this).text());
	      numArr.push($(this));
	      number.push(numArr);
	      number.sort(function(a,b){
	        return a-b
	      });
	    })
	    
	    $('#alphBnt').on('click', function(){
	      $('.box').remove();
	      for(var i=0; i<alpha.length; i++){
	        $('.wrap').append(alpha[i][1]);
	      }
	    })
	    
	    $('#numBnt').on('click', function(){
	      $('.box').remove();
	      for(var i=0; i<number.length; i++){
	        $('.wrap').append(number[i][1]);
	      }
	    })
	    
	  })
	
	</script>
</body>

</html>

Hi,

You don’t need to create so many arrays. You can just get a reference to all of the divs you want to sort, then use JavaScript’s native .sort() function.

var $divs = $("div.box");

$('#alphBnt').on('click', function(){
    var alphabeticallyOrderedDivs = $divs.sort(function(a,b){
        return $(a).find("h1").text() > $(b).find("h1").text();
    });
    $("#container").html(alphabeticallyOrderedDivs);
});
	    
$('#numBnt').on('click', function(){
    var numericallyOrderedDivs = $divs.sort(function(a,b){
        return $(a).find("h2").text() > $(b).find("h2").text();
    });
    $("#container").html(numericallyOrderedDivs);
});

fiddle

1 Like

Thanks Pullo, your way is obviously a lot better than mine.

I think I understand whats going on here but could you give a quick explanation of how this works.

How does this sort the returning divs?


var alphabeticallyOrderedDivs = $divs.sort(function(a,b){
        return $(a).find("h1").text() > $(b).find("h1").text();
    });

Sure.
You are passing sort() a callback.
This callback is called many times over for your array, where a is the current item and b is the next item.
The callback compares both items and returns 0 if the two elements are equal, a negative number if a should be before b and a positive number if b should be before a.
Based on the return value it orders the items in the array correspondingly.

To sort the array in reverse order, you could do:

return $(a).find("h1").text() < $(b).find("h1").text();

instead of:

return $(a).find("h1").text() > $(b).find("h1").text();

You can use console.log to peek under the hood:

var myArray=[25, 8, 7, 41, 8, 99, 2, 55], 
    i = 1;

myArray.sort(function(a,b){
    console.log("Iteration " + i);
    console.log("Array: " + myArray);
    console.log("Comparing " + a + " with " + b);
    console.log(a > b? a + " is greater" : b > a? b + " is greater" : "Elements are the same"); 
    console.log("\
");
    i++;
    return b - a;
});

Does that help?

Thanks Pullo, that makes more sense now

Pullo, THIS makes more sense now but I’m sure the next thing will stump me.

Can you recommend any books, references, tutorials to get better at Javascript.

I’m sure I’ve read everything but maybe I’m reading the wrong things.

Sure.
It depends a bit on what works for you, but I would recommend this: https://learnable.com/books/jump-start-javascript
Then this: http://eloquentjavascript.net/

I would also recommend that you hang around the JS forum and try to answer questions here.
It is really an excellent way to learn, as well as to cement your own knowledge.

Hi Pullo!

Your solution seems to be exactly what I need, but i can’t seem to get it working!

On this site: http://www.webpol.dk/VisArtikel.asp?TemplateID=525&kat=5 (at first you’ll get redirected to the front page, but then just paste the url again), I’ve tried to adapt your code to our site, but it isn’t working. Would be look through the code and tell me why not? It’s the boxes containing our products, that need sorting!

The following jquery is on the site:

var $divs = $("div.vareboxtd");

$('#alphBnt').on('click', function () {
    var alphabeticallyOrderedDivs = $divs.sort(function (a, b) {
        return $(a).find(".varetekstiboks").text() > $(b).find(".varetekstiboks").text();
    });
    $(".midttable").append(alphabeticallyOrderedDivs);
});

$('#numBnt').on('click', function () {
    var numericallyOrderedDivs = $divs.sort(function (a, b) {
        return $(a).find(".varepointiboks").text() > $(b).find(".varepointiboks").text();
    });
    $(".midttable").append(numericallyOrderedDivs);
});

It would be greatly appreciated!

Hi,

I had a look at your site.
The page you link to is 4410 lines long and contains inline CSS and inline JS.
This makes it a bit difficult to see what is happening where.

Would it be possible for you to make a simple test page which removes the unnecessary JS, with minimal styling and only five or so products?
That way it’ll be much easier to get to the root of your problem.

When you have done that, just post the link back here.

Hej Pullo

I worked it out - still such a great solution.

As far as i could see, the problem was that some browsers couldn’t understand the output from the return function. Adding " ? 1 : -1" solved it all.

    return ($(a).find(".varetekstiboks").text() &gt; $(b).find(".varetekstiboks").text() ? 1 : -1);