<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Angular Bootstrap Switch Demo</title>


  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">

  <!-- latest bootstrap-switch release -->
  <link rel="stylesheet" href="https://rawgit.com/nostalgiaz/bootstrap-switch/master/dist/css/bootstrap3/bootstrap-switch.css">

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>

  <!-- latest bootstrap-switch release -->
  <script src="https://rawgit.com/nostalgiaz/bootstrap-switch/master/dist/js/bootstrap-switch.js"></script>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  <script src="https://rawgit.com/frapontillo/angular-bootstrap-switch/develop/common/module.js"></script>
  <script src="https://rawgit.com/frapontillo/angular-bootstrap-switch/develop/src/directives/bsSwitch.js"></script>


</head>

<body ng-app="switchApp">
  
  <div ng-controller="SwitchController">
    <div ng-repeat="c in checkboxes">
      <input id="check_{{ c }}" bs-switch emit-change="{{ c }}" ng-model="check[c]" switch-active="{{ active }}" type="checkbox">
    </div>  

    <p>Value is {{check}}</p>

    <p>
      <input type="button" value="Toggle activation" ng-click="toggleActive()" />
      <input type="button" value="Toggle model" ng-click="toggleModel()" />
    </p>
    
    <textarea id="log" style="width: 90%; margin: 1em 5%;height: 12em;"></textarea>

  </div>

  <!-- demo app -->
  <script>
    var myApp = angular.module('switchApp', ['frapontillo.bootstrap-switch']);
    myApp
    .directive('emitChange', function() {
      return function(scope, elem, attr) {
        elem.on('switchChange.bootstrapSwitch', function (e) {
          scope.$emit('switchChanged', e.target.checked, attr.emitChange);
        })
      }
    }).controller('SwitchController', ['$scope',
      function($scope) {

        $scope.checkboxes = [ "foo", "bar", "baz", "bat"];

        $scope.check = {};
        angular.forEach($scope.checkboxes, function(k,i) { $scope.check[k] = (i % 2) !== 1; })
        $scope.active = true;

        $scope.toggleActive = function() {
          $scope.active = !$scope.active;
        };

        $scope.$on('switchChanged', function(scope, val, id)
        {
          angular.element('#log').val(id + ': ' + val)
        })

        $scope.toggleModel = function() {
          angular.forEach($scope.check, function(k,i) { $scope.check[i] = !k});
        };

      }
    ]);
  </script>
</body>

</html>
/**
 * angular-bootstrap-switch
 * @version v0.4.0-alpha.1 - 2015-04-01
 * @author Francesco Pontillo (francescopontillo@gmail.com)
 * @link https://github.com/frapontillo/angular-bootstrap-switch
 * @license Apache License 2.0(http://www.apache.org/licenses/LICENSE-2.0.html)
**/

