Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                .container(ng-app="app" ng-controller="main as ctrl")
	.jumbotron
		h3 Angular Toggle Switch
		p Using&nbsp;
			a(href="https://github.com/cgarvis/angular-toggle-switch") Angular Toggle Switch
		
		button.btn.btn-default(type="button" ng-click="ctrl.refreshList()") Refresh

	.col-sm-6
		table.table.table-striped
			tr
				th.full-width Item
				th.toggle-column.text-center Enabled
			tr(ng-repeat="item in ctrl.items | orderBy: 'name' track by item.name")
				td.full-width {{ item.name }}
				td.toggle-column.text-center
					toggle(ng-model="item.isEnabled" ng-model-options="{ getterSetter: true }" on="Activated" off="Deactivated" onstyle="btn-success active" offstyle="btn-danger")
					label Enabled
						input(type="checkbox" ng-model="item._isEnabled")
              
            
!

CSS

              
                .full-width
	width 100%
	
// https://rawgit.com/ziscloud/angular-bootstrap-toggle/master/dist/angular-bootstrap-toggle.min.css

.checkbox label .toggle,
.checkbox-inline .toggle {
  margin-left: -20px;
  margin-right: 5px;
}
.toggle {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  position: relative;
  overflow: hidden;
}
.animation-disabled .toggle-group {
  transition: none;
  -webkit-transition: none;
}
.toggle-group {
  position: absolute;
  width: 200%;
  top: 0;
  bottom: 0;
  left: 0;
  transition: left 0.35s;
  -webkit-transition: left 0.35s;
  -moz-user-select: none;
  -webkit-user-select: none;
}
.toggle.off .toggle-group {
  left: -100%;
}
.toggle-on {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 50%;
  margin: 0;
  border: 0;
  border-radius: 0;
}
.toggle-off {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  right: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
}
.toggle-handle {
  position: relative;
  margin: 0 auto;
  padding-top: 0px;
  padding-bottom: 0px;
  height: 100%;
  width: 0px;
  border-width: 0 1px;
}
.toggle.btn {
  min-width: 59px;
  min-height: 34px;
}
.toggle-on.btn {
  padding-right: 24px;
}
.toggle-off.btn {
  padding-left: 24px;
}
.toggle.btn-lg {
  min-width: 79px;
  min-height: 45px;
}
.toggle-on.btn-lg {
  padding-right: 31px;
}
.toggle-off.btn-lg {
  padding-left: 31px;
}
.toggle-handle.btn-lg {
  width: 40px;
}
.toggle.btn-sm {
  min-width: 50px;
  min-height: 30px;
}
.toggle-on.btn-sm {
  padding-right: 20px;
}
.toggle-off.btn-sm {
  padding-left: 20px;
}
.toggle.btn-xs {
  min-width: 35px;
  min-height: 22px;
}
.toggle-on.btn-xs {
  padding-right: 12px;
}
.toggle-off.btn-xs {
  padding-left: 12px;
}

              
            
!

JS

              
                class Item {
	private _isEnabled: boolean = false;

	constructor(public name: string, isEnabled: boolean, private confirm: (item: Item, value: boolean) => any) {
		this._isEnabled = isEnabled;
	}
	
	isEnabled(value?: boolean): boolean | void {
		if (value === undefined) {
			return this._isEnabled;
		} else if ((value != this._isEnabled) && this.confirm) {
			this.confirm(this, value).then(confirmed => {
				if (confirmed) {
					this._isEnabled = value;
				}
			});
		}
	}
}

class MainController {
	items = [];

	static $inject = ['$q', '$timeout', '$window'];

	constructor(private $q: any, private $timeout: any, private $window: any) {
		this.refreshList();
	}

	private confirm(item: Item, newValue: boolean) {
		return this.$q((resolve, reject) => {
			if (newValue) {
				console.log('Confirming immediately');
				return resolve(true);
			}
			
			console.log('Confirming in a bit');
			this.$timeout(() => {
				console.log('Prompting user');
				const confirmed = this.$window.confirm('Are you sure you want to disable');
				return resolve(confirmed);
			}, 200);
		});
	}

	refreshList() {
		this.$timeout(() => {
			this.items = [
				new Item('Stuff', true, this.confirm.bind(this)),
				new Item('Things', false, this.confirm.bind(this))
			];
		}, 600);
	}
}

// https://rawgit.com/ziscloud/angular-bootstrap-toggle/master/dist/angular-bootstrap-toggle.js

