Dividing a List Automatically in Ionic Framework

posted in: Uncategorized | 10

As mentioned by Raymond Camden on Twitter, JQuery Mobile has the ability to automatically divide a list of items by a given property. By default, it is done alphabetically by letter similar to the Songs view in the Music app on iOS. It also has the ability to accept a custom function to change the default behaviour of how the list is divided.

The Ionic Framework currently does not have this functionality of automatically dividing a list (As of Beta 14).

I decided to look at tackling this as an external module (ion) and then see if the Ionic guys are interested in merging it into the core framework. It’s on GitHub!

Setup

To use the module, you’ll need to pull in the module’s script file AFTER Ionic script and BEFORE your app.js script.

<script src="ionic-ion-autoListDivider.js"></script>

You’ll then need to import the module into your app.

angular.module('ionicApp', ['ionic','ionic.ion.autoListDivider'])

Basic Usage

Our most basic markup will look like this:

<ion-list>
	<ion-item auto-list-divider auto-list-divider-value="{{item.propertyName}}" ng-repeat="item in items">
</ion-list>

Here, we’re taken an ng-repeat where items is a sorted array of objects and added the auto-list-divider and auto-list-divider-value attributes. auto-list-divider does not require a value. auto-list-divider-value should be the value you are dividing/categorizing on.

NOTE: You can also use Angular’s orderBy for sorting the array.

By default, the directive will categorize by the first letter of whatever value is passed into auto-list-divider-value.

A automatically dividing list

Custom Dividing Function

This directive also allows you to change the way items are categorized. For example, say we have an array of users and we want to divide by gender, we can define a function in our controller’s $scope and pass a reference of that function to our directive via the auto-divider-function attribute.

<ion-list>
        <ion-item auto-divider auto-divider-value="{{item.user.gender}}" auto-divider-function="dividerFunction" class="item-avatar" ng-repeat="item in items">
    </ion-item>
</ion-list>

… and in your controller:

$scope.dividerFunction = function(key){
  return key;
}

How it Works

The directive itself is actually fairly simple. Remember that this directive is called on each list item that is bound.

First we grab the value of the auto-list-divider-value.

var key = attrs.autoListDividerValue;

and define our default divide function:

var defaultDivideFunction = function(k){
	return k.slice( 0, 1 ).toUpperCase();
}

The next bit is called in a function via a $timeout set to 0. This is to let the browser (and Angular) finish what it’s doing before we attempt to do anything.

We attempt to get the auto-divider-function but default to the default function and then call that function, storing the value.

var divideFunction = scope.$apply(attrs.autoListDividerFunction) || defaultDivideFunction;
var divideKey = divideFunction(key);

If the divide key (the value of what divider this item should be under) is different than the divide key of the last item, we insert a new divider before the current list item.

if(divideKey != lastDivideKey) { 
	var contentTr = angular.element("<div class='item item-divider'>"+divideKey+"</div>");
	element[0].parentNode.insertBefore(contentTr[0], element[0]);
}

… and finally take note of the current divide key.

lastDivideKey = divideKey;

And that’s it!

Conclusion

Using this directive, you can accomplish dividers in your list automatically without having make any major changes to your code or cluttering your controller. Have any questions? Feel free to comment below. Have any issues? Feel free to open an issue on GitHub!

My name is Andrew McGivery. I currently work full time as an application developer at Manulife Financial in Canada. My current passion is building and leading highly engaged teams where employee happiness, learning, and growth is a priority.

10 Responses

  1. Thanks, I’ll definitely be using this. What about also adding a vertical line on the right with A-B-C etc so if user clicks on the letter it jumps to that section?

  2. Awesome, Andrew!

    After changing the example form auto-divider auto-divider-value=”{{item.user.gender}}” to auto-list-divider auto-list-divider-value=”{{item.user.gender}}” it worked as expected!

    Greetings

  3. Deepak Jain

    Hello sir,
    I want to show list by alphabetically which is contain array of items 3090 and also containing with Special symbols i-e & etc and numbers i-e 2g etc how to give auto divider for that

  4. Jack Seemon

    When used with tab, an extra space will be addd to the top of the table.

  5. Hello,
    This is great but I want to remove particular item from the list for that I have to use splice. when I am using splice how to reload the array from the controller. Please help me in this.
    Thanks,

  6. Thank you! A little mistake: it’s ‘auto-list-divider-function’ and not ‘auto-divider-function’!

  7. How could I update the value of auto-divider-value=”{{item.user.gender}}” on button click? For example it I wanted to change the value that is dividing the list and re draw the list accordingly?

Leave a Reply