(function() {
'use strict';

// Source: common/module.js
angular.module('frapontillo.bootstrap-switch', []);

// Source: dist/.temp/directives/bsSwitch.js
angular.module('frapontillo.bootstrap-switch').directive('bsSwitch', [
  '$parse',
  '$timeout',
  function ($parse, $timeout) {
    return {
      restrict: 'A',
      require: 'ngModel',
      link: function link(scope, element, attrs, controller) {
        var isInit = false;
        /**
         * Return the true value for this specific checkbox.
         * @returns {Object} representing the true view value; if undefined, returns true.
         */
        var getTrueValue = function () {
          if (attrs.type === 'radio') {
            return attrs.value || $parse(attrs.ngValue)(scope) || true;
          }
          var trueValue = $parse(attrs.ngTrueValue)(scope);
          if (!angular.isString(trueValue)) {
            trueValue = true;
          }
          return trueValue;
        };
        /**
         * Get a boolean value from a boolean-like string, evaluating it on the current scope.
         * @param value The input object
         * @returns {boolean} A boolean value
         */
        var getBooleanFromString = function (value) {
          return scope.$eval(value) === true;
        };
        /**
         * Get a boolean value from a boolean-like string, defaulting to true if undefined.
         * @param value The input object
         * @returns {boolean} A boolean value
         */
        var getBooleanFromStringDefTrue = function (value) {
          return value === true || value === 'true' || !value;
        };
        /**
         * Returns the value if it is truthy, or undefined.
         *
         * @param value The value to check.
         * @returns the original value if it is truthy, {@link undefined} otherwise.
         */
        var getValueOrUndefined = function (value) {
          return value ? value : undefined;
        };
        /**
         * Get the value of the angular-bound attribute, given its name.
         * The returned value may or may not equal the attribute value, as it may be transformed by a function.
         *
         * @param attrName  The angular-bound attribute name to get the value for
         * @returns {*}     The attribute value
         */
        var getSwitchAttrValue = function (attrName) {
          var map = {
              'switchRadioOff': getBooleanFromStringDefTrue,
              'switchActive': function (value) {
                return !getBooleanFromStringDefTrue(value);
              },
              'switchAnimate': getBooleanFromStringDefTrue,
              'switchLabel': function (value) {
                return value ? value : '&nbsp;';
              },
              'switchIcon': function (value) {
                if (value) {
                  return '<span class=\'' + value + '\'></span>';
                }
              },
              'switchWrapper': function (value) {
                return value || 'wrapper';
              },
              'switchInverse': getBooleanFromString,
              'switchReadonly': getBooleanFromString
            };
          var transFn = map[attrName] || getValueOrUndefined;
          return transFn(attrs[attrName]);
        };
        /**
         * Set a bootstrapSwitch parameter according to the angular-bound attribute.
         * The parameter will be changed only if the switch has already been initialized
         * (to avoid creating it before the model is ready).
         *
         * @param element   The switch to apply the parameter modification to
         * @param attr      The name of the switch parameter
         * @param modelAttr The name of the angular-bound parameter
         */
        var setSwitchParamMaybe = function (element, attr, modelAttr) {
          if (!isInit) {
            return;
          }
          var newValue = getSwitchAttrValue(modelAttr);
          element.bootstrapSwitch(attr, newValue);
        };
        var setActive = function () {
          setSwitchParamMaybe(element, 'disabled', 'switchActive');
        };
        /**
         * If the directive has not been initialized yet, do so.
         */
        var initMaybe = function () {
          // if it's the first initialization
          if (!isInit) {
            var viewValue = controller.$modelValue === getTrueValue();
            isInit = !isInit;
            // Bootstrap the switch plugin
            element.bootstrapSwitch({
              radioAllOff: getSwitchAttrValue('switchRadioOff'),
              disabled: getSwitchAttrValue('switchActive'),
              state: viewValue,
              onText: getSwitchAttrValue('switchOnText'),
              offText: getSwitchAttrValue('switchOffText'),
              onColor: getSwitchAttrValue('switchOnColor'),
              offColor: getSwitchAttrValue('switchOffColor'),
              animate: getSwitchAttrValue('switchAnimate'),
              size: getSwitchAttrValue('switchSize'),
              labelText: attrs.switchLabel ? getSwitchAttrValue('switchLabel') : getSwitchAttrValue('switchIcon'),
              wrapperClass: getSwitchAttrValue('switchWrapper'),
              handleWidth: getSwitchAttrValue('switchHandleWidth'),
              labelWidth: getSwitchAttrValue('switchLabelWidth'),
              inverse: getSwitchAttrValue('switchInverse'),
              readonly: getSwitchAttrValue('switchReadonly')
            });
            if (attrs.type === 'radio') {
              controller.$setViewValue(controller.$modelValue);
            } else {
              controller.$setViewValue(viewValue);
            }
          }
        };
        /**
         * Listen to model changes.
         */
        var listenToModel = function () {
          attrs.$observe('switchActive', function (newValue) {
            var active = getBooleanFromStringDefTrue(newValue);
            // if we are disabling the switch, delay the deactivation so that the toggle can be switched
            if (!active) {
              $timeout(function () {
                setActive(active);
              });
            } else {
              // if we are enabling the switch, set active right away
              setActive(active);
            }
          });
          function modelValue() {
            return controller.$modelValue;
          }
          // When the model changes
          scope.$watch(modelValue, function (newValue) {
            initMaybe();
            if (newValue !== undefined) {
              element.bootstrapSwitch('state', newValue === getTrueValue(), false);
            }
          }, true);
          // angular attribute to switch property bindings
          var bindings = {
              'switchRadioOff': 'radioAllOff',
              'switchOnText': 'onText',
              'switchOffText': 'offText',
              'switchOnColor': 'onColor',
              'switchOffColor': 'offColor',
              'switchAnimate': 'animate',
              'switchSize': 'size',
              'switchLabel': 'labelText',
              'switchIcon': 'labelText',
              'switchWrapper': 'wrapperClass',
              'switchHandleWidth': 'handleWidth',
              'switchLabelWidth': 'labelWidth',
              'switchInverse': 'inverse',
              'switchReadonly': 'readonly'
            };
          var observeProp = function (prop, bindings) {
            return function () {
              attrs.$observe(prop, function () {
                setSwitchParamMaybe(element, bindings[prop], prop);
              });
            };
          };
          // for every angular-bound attribute, observe it and trigger the appropriate switch function
          for (var prop in bindings) {
            attrs.$observe(prop, observeProp(prop, bindings));
          }
        };
        /**
         * Listen to view changes.
         */
        var listenToView = function () {
          if (attrs.type === 'radio') {
            // when the switch is clicked
            element.on('change.bootstrapSwitch', function (e) {
              // discard not real change events
              if (controller.$modelValue === controller.$viewValue && e.target.checked !== $(e.target).bootstrapSwitch('state')) {
                // $setViewValue --> $viewValue --> $parsers --> $modelValue
                // if the switch is indeed selected
                if (e.target.checked) {
                  // set its value into the view
                  controller.$setViewValue(getTrueValue());
                } else if (getTrueValue() === controller.$viewValue) {
                  // otherwise if it's been deselected, delete the view value
                  controller.$setViewValue(undefined);
                }
              }
            });
          } else {
            // When the checkbox switch is clicked, set its value into the ngModel
            element.on('switchChange.bootstrapSwitch', function (e) {
              // $setViewValue --> $viewValue --> $parsers --> $modelValue
              controller.$setViewValue(e.target.checked);
            });
          }
        };
        // Listen and respond to view changes
        listenToView();
        // Listen and respond to model changes
        listenToModel();
        // On destroy, collect ya garbage
        scope.$on('$destroy', function () {
          element.bootstrapSwitch('destroy');
        });
      }
    };
  }
]).directive('bsSwitch', function () {
  return {
    restrict: 'E',
    require: 'ngModel',
    template: '<input bs-switch>',
    replace: true
  };
});
// Source: bsSwitch.suffix
})();