AngularJS – Custom filter to show Arabic numbers

Photo by Maxwell Nelson on Unsplash

Today, we will create a custom AngularJS filter to convert English numbers into Arabic numbers, which is also useful for RTL AngularJS applications and multilingual AngularJS applications.

AngularJS provides filters components, which help you manipulate your HTML binding data. You can use filters to format dates, currencies, and more.

An example of what AngularJS filter can do is imagine you have retrieved a date from your database and render it.
In many cases, it will be shown in milliseconds format like this 1400956671914, so you can’t show it to a user in this un-friendly way.

Using the AngularJS filter, you can start adding the date filter and choose the date format in this way.

				
					{{ 1490648400000 | date: 'dd-MM-yyyy' }}
				
			

This results in user-friendly date formate as following 28-03-2017.

To read more about AngularJS filters check:  Filter components in AngularJS

Custom AngularJS filter

AngularJS has a .filter() method for each Module, so we will add a custom filter to convert Latin script (English) numbers to Arabic.

Start with creating your Angular App; then, you can attach the filter module to your app.

				
					var app = angular.module('app', []); app.filter('ngArabicNumber', function () { 
        return function () {
            return;
        };
    });
				
			

It’s easy, as you can see, we pass the filter name ‘ngArabicNumber, then return a function that allows us to keep watching the binding values.

Next, we want to define what English and Arabic numbers should be to map every English number to its corresponding Arabic one.

				
					app.filter('ngArabicNumber', function () { 

        return function (number) {
        
            var englishNumbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
            var arabicNumbers = ['١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩', '٠'];
            
            return; 
            
        };
    });
				
			

Also, you can see we have added a passed variable to our function, which is the English number we want to convert, and from your views, you can handle this using the way we have used it in the date filter, assuming that myNumber is a pre-defined value in your controller

				
					app.controller('MainCtrl', function($scope){ 
        $scope.myNumber = 5; 
    });
				
			

Then, we can return to our filter to handle the mapping part. First, convert the number to a string and set up a for loop to handle mapping the numbers using RegExp

				
					app.filter('ngArabicNumber', function () { 

        return function (number) {
        
            var englishNumbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
            var arabicNumbers = ['١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩', '٠'];
            
            var numberToString = number.toString();
            
            for (var i = 0; i < englishNumbers.length; i++) {
                numberToString = numberToString.replace(new RegExp(englishNumbers[i], 'g'),          arabicNumbers[i]);
                } 
                
        return;
                
    }; 
});
				
			

You have an Arabic number stored in your variable ‘numberToString.’ What we have to do next is to return it to the binding DOM.

				
					app.filter('ngArabicNumber', function () { 

        return function (number) {
        
            var englishNumbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
            var arabicNumbers = ['١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩', '٠'];
            
            var numberToString = number.toString();
            
            for (var i = 0; i < englishNumbers.length; i++) {
                numberToString = numberToString.replace(new RegExp(englishNumbers[i], 'g'),          arabicNumbers[i]);
                } 
                
        return numberToString;
                
    }; 
});
				
			

Notice that now your view will always show an Arabic number instead of the English one, but what if you are working on multilingual AngularJS applications. Hence, you have to handle when you need to convert the number to Arabic and show it as an English number.

Handle the filter for multilingual AngularJS applications

Thanks to Angular Filter, you can perform your transitional filter based on an evaluated condition, so in our case, we need to convert the English number into an Arabic number only when the user changes his locale to Arabic

Start by editing your views to be like this

				
					{{ myNumber | ngArabicNumber: (lang == 'ar') }}
				
			

:(lang == ‘ar’) is a condition that detects do we have to apply the ngArabicNumber filter or not.

Now, go to our created filter to pass this condition

				
					app.filter('ngArabicNumber', function () {

        return function (number, isArabic) {
        
        var englishNumbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
        var arabicNumbers = ['١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩', '٠'];
        
        var numberToString = number.toString();
        
        if (isArabic) {
        
            for (var i = 0; i < englishNumbers.length; i++) {
                numberToString = numberToString.replace(new RegExp(englishNumbers[i], 'g'), arabicNumbers[i]);
                }
                
        } else { 
            return number;
        } 
        
        return numberToString;
                
    };
});
				
			

It is clear that what we have updated in our filter, we have told the filter to convert the English number into Arabic number only if ‘User locale is Arabic’; else, we will return the English number.

you can see a demo on codepen for this here with some enhancement