Tuesday, September 12, 2017

Dynamically changing classes in Angular

I have a web page that has a potentially long header. On smaller screens the header wraps easily and can consume too much of the screen space. One option is to truncate the header to one line with an ellipsis. The option I chose to implement was to reduce the font size as the screen gets narrower.

There are many ways this can be done. I chose to implement one of two classes for the header depending on whether the client width was more than or less than 1024 pixels.

Start a new C# ASP.NET project called AdjustPointSize. Chose the empty template and uncheck 'Host in the cloud'.



Right-click the project in the solution explorer and select Add -> HTML Page. Name the new page "MainPage.html".

Replace the contents of MainPage with the following html.

<!DOCTYPE html>
<html ng-app="defaultApp">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script>
        angular.module("defaultApp",[])
            .controller("defaultCtrl", function ($scope, $window) {
                $scope.innerWidth = $window.window.innerWidth;

                angular.element($window).on('resize', function () {
                    $scope.$apply(function () {
                        $scope.innerWidth = $window.window.innerWidth;
                    });
                });
            });
    </script>
    <style>
        .largeHead {font-size: 24pt;}
        .smallHead {font-size: 12pt;}
    </style>
</head>
<body ng-controller="defaultCtrl">
    <div ng-class="(innerWidth < 640)?'smallHead':'largeHead'">Welcome to the Adjust Point Size Demo!</div>
</body>
</html>

You can run this immediately and you will see as you narrow the web page the font will suddenly get smaller.

The two key parts to this demo are the resize handler and the binding of ng-class.

We first use the angular.element function to get an angular window object and attach an event handler to the 'resize' event. This handler saves the window's innerWidth to a $scope variable. The handler is inside a $apply method to force re-evaluation of bindings affected by it. When the window size changes, the value of $scope.innerWidth is updated and anything bound to it is re-evaluated. Now we have to bind something to it.

The binding is in the ng-class definition. We compare the window width to a predefined value and assign one of two predefined classes to the DIV. When you make the window narrower or wider you will see the font change size.

The technique is very useful on mobile platforms where rotating from landscape to portrait will fire the event. It puts another tool in your responsiveness tool box.



No comments:

Post a Comment