(function () {
    'use strict';

    angular.module('ui.toggle', [])

        .value('$toggleSuppressError', false)

        .constant('toggleConfig', {
            /**
             * This object defines supported toggle widget attributes and their default values.
             * Angular's ngClick and ngDisabled are handled separately. Search code below.
             */
            /**
             * This version simulates checkbox functionality which can have either true or false value.
             * User-defined values are not supported.
             */
            'btnCheckboxFalse': false,
            'btnCheckboxTrue' : true,
            /**
             * Type: string/html
             * Default: "On"
             * Description: Text of the on toggle
             */
            on: 'On',
            /**
             * Type: string/html
             * Default: "Off"
             * Description: Text of the off toggle
             */
            off: 'Off',
            /**
             * Type: string
             * Default: ''
             * Description: Allows to specify one of the standarg bootstrap's button sizes (class).
             * Possible values are btn-lg, btn-sm, btn-xs.
             */
            size: '',
            /**
             * Type: string
             * Default: "btn-primary"
             * Description: Class for "on" state from one of standard bootstrap button types.
             * Possible values: btn-default, btn-primary, btn-success, btn-info, btn-warning, btn-danger
             */
            onstyle: 'btn-primary',
            /**
             * Type: string
             * Default: "btn-default"
             * Description: Class for "off" state from one of standard bootstrap button types.
             * Possible values: btn-default, btn-primary,btn- success, btn-info, btn-warning, btn-danger
             */
            offstyle: 'btn-default',
            /**
             * Type: JSON string
             * Default: ''
             * Description: Allows to pass user-defined style to the toggle's first immediate child (first DIV inside
             * <toggle ...> which is what you actually see as widget's outer container).
             * This can be used to alter widget's appearance. Use with caution! Note that "width" and "height" values
             * will be overwritten by either auto-calculated values or used-specified values from "width" and "height"
             * attributes.
             * Example: <toggle ... toggle-style="{'border': '1px dashed #f00'}">
             */
            toggleStyle: '',
            /**
             * Type: string
             * Default: ''
             * Description: Allows to force width and height to specified value. Use css notation such as 50px, 1%. etc.
             * This is useful when you have a group of toggles with different text in the lables and, therefore,
             * would never line-up to the same width.
             * Example: <toggle ... width="90px">
             */
            width : '',
            height: '',
            /**
             * Type: boolean
             * Default: false
             * Description: Defines "disabled" attribute for the <toggle> directive itself. The ng-disabled dirrective
             * manipulates this attribute, plus there is additional code that propagates its value to child elements.
             * Applying "disabled" to <toggle> itself apparently does nothing, but when its value is propagated to
             * two child <label> elements, it allows us to disable the widget.
             * Note that attribute "diasbled" is not the same as ng-disabled Angular directive. In most cases, you
             * should use <toggle ... ng-disabled="expression"> (not <toggle ... disabled="{{expression}}">) for this to
             * work properly.
             * [Per HTML specs, the "disabled" property does not need a value. Just mentioning it is enough.
             * Angular will, however, also add the value "disabled" (< ... disabled="disabled">)]
             */
            disabled: false,
        })

        .controller('ToggleController',
            ['$scope', '$attrs', '$interpolate', '$log', 'toggleConfig', '$toggleSuppressError', '$timeout',
                function ($scope, $attrs, $interpolate, $log, toggleConfig, $toggleSuppressError, $timeout) {
                    var self = this;
                    var labels, spans, divs;
                    var ngModelCtrl = {$setViewValue: angular.noop};
                    var toggleConfigKeys = Object.keys(toggleConfig);
                    var animationDisabled = true;

                    // Configuration attributes
                    angular.forEach( toggleConfigKeys, function (k, i) {
                        if (angular.isDefined($attrs[k])) {
                            /*
                            if (i < toggleConfigKeys.length) {
                                self[k] = $interpolate($attrs[k])($scope.$parent);
                            } else {
                                self[k] = $scope.$parent.$eval($attrs[k]);
                            }
                            */
                            switch ( typeof toggleConfig[k] ) {
                                case 'string':
                                    self[k] = $interpolate($attrs[k])($scope.$parent);
                                    break;
                                case 'function':
                                    // TBD
                                    break;
                                default:
                                    self[k] = $scope.$parent.$eval($attrs[k]);
                            }
                        } else {    // use default from toggleConfig
                            self[k] = toggleConfig[k];
                        }
                    });

                    this.init = function (ngModelCtrl_) {
                        ngModelCtrl = ngModelCtrl_;

                        labels = self.element.find('label');
                        spans  = self.element.find('span');
                        divs   = self.element.find('div');
                        // ^-- divs[0] is the DIV that has class="toggle btn"
                        //     divs[1] is a child of [0] and has class="toggle-group"

                        // Set wigget's visible text such as On/Off or Enable/Disable
                        angular.element(labels[0]).html(self.on);
                        angular.element(labels[1]).html(self.off);

                        self.computeStyle();

                        ngModelCtrl.$render = function () {
                            self.updateUI();

                            if (animationDisabled) {
                                // Allow angular to finish the current digest so it
                                // can render at least once with animation disabled
                                // then turn animation on
                                $timeout(function() {
                                    animationDisabled = false;
                                });
                            }
                        };

                        // ng-change (for optional onChange event handler)
                        if (angular.isDefined($attrs.ngChange)) {
                            ngModelCtrl.$viewChangeListeners.push(function () {
                                $scope.$eval($attrs.ngChange);
                            });
                        }
                    };

                    this.computeStyle = function () {
                        // Set wigget's disabled state.
                        // This action is unrelated to computing the style, but this function is the right place for it.
                        // The property must be propagated to lables and span inside the toggle-group container. This
                        // triggers .btn[disabled] style (cursor: not-allowed; opacity: 0.65;) but it does not prohibit
                        // the click event. Click event is handled in .onSwitch().
                        angular.element(labels[0]).attr('disabled', self.disabled);
                        angular.element(labels[1]).attr('disabled', self.disabled);
                        angular.element( spans[0]).attr('disabled', self.disabled);

                        // Build an object for widget's ng-style
                        $scope.wrapperStyle = (self.toggleStyle) ? $scope.$parent.$eval(self.toggleStyle) : {};

                        if (self.width) {
                            $scope.wrapperStyle.width = self.width;
                        } else {
                            // INCORRECT MATH - spans[0] overlaps two side-by-side LABEL's. Half of its width should
                            // not be included in the total.
                            //var wrapperComputedWidth =
                            //   Math.max(labels[0].offsetWidth, labels[1].offsetWidth) + (spans[0].offsetWidth / 2);
                            var wrapperComputedWidth = Math.max(labels[0].offsetWidth, labels[1].offsetWidth);
                            var wrapperWidth = divs[0].offsetWidth;

                            if (wrapperWidth < wrapperComputedWidth) {
                                $scope.wrapperStyle.width = wrapperComputedWidth + 'px';
                            } else {
                                $scope.wrapperStyle.width = wrapperWidth + 'px';
                            }
                        }

                        if (self.height) {
                            $scope.wrapperStyle.height = self.height;
                        } else {
                            var wrapperComputedHeight = Math.max(
                                labels[0].offsetHeight,
                                labels[1].offsetHeight);
                            var wrapperHeight = divs[1].offsetHeight;

                            var useComputedHeight =
                                wrapperHeight < wrapperComputedHeight &&
                                self.size !== 'btn-xs' && self.size !== 'btn-sm';

                            if (useComputedHeight) {
                                $scope.wrapperStyle.height = wrapperComputedHeight + 'px';
                            } else {
                                $scope.wrapperStyle.height = wrapperHeight + 'px';
                            }
                        }

                        // Build arrays that will be passed to widget's ng-class.
                        $scope.onClass     = [self.onstyle , self.size, 'toggle-on'];
                        $scope.offClass    = [self.offstyle, self.size, 'toggle-off'];
                        $scope.handleClass = [self.size , 'toggle-handle'];
                    };

                    this.updateUI = function () {
                        if (angular.isDefined(ngModelCtrl.$viewValue)) {
                            if (ngModelCtrl.$viewValue) {
                                $scope.wrapperClass = [self.onstyle, self.size, self.style];
                            } else {
                                $scope.wrapperClass = [self.offstyle, 'off ', self.size, self.style];
                            }
                        } else {
                            $scope.wrapperClass = [self.offstyle, 'off ', self.size, self.style];
                        }
                        if (animationDisabled) {
                            $scope.wrapperClass.push('animation-disabled');
                        }
                    };

                    $scope.onSwitch = function (evt) {
                       if (self.disabled) {    // prevent changing .$viewValue if .disabled == true
                            return false;
                       } else {
                           ngModelCtrl.$setViewValue(!ngModelCtrl.$viewValue);
                           ngModelCtrl.$render();
                       }
                       return true;
                    };

                    // Watchable data attributes
                    angular.forEach(['ngModel'], function (key) {
                        var watch = $scope.$parent.$watch($attrs[key], function (value) {
                            ngModelCtrl.$render();
                        });
                        $scope.$parent.$on('$destroy', function () {
                            watch();
                        });
                    });

                    angular.forEach( toggleConfigKeys, function (k, i) {
                        $attrs.$observe(k, function (v) {
                            if (self[k] !== v) {
                                self[k] = v;
                                self.computeStyle();
                            }
                        });
                    });
                }])

        .directive('toggle', function () {
                return {
                    restrict: 'E',
                    transclude: true,
                    template: '<div class="toggle btn" ng-class="wrapperClass" ' +
                              'ng-style="wrapperStyle" ng-click="onSwitch($event)">' +
                                '<div class="toggle-group">' +
                                  '<label class="btn" ng-class="onClass"></label>' +
                                  '<label class="btn active" ng-class="offClass"></label>' +
                                  '<span class="btn btn-default" ng-class="handleClass"></span>' +
                                '</div>' +
                              '</div>',
                    scope: {
                        ngModel: '='
                    },
                    require: ['toggle', 'ngModel'],
                    controller: 'ToggleController',
                    controllerAs: 'toggle',
                    compile: function (element, attrs, transclude) {
                        return {
                            pre: function (scope, element, attrs, ctrls) {
                                var toggleCtrl = ctrls[0], ngModelCtrl = ctrls[1];
                                toggleCtrl.element = element;
                                toggleCtrl.init(ngModelCtrl);
                            },
                            post: function () {}
                        };
                    }
                };
            }
        );
})();

angular
	.module('app', ['ui.toggle'])
	.controller('main', MainController);


              
            
!
999px

Console