a blog for those who code

Monday 28 March 2016

Repeater Control in Ionic Framework with Grouping

In this post we will be discussing about repeater control in Ionic Framework with Grouping elements. In our previous post we had discussed about Repeater Control in Ionic Framework with Refresh where we get the elements and update it whenever we refresh the page. Now lets say you want to show those elements in Groups.


The Ionic Framework has a collection-repeat directive that you can use instead of ng-repeat because collection-repeat allows an app to show huge lists of items with great performance than ng-repeat.

At first we will update our index.html to the below code :

<body ng-app="starter">
  <ion-nav-bar class="bar-stable"></ion-nav-bar>
  <ion-nav-view></ion-nav-view>
</body>

Next we will write our Controller i.e. repeaterCtrl which will give us the data where before displaying we are sorting the data based on first_name.

.controller('repeaterCtrl', function ($scope) {
  $scope.values = window.Values.sort(function (a, b) {
    return a.first_name > b.first_name ? 1 : -1;
  });

  $scope.doRefresh = function () {
    $scope.values = window.Values;
    $scope.$broadcast('scroll.refreshComplete');
  }
})

We will also create a variable called values in our window element from which the data will be fed to our controller :

window.Values = [{ first_name: "Chris", last_name: "Jordon" },
    { first_name: "Hemant", last_name: "Joshi" },
    { first_name: "Apple", last_name: "Pie" },
    { first_name: "Sachin", last_name: "Tendulkar" },
    { first_name: "Shewag", last_name: "Paji" },
    { first_name: "Mahendra", last_name: "Singh" },
    { first_name: "Ajinkya", last_name: "Rahane" },
    { first_name: "Sunil", last_name: "Gavaskar" },
    { first_name: "Yuvraj", last_name: "Singh" },
    { first_name: "Harbajan", last_name: "Singh" }];

Next we will write our filter code as shown below. In this code we are getting the first character of first_name and then if it is unique we are adding it to the array with isDivider = true condition. We are also adding the full item into the array for displaying it.

.filter('groupByLastName', function ($parse) {
  var allValues = {};
  return function (input) {
    if (!input || !input.length) return;
    var output = [];
    var previousLetter;
    for (var i = 0, j = input.length; i < j && (item = input[i]) ; i++) {
      var currentLetter = item.first_name && item.first_name.charAt && item.first_name.charAt(0).toUpperCase();
      if (currentLetter && currentLetter !== previousLetter) {
        if (!allValues[currentLetter]) {
          allValues[currentLetter] = {
            isDivider: true,
            currentLetter: currentLetter
          };
        }
      output.push(allValues[currentLetter]);
      previousLetter = currentLetter;
      }
      output.push(item);
    }
  return output;
  };
})

Next we will write our logic for dividing the elements and showing in the front end. For this purpose we have written dividerColllectionRepeat directive as shown below : In the below code we are getting the item one by one in our compile function and then if the item is a divider we are changing the itemHeight and pepending a div element.

.directive('dividerCollectionRepeat', function ($parse) {
  return {
    prioprity: 1001,
    compile: compile
  };

  function compile(element, attr) {
    var height = attr.itemHeight || '75';
    var itemExpr = attr.collectionRepeat.split(' ').shift();
    attr.$set('itemHeight', itemExpr + '.isDivider ? 37 : ' + height);
    var children = element.children().attr('ng-hide', itemExpr + '.isDivider');
    element.prepend('<div class="item item-divider ng-hide" ng-show="' + itemExpr + '.isDivider" ng-bind="' + itemExpr + '.currentLetter"></div>')
  }

  return function postLink(scope, element, attr) {
    scope.$watch(itemExpr + '.isDivider', function (isDivider) {
      element.toggleClass('item-divider', !!isDivider)
    })
  }
})

Next we will write our page1.html which is created inside templates folder as shown below. In the below code we are creating a list using ion-list with each item added in a ion-item using collection-repeat directive. We are also using ion-refresher which will call the doRefresh() function on refreshing.

<ion-view view-title="Repeater Controller Example (Pull to Refresh)">
  <ion-content class="padding">
    <ion-refresher pulling-text="Update Date" on-refresh="doRefresh()"></ion-refresher>
    <ion-list>
      <ion-item collection-repeat="value in values | groupByLastName" divider-collection-repeat>
        <p>First Name : {{value.first_name}}</p>
        <p>Last Name : {{value.last_name}}</p>
      </ion-item>
    </ion-list>
  </ion-content>
</ion-view>

Our app.js file will have the code as shown below were we are configuring the state.

.config(function($stateProvider, $urlRouterProvider) {
  .state('page1', {
    url: "/page1",
    templateUrl: 'templates/page1.html',
    controller: 'repeaterCtrl'
  })

  $urlRouterProvider.otherwise('/page1');
}); 

After running you will get the following output :


Please Like and Share the CodingDefined.com Blog, if you find it interesting and helpful.

No comments:

Post a Comment