Ion-network directive


#1

Hello,
I made a directive to automatically detect if the device is connected or not to internet using the Cordova Network Information Plugin.
If the directive is set on a form element such as an input, a button, a select or a textarea, it will be disabled.
A css class is set depending on the connectivity (“online” or “offline”).
You can apply an interval to check the network, the default is 500 milliseconds.

Here is how to use it :

<style>
    .hide {
        display: none;
    }
    .hide.offline {
        display: block;
    }
</style>
<div class="hide" ion-network>
        You are disconnected
</div>
<button ion-network>Send to the Internet !</button>

If you want to change the interval of time, just pass a value in milliseconds to the attribute :

<button ion-network="3000">Check the network every 3 seconds</button>

And finally, here is the directive :

.directive('ionNetwork', function ($interval) {
    return {
        restrict: 'A',
        scope: {
            interval: '@?ionNetwork'
        },
        link: function (scope, element) {
            if (window.cordova) {
                var allowedNetworkStates = [Connection.WIFI, Connection.CELL_4G, Connection.CELL_3G, Connection.CELL_2G];
                var disabledTags = ['input', 'button', 'textarea', 'select'];
                var tag = element[0].tagName.toLowerCase();
                scope.interval = parseInt(scope.interval) || 500;

                function checkNetworkState() {
                    if (allowedNetworkStates.indexOf(navigator.connection.type) === -1) {
                        if (disabledTags.indexOf(tag) !== -1) {
                            element[0].disabled = true;
                        }
                        element.removeClass('online');
                        element.addClass('offline');
                    } else {
                        if (disabledTags.indexOf(tag) !== -1) {
                            element[0].disabled = false;
                        }
                        element.removeClass('offline');
                        element.addClass('online');
                    }
                }

                checkNetworkState();
                stop = $interval(checkNetworkState, scope.interval);

                scope.$on('$destroy', function() {
                    $interval.cancel(stop);
                });
            }
        }
    };
});

#2

Awesome job! Thanks for sharing this


#3

Thanks. ^^
Now I have to find a way to register a single $interval instance and share it through all the elements where the directive is set on a same page.


#4

Found something similar here

    app.run(function($rootScope) {
  // console.log("online:" + navigator.onLine);

  $rootScope.online = navigator.onLine ? 'online' : 'offline';
  $rootScope.$apply();

  if (window.addEventListener) {
    window.addEventListener("online", function() {
      $rootScope.online = "online";
      $rootScope.$apply();
    }, true);
    window.addEventListener("offline", function() {
      $rootScope.online = "offline";
      $rootScope.$apply();
    }, true);
  } else {
    document.body.ononline = function() {
      $rootScope.online = "online";
      $rootScope.$apply();
    };
    document.body.onoffline = function() {
      $rootScope.online = "offline";
      $rootScope.$apply();
    };
  }
});