RSS

Tag Archives: AngularJs

Internationalization Aspects for Web Applications

Making web applications that supports multiple languages might be a challenging to maintain. So before building you should consider several aspects that are concerned with internationalization.

In summary very often it is not only translating the texts to other “languages” but also supporting “specific culture/locale”s as well!!!.

First of all there are certain terms that are often described when it comes to supporting multiple languages.

Internationalization (I18n)

In software applications, internationalization (often shortened to “I18N , meaning “I – eighteen letters and then a -N”) is the process of planning and implementing applications and services so that they can easily be adapted to specific local languages translations and cultures, a process called localization(which described below) which also means making your applications and services “localizable”.

In Other words the process of changing your software so that it isn’t hardwired to one language/locale/culture.

 

Localization (l10n)

The process of adding the appropriate resources to your software so that a particular language/locale is supported. This often includes adding language translation files without re-implementing/rebuilding your application.

 

Approaches to Localizing Web Applications

For web applications you can either do the translations in server side or do it in the client side. This almost always depends on the way your web application has been developed. ie. if it is a SPA application written with AngularJS then doing the translations in client side is preferable.

 

Server Side Translations for ASP.NET Applications

Obvious choice is to use the .NET framework support to create resource files(.resx) in the application and get the framework support to set CurrentCulture and CurrentUICulture for the current request thread. You need to suffix resource files with standard culture acronym and appropriate resource values will be selected by framework. Visual studio has builtin support for managing resource files.

resources

In summary “CurrentCulture” will be used for date formatting, number formatting etc. and the CurrentUICulture will be used for resource translations. You can configure the settings as following in Web.config file.

<configuration>
<system.web>
<globalization culture="auto:en-US" uiCulture="auto:fr" />
</system.web>
</configuration>

 

Use of “auto” in globalization setting.

We can set the current culture and “ui culture” as shown above with “auto” prefixed setting. when we use “auto” client user browser’s settings will be used to detect cultures and if not present will be defaulted to “en-US” and “de” in above example. This is through accept-language” request header as shown below. These settings are typically found in OS level or changeable in browser settings.

accept-language

 

Set Current Culture and Current UI Culture Programatically

For ASP.NET applications culture settings can be set at application_beginrequest or application_aquirerequeststate. This will affect all web pages unless they have been written at page level as describe below

void Application_BeginRequest(object sender, EventArgs e)
{
  Thread.CurrentThread.CurrentCulture = new System.Globalization.CreateSpecificCulture("en-US");

  Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
}

Overriding Culture at Individual Page Level(ASP.NET Web Forms)

ASP.NET web forms has a virtual method called  “InitializeCulture” which can be overridden to change culture settings at page level as shown below.

protected override void InitializeCulture()
{
        Thread.CurrentThread.CurrentCulture = 
            CultureInfo.CreateSpecificCulture("en-US");
        Thread.CurrentThread.CurrentUICulture = new 
            CultureInfo("en-US");

        base.InitializeCulture();
}

Client Side Translations

For web applications client side translations are often done with the help of JSon files which acts as resource files.

Localization for Angular JS

Angular Js has built in support for datetime, currency simbol and number format culture support via https://docs.angularjs.org/guide/i18n. Language translations to be done easier in AngularJS, we can use https://github.com/angular-translate/angular-translate library.

In brie your angular application’s config phase you need to configure the translate provider service that provided with the library with some basic settings ie. path to language translation resources folder etc.  as shown below

function configure($logProvider, routerHelperProvider, exceptionHandlerProvider, $translateProvider) {
$translateProvider
 .addInterpolation('$translateMessageFormatInterpolation')
 .preferredLanguage('en')
 .fallbackLanguage('en')
 .useStaticFilesLoader({
 prefix: '/app/i18n/',
 suffix: '.json'
 });
}

You can maintain the translation files JSON in your project as indicated below

translation folder

translation json content

Translation JSON Example (Spanish-es)

Within the UI language translation key can be used with the directive given by the translation library as indicated below.

translation in UI

Above the “translate” is a directive given by angular translate library. “Splash_Msg” is a key in translation file which will be included in run time.

