One place for hosting & domains

      Sort and Filter a Table Using Angular

      Introduction

      When building Angular applications, one of the cornerstones we will use is ng-repeat. Showing data is something that we do in applications like when we show a table of users or whatever other data we need to show our users. Today we’ll be looking at a way to sort and filter our tabular data. This is a common feature that is always useful so let’s look at what we’ll be building and dive right into the code.

      Here’s a quick demo: http://codepen.io/sevilayha/pen/AmFLE/

      Our application will allow us to:

      • Show a table of data (ng-repeat)
      • Sort by ascending or descending columns (orderBy)
      • Filter by using a search field (filter)

      These are three common functions in any application and Angular lets us implement these features in a very simple way. Let’s set up our sample application’s HTML and Angular parts and then look at how we can sort and filter.

      We’ll be using Bootstrap and Font Awesome to style our app. Let’s take a look at the Angular module first. This will be a simple module with one controller where we define a few variables and the list of data we’ll show to our users (we’ll be using sushi, yum). The files we will need are:

      Our demo is built inside of CodePen, so you can create the two files above or just work within your own CodePen. Here is the code for app.js

      
      angular.module('sortApp', [])
        .controller('mainController', function($scope) {
          $scope.sortType     = 'name'; 
          $scope.sortReverse  = false;  
          $scope.searchFish   = '';     
      
          
          $scope.sushi = [
            { name: 'Cali Roll', fish: 'Crab', tastiness: 2 },
            { name: 'Philly', fish: 'Tuna', tastiness: 4 },
            { name: 'Tiger', fish: 'Eel', tastiness: 7 },
            { name: 'Rainbow', fish: 'Variety', tastiness: 6 }
          ];
        });
      

      We have set the 3 variables and the list of sushi. Now let’s use this module in our HTML. Here is the HTML we’ll need for index.html:

      <div class="container" ng-app="sortApp" ng-controller="mainController">
        <div class="alert alert-info">
          <p>Sort Type: {{ sortType }}</p>
          <p>Sort Reverse: {{ sortReverse }}</p>
          <p>Search Query: {{ searchFish }}</p>
        </div>
      
        <table class="table table-bordered table-striped">
          <thead>
            <tr>
              <td>
                  Sushi Roll
                </a>
              </td>
              <td>
                Fish Type
                </a>
              </td>
              <td>
                Taste Level
                </a>
              </td>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="roll in sushi">
              <td>{{ roll.name }}</td>
              <td>{{ roll.fish }}</td>
              <td>{{ roll.tastiness }}</td>
            </tr>
          </tbody>
        </table>
      </div>
      

      We are loading Bootstrap, Font Awesome, and Angular. We will also apply the Angular module named sortApp and the Angular controller called mainController to the tag.

      We are also using an ngRepeat to loop over the sushi in our $scope.sushi array we created in our Angular module.

      Great. We have the list of data displayed all nicely for our users. Now let’s offer them some functionality by letting them sort the table.

      We will be accomplishing this sorting feature using two of the variables that we created earlier ($scope.sortType and $scope.sortReverse). We will also be using the Angular orderBy filter. Basically, applying a combination of sortType and sortReverse variables to an orderBy clause in our ng-repeat will sort the table.

      <tr ng-repeat="roll in sushi | orderBy:sortType:sortReverse">
      

      That’s all we need to change the sort order of our ngRepeat. If you refresh your page, you’ll see that your list is sorted by name in normal order. Now go into your Angular module and change the sortType variable to $scope.sortType="fish" and refresh the page. You’ll now see the table sorted by Fish Type. The next step is to change the headings of our table so that they will change the sortType variable. That will automatically sort our table without refreshing the page (as is the Angular way).

      Making Table Headings Clickable

      We’ll be adding links to our table headings. Let’s look at the thead section of our site and use ng-click to adjust the sortType variable.

      <td>
        <a href="#" ng-click="sortType = 'name';">
          Sushi Roll
        </a>
      </td>
      

      Now as you click the links across your table headers, you’ll see your table sorted since we are setting the sortType variable using ng-click.

      Changing the Sort Order

      Next up, we’ll be adding a way to change the sort order so users can sort by ascending or descending. The orderBy filter arguments offer a third parameter for reverse. We just have to pass in true or false to change the sort order. Currently, we have it set to false since we defined that as one of the variables earlier ($scope.sortReverse). The way we will give users the option to reverse the sort is to add sortReverse = !sortReverse in the ng-click of our table headers. This will change the order if users click the link.

      <td>
        <a href="#" ng-click="sortType = 'name'; sortReverse = !sortReverse">
          Sushi Roll
        </a>
      </td>
      

      Just add that to all the other ng-clicks in the code as well. Now if you click your header links, you’ll see the sort order changing. This isn’t very intuitive right now though since we don’t provide any sort of visual feedback that the sort is changing. Let’s add carets to show up and down to represent our current sort order. We’ll add an up and down caret here and then use ngShow and ngHide to show and hide the caret based on order.

      <td>
        <a href="#" ng-click="sortType = 'name'; sortReverse = !sortReverse">
          Sushi Roll
          <span ng-show="sortType == 'name' && !sortReverse" class="fa fa-caret-down"></span>
          <span ng-show="sortType == 'name' && sortReverse" class="fa fa-caret-up"></span>
        </a>
      </td>
      

      Now the up arrow will only show if sortType is name and sortReverse is set to true. Applying this to the other headers will give you the same effect. With a few Angular directives, we are now able to show proper feedback for sorting and for sort order. The last part of this tutorial will deal with filtering the table of data.

      Filtering data in an ng-repeat is fairly easy since Angular also comes with the filter module. There are only two things we need to do here: create the form and apply the form variable to the ng-repeat.

      Let’s create the form first. Above the code for the table and below the code for the alert.

      <form>
        <div class="form-group">
          <div class="input-group">
            <div class="input-group-addon"><i class="fa fa-search"></i></div>
            <input type="text" class="form-control" placeholder="Search the Fish" ng-model="searchFish">
          </div>
        </div>
      </form>
      

      A lot of that is Bootstrap markup to style our form beautifully, but the line we need to pay attention to is the input. This is where we define our ng-model to adjust the searchFish variable. Now as we type into that input box, you should see that variable change in the alert box above. With that variable bound and ready to go, all we have to do is apply it to our ng-repeat.

      Just like that, our filter will now be applied to the table. Go ahead and type into your filter box and see the table data change. You’ll also notice that the orderBy and filter will work together to find you the exact sushi roll that you want.

      Using some built-in Angular tools like ngRepeat, orderBy, filter, ngClick, and ngShow, we’ve been able to build a clean and fast table of data. This is a great look at the power that Angular has in building some great functionality into your own applications without too much work.

      Further Reading

      For more Angular goodness, here are some other great articles:

      Using JavaScript’s sort Method for Sorting Arrays of Numbers


      While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or
      edited it to ensure you have an error-free learning experience. It’s on our list, and we’re working on it!
      You can help us out by using the “report an issue” button at the bottom of the tutorial.

      The sort method available on the Array prototype allows you to sort the elements of an array and control how the sorting should be done. The aim of this post is to explain to you why, why not and how the sort method works when sorting an array of numbers.

      TL;DR — Sort an array of numbers in ascending order using:
      myArray.sort((a, b) => a - b);

      Arrays in JavaScript are data structures consisting of a collection of data items. Because Javascript is not a typed language, Javascript arrays can contain different types of elements – strings, numbers, undefined, etc. It’s most often a good idea to have all items in an array be of the same type however.

      One of the many operations that can be performed on an array is sorting. Whether you need to know the best students from a collection of grades, the big winners of Wall Street, how much data you’ve been consuming lately, it all involves organizing a collection through sorting.

      In the code examples below. We’ll get a collection of eggs in our nest, then sort them both in ascending and descending order. Ready? Let’s do it!

      Filling an Array

      We declare and initialize a nest array and prefill it with null values – for the moment:

      let eggsInNest = new Array(10).fill(null);
      

      We use the static fill method available on the Array constructor method. Next, let’s fill the 10 elements each with random values ranging from 1 – 200:

      eggsInNest = eggsInNest.map(() => (Math.floor(Math.random() * 200) + 1));
      

      Sorting

      We can then sort simply by calling the sort method on our array without arguments:

      eggsInNest.sort();
      
      // e.g.: [109, 136, 156, 188, 19, 190, 2, 34, 55, 90]
      

      As you can see, there’s a slight problem and sorting didn’t quite work out as you might have expected. Read on to learn why and how to fix it.

      By default the sort() method sorts the array:

      1. In ascending order
      2. With the items casted to strings

      To do this, the sort method calls the String() casting method on every array element and then compares the equivalent strings to determine the correct order.

      It would have been that easy, except for the fact that items are compared as strings, which has items sorted as if they were strings of characters instead of numbers. In short, most times, using the sort method without a callback method doesn’t quite work, because sort doesn’t sort the way we expect. Instead, it needs to be explicitly told how to do so – with a callback function.

      The callback function or, technically, comparison function receives two arguments (called a and b by convention) and should return 1 if the first argument should preceed the second, -1 if the second argument should preceed the first and 0 if they are equal. Whew! 😓


      Let’s create a sortEggsInNest comparison function:

      function sortEggsInNest(a, b) {
        if (a > b) {
          return 1;
        } else if (b > a) {
          return -1;
        } else {
          return 0;
        }
      }
      
      

      If you want to be a hotshot 😎, you could reduce the sortEggsInNest comparison function with a ternary operator like so:

      function sortEggsInNest(a, b) {
        return a > b ? 1 : b > a ? -1 : 0;
      }
      

      Then we can call the sort method again but this time passing in the sortEggsInNest comparison function:

      eggsInNest.sort(sortEggsInNest);
      

      And yes, it works… in ascending order.

      Descending order

      Need to sort in descending order? Just swap the return 1 in the comparison function with return -1 like so:

      function sortEggsInNest(a, b) {
        if (a > b) {
          return -1;;
        } else if (b > a) {
          return 1;;
        } else {
          return 0;
        }
      }
      

      Or, the short version using ternary operators:

      function sortEggsInNest(a, b) {
        return a > b ? -1 : b > a ? 1 : 0;
      }
      

      A Shorter Way with Numbers

      Finally, there’s even a shorter way to write the comparison function. Here:

      eggsInNest.sort((a, b) => a - b);
      

      This is only Ok because the comparison function only returns 1, -1 or 0. and subtracting the two intermediate values yields exactly that. However keep in mind – this can only be used with numeric types or objects whose valueOf() method returns numeric values (such as the Date object).

      Further Reading

      sort is one of many Array Mutator Methods along with shift, splice, reverse and others. For more info on all methods see How To Use Array Methods in JavaScript: Mutator Methods



      Source link