Home » Angularjs » AngularJS different views based on Desktop or Mobile

AngularJS different views based on Desktop or Mobile

Posted by: admin November 11, 2017 Leave a comment

Questions:

I would like to use AngularJS for a single page webapp.
I am concerned if there is an elegant way to “send” different templates based on whether the client is a mobile or desktop.
Is there any way to do it ? Is it recommended that web server “understand” what the browser is and send the view accordingly so the browser always asks for template.html OR you write javascript so the browser will tell webserver to get the mobile/template.html ?

Answers:

How I would go about with this is to display one template to the user and make the template Responsive. Just because you are using AngularJS templates, I do not see a reason why you would not want to make the template responsive. I would not go for the solution that involves displaying a different template to the user based on the device browser.

That said, one way that I would do is:

  1. To have a simple script for the home / landing page of the web application that determines the browser / device. This can be found here.
  2. Next, depending on the browser / device, you redirect the user to a different route
  3. Have different routes based on the browser / device type – display a different template based on the route and thus identify if it s a mobile device or not based on the route.

The last step would be something like:

angular.module('myApp', []).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      //Display desktop version
      when('/desktop/homePage', {
        //Template for Desktop based browsers
        templateUrl: 'partials/desktop/home-page.html'
      }).
      //Display mobile version
      when('/mobile/homePage', {
        //Template for Mobile based browsers
        templateUrl: 'partials/mobile/home-page.html'
      }).
      otherwise({redirectTo: '/desktop/homePage'});
}]);

Questions:
Answers:

if you wanted to use the same URL but serve two different sets of HTML (say swap out large images and inpage videos for something else) I would do something like this

'use strict';

angular.module('MyApp', []).config(function ($routeProvider) {
// Magic sauce, imediate so the value is stored and we don't need to lookup every check
    var _isNotMobile = (function() {
        var check = false;
        (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
        return !check;
    })();

    // Swap out different HTML because you want to say, hide a video etc.
    $routeProvider
        .when('/', {
            templateUrl: (_isNotMobile )? 'views/MY_DESKTOP_VIEW.html':'views/m/MY_MOBILE_VIEW.html',
            controller: (_isNotMobile )?'MyHomeCtrl':'MyMobileCtrl'
          })
          .otherwise({
            redirectTo: '/'
          });
});

Questions:
Answers:

Responsive design will work well for smaller apps but gets rather messy when you move to bigger applications.

I’d personally suggest detecting the user agent on page load, and redirecting him to a separate mobile app if needed. You can still use most of your code base for both apps (simply import individual modules).

If your interested in detecting the user agent using javascript I suggest this solution (simply select javascript): http://detectmobilebrowsers.com/ the most extensive solution I’ve found so far

Questions:
Answers:

use boostrap. and it could be easily done.

 <!-- Display Only Screen > Big -->
 <div class="hidden-xs">
    <div ng-view class="section" ng-class="animate"></div>
    </div>
  <!-- Display Only Screen < Small -->
  <div class="visible-xs">
      <div ng-swipe-right="openSlide()">
        <div ng-view class="section" ng-class="animate"></div>
      </div>
 </div>

and in landing.html

  <div class="visible-xs" ng-include="'{{template path}}/desktop.html'" ></div>
  <div class="hidden-xs" ng-include="'{{template path}}/mobile.html'" ></div>

ANd in config

 $routeProvider
    .when(/,{
     templateUrl : "landing.html"
     controller : "landingCtrl"
    });

it works floawlessley for me. Its not of the way. maybe there could be another using pure JS. This just happened pout of the box since i am using boostrap and leverage it to my advantage.

Questions:
Answers:

BOOSTRAP + ANGULARJS solution to this problem:

You can check out the angular-match-media library. It is extremely small in size but very helpful and elegant.

https://github.com/jacopotarantino/angular-match-media

**Watch out: This is installed with bower install angular-media-queries; however, the path to the js file is /path/to/library/angular-media-queries/match-media

Questions:
Answers:

A bit late, but in something like your header, or nav controller, you could set the initial width:

angular
    .module('myApp')
    .controller('navCtrl', ['$rootScope', '$window',
        function($rootScope, $window) {
            $rootScope.is_mobile = ($window.innerWidth < 480);

And if you want checking on resize, go ahead and bind it:

angular.element($window).bind('resize', function() {
    $scope.$apply();
});

Then watch it:

$scope.$watch(function () {
    return $window.innerWidth;
}, function (innerWidth) {
    $rootScope.safeApply(function () {
        $rootScope.is_mobile = innerWidth < 480 // went with max device width
    });
});

Then in your HTML:

<div ng-if="$root.is_mobile">Show me only in mobile</div>