Internationalization Concerns

  • Date Time – Week month name translations should be done to support localization. It is often easier to find and use controls that supports these concerns or build your own that supports these features. When date time period calculations done it is often easier to do it with base neutral culture.
  • calendar

    French and English Language Supported Date Picker

    Bootstrap UI DateTime Picker (http://plnkr.co/edit/nLw9DMgOLDK1dTIOJq4Q?p=preview)

    Date time related concerns are probably be the most complex and challenging concern in localization. Time Zone related conversions are extremely hard to deal accurately in web applications with different locales.

  • Unit of Measure – This might be probably not very important but some parts of the world it is often specific units are being used when displaying data. e.g., in Russia, it is normal to use Russian abbreviations (in Cyrillic letters) instead of standard symbols, e.g. кг and not kg.
  • Monetary conversions – It is often useful to display monetary values with locale specific currency units or using money symbols specific to the culture. Frameworks like .NET framework and Angular l18n supports currency formatting and currency symbols but biggest concern is exchange rates.
  • Numeric Formats – In some cultures symbols have been used for different purposes. e.g. Comma and period being used  alternatively for decimals  33.3 (English) > 33,3 (German). Client side validations and server side validations should be used with care for these concerns and additional coding has to be done.
  • String translations – String translations for static string labels are relatively easier to do when it compared to culture specific formatting. Resource files with different languages are often used.

Language/Culture Selections

Culture and language selections can be done in variety of ways in web applications. It can be detected automatically based on request information or can be set by user as briefly described below.

  • Browser settings
    • accept-language http header present in request headers
    • Location of the client – Based on client request remote IP location can be detected and hence the culture can be set automatically.
  • User Selections
    • User selects language – Within the UI we can let user to select preferred language and change the language in user interface.
    • Store it in profile – Based on user registration or in user profile page we can set the language and culture.

What to Translate

  • Static Texts – Static text labels are relatively easily factored out to resource files
  • Application Data – Application data is probably one of the most difficult to be translated unless you use a dynamic translation service to translate data(e.g. Google Translate). It is difficult and inefficient to “store” these translation data and will be difficult to maintain highly changing data to be maintained with different languages unlike static text labels etc. present in a web site.
  • Error Messages – Error messages should also be translated to specific languages. Specially the client side validation script should be written to support multiple langues.
 
Leave a comment

Posted by on April 22, 2016 in .NET, AngularJs, ASP.NET, Javascript

 

Tags: , , , , ,

Optimizing AngularJS Directives By Using Compile Phase

Many AngularJs developers do not use compile phase in directives at all, instead they almost always use link function. I have seen this so much times. But refactoring them later might be painful and might introduce glitches. Learning to use compile function when appropriate is really important skill to have since it will improve performance of your application as well. Consider following AngularJs view fragment,

 <div ng-app="app">
    <div ng-controller="myController">
        <div ng-repeat="fruit in fruits">
            <my-directive fruit="{{fruit}}"></my-directive>
        </div>
    </div>
 </div>

And consider possible naive JS implementation for the directive.

angular.module('app', [])
    .controller('myController', function ($scope) {
    $scope.fruits = ["Bananas", "Apples", "Oranges", "Grapes"];
})
    .directive('myDirective', function ($log) {
    return {
        template: "<div>{{fruit}}</div>",

        link: function (scope, element, attrs) {

                $log.log('link phase:', attrs.fruit);
            
        }
    };
});

As you can see in the above code, common pitfall is all the code that is common to all directive instances and instance specific code in same good old link function! Think how this will impact for the performance of the application, if the directive lives inside of a “ngrepeat” directive and especially if the repeated collection is relatively large performance impact will be augmented. In the above implementation common code is wasting time by executing additional code in each of “ngrepeat” directive’s iterations.

Solution is to use compile function as shown in below implementation.

angular.module('app', [])
    .controller('myController', function ($scope) {
    $scope.fruits = ["Bananas", "Apples", "Oranges", "Grapes"];
})
    .directive('myDirective', function ($log) {
    return {
        template: "<div>{{fruit}}</div>",

        compile: function (element, attrs) {
            // Code in this block will be called once regardless of instance count
            $log.log('compile phase:', attrs.fruit);
            return function link(scope, element, attrs) {
                // Code in this block will be called for each directive instance
                $log.log('link phase:', attrs.fruit);
            };
        }
    };
});

One common use from compile phase is to do template customizations dynamically based on runtime conditions. If you run the above sample code in your browser you would see following console output, notice that compile phase log appears only once but for each iteration in ngrepeat item will be logged through link function of the directive.

directive output

What you should understand is in compile phase scope is not linked to directive content, so there are serious limitations on things you could do within it. What this means is you should avoid using it for registering DOM listeners etc. Compile phase is also useful to do template modifications dynamically hence it will be cloned and propagated to each and every directive instances.

Complete sample is available in following js fiddle.
http://jsfiddle.net/idimuthu/263oo2nw/

 
Leave a comment

Posted by on August 5, 2015 in AngularJs

 

Tags: , , , ,

Writing a Custom Directive Compatible With Native Angular Form Validators

Directive is one of angular’s construct that gives great power where I think probably angular shines a lot than other similar libraries. They are great containers to encapsulate domain logic and to build domain specific language. Angular js has number of built in directives that supports form processing and other common tasks. What I am going to show is how to write custom validator plugin to angular js form validators that can be  hooked in to framework itself without writing extra validation code ourself.

Consider following simple form. (assume angular js is included)

<html ng-app="myApp">
<head>
  <title>My Application</title>
</head>
<body ng-controller="MainCtrl as ctrl">
  <form ng-submit="ctrl.submit()" name="myForm">
    <input type="text" ng-model="ctrl.page.name" required ng-minlength="4">
    <input type="text" ng-model="ctrl.page.description" required>
    <input type="submit" value="Submit" ng-disabled="myForm.$invalid">
  </form>
</body>
<!---Content With Angular JS Included-->.....

Above our imaginary “page” model will be validated out of the box nicely with angulars built in validation framework. In this case “page” name with required field, minium length of 4 characters and “page” description which is also required. Here I am disabling “Submit” button when the form is invalid.

 <input type="submit"
        value="Submit"
        ng-disabled="myForm.$invalid">

Notice that this acts as a validation group validator (ASP.NET developers are using same named control). If the any of form controls are invalid the property would be set to true hence submit button will be disabled. Let’s imagine we need to add another text box where we need to give page’s relative URL which must be started with “/” and until its validated form submission must be disabled. There are many ways of solving this but if we could hook our custom directive into angular validation framework then it would be not only very clean and robust but also you don’t need to write additional code to validate and decorate the UI.

(function(module) {
    function relativeUrl(){

       return {
            require:'ngModel',
            restrict:'A',
            link : function(element,scope, attributes, ngModel ){
                 ngModel.$validators.relativeUrl = function(modelValue) {
                     if(!modelValue || modelValue && modelValue.charAt(0) !=='/'){
                        return false;
                     }else{
                         return true;
                     }
                 }
            }
       };
    }
    module.directive('relativeUrl', relativeUrl);
})(
    angular.module('app')
);

In above we could inject “ngModel” built in angular controller we use quite often which allows to hook into angulars built in validation framework.

Page Submit Validator for Relative URLS Error Display

Page Submit Validator for Relative URLs Success

It is when all three input gets green that submit button will be enabled. You would observe that built in angular classes will be added up dynamically when according to the input text we type into the relative url textbox.

<input type="text" relative-url="" class="form-control ng-dirty ng-valid-parse ng-valid ng-valid-relative-url ng-touched" name="url" ng-model="relativeUrl" id="url">

This would be additional advantage when giving visual feedback to user when input is valid or invalid. I have added very basic input styling for that but styling you could do is far beyond this.

input.ng-valid{
            background-color: greenyellow;
            border: 1px solid darkgreen;

}
input.ng-invalid {
            border: 2px solid red;
}
 
Leave a comment

Posted by on May 13, 2015 in AngularJs

 

Tags: , , ,