<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@1.10.1" 
            data-semver="1.10.1" 
            src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <link data-require="bootstrap@3.0.0" 
          data-semver="3.0.0" rel="stylesheet" 
          href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
    <script data-require="bootstrap@3.0.0" 
            data-semver="3.0.0" 
            src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    <script src="jquery.bootstrap.wizard.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.0.8" 
            data-semver="1.0.8" 
            src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
    <script src="rcSubmit.js"></script>
    <script src="rcDisabled.js"></script>
    <script src="rcWizard.js"></script>
    <script src="sampleWizardController.js"></script>
    <script src="sampleWizardApp.js"></script>
  </head>

  <body ng-app="SampleWizardApp">
    <div class="container" >
      <div class="row">
        <div class="col-xs-12 col-sm-6 col-sm-offset-3">
          <h1>Simple Wizard</h1>
          <div ng-controller="SampleWizardController" 
               rc-wizard="sampleWizard" rc-disabled="rc.firstForm.submitInProgress">
            <ul class="nav rc-nav-wizard">
              <li class="active">
                <a class="active" href="#first" data-toggle="tab">
                  <span class="badge">1</span>
                  <span>First Step</span>
                </a>
              </li>
              <li>
                <a href="#second" data-toggle="tab">
                  <span class="badge">2</span>
                  <span>Second Step</span>
                </a>
              </li>
              <li>
                <a href="#last" data-toggle="tab">
                  <span class="badge">3</span>
                  <span>Last Step</span>
                </a>
              </li>
            </ul>
            <div class="tab-content">
              <form class="tab-pane active" id="first" name="firstForm" 
                    rc-submit="saveState()" rc-step novalidate>
                <h2>Enter first step data</h2>
                <div class="form-group"
                     ng-class="{'has-error': rc.firstForm.needsAttention(firstForm.firstName)}">
                  <label class="control-label">First Name</label>
                  <input name="firstName" class="form-control" type="text" required
                         ng-model="user.firstName"/>
                </div>
                <div class="form-group"
                     ng-class="{'has-error': rc.firstForm.needsAttention(firstForm.lastName)}">
                  <label class="control-label">Last Name</label>
                  <input name="lastName" class="form-control" type="text" required
                         ng-model="user.lastName" />
                </div>
              </form>
              <form class="tab-pane" id="second" name="secondForm" rc-submit rc-step>
                <h2>Enter second step data</h2>
                <div class="form-group">
                  <label class="control-label">Street Address</label>
                  <input name="streetAddress" class="form-control" type="text" 
                         ng-model="user.streetAddress" />
                </div>
                <div class="form-group">
                  <label class="control-label">City</label>
                  <input name="city" class="form-control" type="text" 
                         ng-model="user.city" />
                </div>
                <div class="form-group">
                  <label class="control-label">State</label>
                  <input name="state" class="form-control" type="text" 
                         ng-model="user.state" />
                </div>
                <div class="form-group">
                  <label class="control-label">City</label>
                  <input name="postalCode" class="form-control" type="text" 
                         ng-model="user.postalCode" />
                </div>
              </form>
              <form class="tab-pane" id="last" name="lastForm" rc-submit="completeWizard()" rc-step>
                <h2>Finish last step</h2>
                <div class="form-group">
                  <label class="control-label">First Name:</label>
                  <p class="form-control-static">{{ user.firstName }}</p>
                </div>
                <div class="form-group">
                  <label class="control-label">Last Name:</label>
                  <p class="form-control-static">{{ user.lastName }}</p>
                </div>
                <div class="form-group">
                  <label class="control-label">Address:</label>
                  <p class="form-control-static">
                    {{ user.streetAddress }}
                    <br />
                    {{ user.city }}, {{ user.state }} {{ user.postalCode }}
                  </p>
                </div>
              </form>
            </div>
            <div class="form-group">
              <div class="pull-right">
                <a class="btn btn-default" ng-click="rc.sampleWizard.backward()"
                   ng-show="rc.sampleWizard.currentIndex > rc.sampleWizard.firstIndex">Back</a>
                <a class="btn btn-primary" data-loading-text="Please Wait..." ng-click="rc.sampleWizard.forward()" 
                   ng-show="rc.sampleWizard.currentIndex < rc.sampleWizard.navigationLength">Continue</a>
                <a class="btn btn-primary" ng-click="rc.sampleWizard.forward()" 
                   ng-show="rc.sampleWizard.currentIndex == rc.sampleWizard.navigationLength">Complete</a>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>

</html>
/* Styles go here */
.rc-nav-wizard > li {
  float: left;
  font-size: 18px;
}

.rc-nav-wizard > li + li {
  margin-left: 2px;
}

.rc-nav-wizard > li > a {
  border-radius: 5px;
  cursor: default;
  color: #999;
}

.rc-nav-wizard > li > a,
.rc-nav-wizard > li > a:hover,
.rc-nav-wizard > li > a:focus {
  background-color: transparent;
}

.rc-nav-wizard > li > a > .badge {
  margin-left: 3px;
  font-size: 18px;
  padding: 5px 9px;
  border-radius: 15px;
}

/* active = current wizard step */
.rc-nav-wizard > li.active > a,
.rc-nav-wizard > li.active > a:hover,
.rc-nav-wizard > li.active > a:focus {
  color: #428bca;
  background-color: transparent;
}

.rc-nav-wizard > .active > a > .badge {
  color: #ffffff;
  background-color: #428bca;
}

/* success = completed wizard step */
.rc-nav-wizard > li.success > a,
.rc-nav-wizard > li.success > a:hover,
.rc-nav-wizard > li.success > a:focus {
  color: #D4AF37;
  background-color: transparent;
}

.rc-nav-wizard > .success > a > .badge {
  color: #ffffff;
  background-color: #D4AF37;
}

The is a live example of code found in the following article: 
http://code.realcrowd.com/the-wonderful-wizard-of-angularjs/
/*!
 * jQuery twitter bootstrap wizard plugin
 * Examples and documentation at: http://github.com/VinceG/twitter-bootstrap-wizard
 * version 1.0
 * Requires jQuery v1.3.2 or later
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * Authors: Vadim Vincent Gabriel (http://vadimg.com), Jason Gill (www.gilluminate.com)
 */
;(function($) {
var bootstrapWizardCreate = function(element, options) {
	var element = $(element);
	var obj = this;

	// Merge options with defaults
	var $settings = $.extend({}, $.fn.bootstrapWizard.defaults, options);
	var $activeTab = null;
	var $navigation = null;
	
	this.rebindClick = function(selector, fn)
	{
		selector.unbind('click', fn).bind('click', fn);
	}

	this.fixNavigationButtons = function() {
		// Get the current active tab
		if(!$activeTab.length) {
			// Select first one
			$navigation.find('a:first').tab('show');
			$activeTab = $navigation.find('li:first');
		}

		// See if we're currently in the first/last then disable the previous and last buttons
		$($settings.previousSelector, element).toggleClass('disabled', (obj.firstIndex() >= obj.currentIndex()));
		$($settings.nextSelector, element).toggleClass('disabled', (obj.currentIndex() >= obj.navigationLength()));

		// We are unbinding and rebinding to ensure single firing and no double-click errors
		obj.rebindClick($($settings.nextSelector, element), obj.next);
		obj.rebindClick($($settings.previousSelector, element), obj.previous);
		obj.rebindClick($($settings.lastSelector, element), obj.last);
		obj.rebindClick($($settings.firstSelector, element), obj.first);

		if($settings.onTabShow && typeof $settings.onTabShow === 'function' && $settings.onTabShow($activeTab, $navigation, obj.currentIndex())===false){
			return false;
		}
	};

	this.next = function(e) {

		// If we clicked the last then dont activate this
		if(element.hasClass('last')) {
			return false;
		}

		if($settings.onNext && typeof $settings.onNext === 'function' && $settings.onNext($activeTab, $navigation, obj.nextIndex())===false){
			return false;
		}

		// Did we click the last button
		$index = obj.nextIndex();
		if($index > obj.navigationLength()) {
		} else {
			$navigation.find('li:eq('+$index+') a').tab('show');
		}
	};

	this.previous = function(e) {

		// If we clicked the first then dont activate this
		if(element.hasClass('first')) {
			return false;
		}

		if($settings.onPrevious && typeof $settings.onPrevious === 'function' && $settings.onPrevious($activeTab, $navigation, obj.previousIndex())===false){
			return false;
		}

		$index = obj.previousIndex();
		if($index < 0) {
		} else {
			$navigation.find('li:eq('+$index+') a').tab('show');
		}
	};

	this.first = function(e) {
		if($settings.onFirst && typeof $settings.onFirst === 'function' && $settings.onFirst($activeTab, $navigation, obj.firstIndex())===false){
			return false;
		}

		// If the element is disabled then we won't do anything
		if(element.hasClass('disabled')) {
			return false;
		}
		$navigation.find('li:eq(0) a').tab('show');

	};
	this.last = function(e) {
		if($settings.onLast && typeof $settings.onLast === 'function' && $settings.onLast($activeTab, $navigation, obj.lastIndex())===false){
			return false;
		}

		// If the element is disabled then we won't do anything
		if(element.hasClass('disabled')) {
			return false;
		}
		$navigation.find('li:eq('+obj.navigationLength()+') a').tab('show');
	};
	this.currentIndex = function() {
		return $navigation.find('li').index($activeTab);
	};
	this.firstIndex = function() {
		return 0;
	};
	this.lastIndex = function() {
		return obj.navigationLength();
	};
	this.getIndex = function(e) {
		return $navigation.find('li').index(e);
	};
	this.nextIndex = function() {
		return $navigation.find('li').index($activeTab) + 1;
	};
	this.previousIndex = function() {
		return $navigation.find('li').index($activeTab) - 1;
	};
	this.navigationLength = function() {
		return $navigation.find('li').length - 1;
	};
	this.activeTab = function() {
		return $activeTab;
	};
	this.nextTab = function() {
		return $navigation.find('li:eq('+(obj.currentIndex()+1)+')').length ? $navigation.find('li:eq('+(obj.currentIndex()+1)+')') : null;
	};
	this.previousTab = function() {
		if(obj.currentIndex() <= 0) {
			return null;
		}
		return $navigation.find('li:eq('+parseInt(obj.currentIndex()-1)+')');
	};
	this.show = function(index) {
		return element.find('li:eq(' + index + ') a').tab('show');
	};
	this.disable = function(index) {
		$navigation.find('li:eq('+index+')').addClass('disabled');
	};
	this.enable = function(index) {
		$navigation.find('li:eq('+index+')').removeClass('disabled');
	};
	this.hide = function(index) {
		$navigation.find('li:eq('+index+')').hide();
	};
	this.display = function(index) {
		$navigation.find('li:eq('+index+')').show();
	};
	this.remove = function(args) {
		var $index = args[0];
		var $removeTabPane = typeof args[1] != 'undefined' ? args[1] : false;
		var $item = $navigation.find('li:eq('+$index+')');

		// Remove the tab pane first if needed
		if($removeTabPane) {
			var $href = $item.find('a').attr('href');
			$($href).remove();
		}

		// Remove menu item
		$item.remove();
	};

	$navigation = element.find('ul:first', element);
	$activeTab = $navigation.find('li.active', element);

	if(!$navigation.hasClass($settings.tabClass)) {
		$navigation.addClass($settings.tabClass);
	}

	// Load onInit
	if($settings.onInit && typeof $settings.onInit === 'function'){
		$settings.onInit($activeTab, $navigation, 0);
	}

	// Load onShow
	if($settings.onShow && typeof $settings.onShow === 'function'){
		$settings.onShow($activeTab, $navigation, obj.nextIndex());
	}

	// Work the next/previous buttons
	obj.fixNavigationButtons();

	$('a[data-toggle="tab"]', $navigation).on('click', function (e) {
		// Get the index of the clicked tab
		var clickedIndex = $navigation.find('li').index($(e.currentTarget).parent('li'));
		if($settings.onTabClick && typeof $settings.onTabClick === 'function' && $settings.onTabClick($activeTab, $navigation, obj.currentIndex(), clickedIndex)===false){
			return false;
		}
	});

	$('a[data-toggle="tab"]', $navigation).on('shown shown.bs.tab', function (e) {  // use shown instead of show to help prevent double firing
		$element = $(e.target).parent();
		var nextTab = $navigation.find('li').index($element);

		// If it's disabled then do not change
		if($element.hasClass('disabled')) {
			return false;
		}

		if($settings.onTabChange && typeof $settings.onTabChange === 'function' && $settings.onTabChange($activeTab, $navigation, obj.currentIndex(), nextTab)===false){
				return false;
		}

		$activeTab = $element; // activated tab
		obj.fixNavigationButtons();
	});
};
$.fn.bootstrapWizard = function(options) {
	//expose methods
	if (typeof options == 'string') {
		var args = Array.prototype.slice.call(arguments, 1)
		if(args.length === 1) {
			args.toString();
		}
		return this.data('bootstrapWizard')[options](args);
	}
	return this.each(function(index){
		var element = $(this);
		// Return early if this element already has a plugin instance
		if (element.data('bootstrapWizard')) return;
		// pass options to plugin constructor
		var wizard = new bootstrapWizardCreate(element, options);
		// Store plugin object in this element's data
		element.data('bootstrapWizard', wizard);
	});
};

// expose options
$.fn.bootstrapWizard.defaults = {
	tabClass:         'nav nav-pills',
	nextSelector:     '.wizard li.next',
	previousSelector: '.wizard li.previous',
	firstSelector:    '.wizard li.first',
	lastSelector:     '.wizard li.last',
	onShow:           null,
	onInit:           null,
	onNext:           null,
	onPrevious:       null,
	onLast:           null,
	onFirst:          null,
	onTabChange:      null, 
	onTabClick:       null,
	onTabShow:        null
};

})(jQuery);
var rcWizardDirective = {
  'rcWizard': function () {
    return {
      restrict: 'A',
      controller: ['$scope', function ($scope) {
        
        var self;
        var wizardElement;
        var wizardOptions = {};
        var steps = [];
        
        this.currentIndex = 0;
        this.firstIndex = 0;
        this.navigationLength = 0;
        
        this.addStep = function (step) {
          
          steps.push(step);
          
          if (!step.element || !step.submitController) return;
          
          // if a rcSubmitController is being used, automatically add a _hidden_ 
          // submit button so that 
          
          // in order to place an submit button that is still functional it 
          // has to technically be visible, so instead we place it way off 
          // screen
          jQuery(step.element)
            .append('<input type="submit" tabindex="-1" style="position: absolute; left: -9999px; width: 1px; height: 1px;" />')
            .attr('action', 'javascript:void(0);');
          
          // bind to the submit complete event on the rcSubmitController and 
          // if the action was successful, trigger a next on the wizard.
          step.submitController.onSubmitComplete(function (evt) {
            if (evt.success) {
              onForward(step);
            }
          });
        };
          
        this.forward = function () {
          
          if (steps.length)
          
          var currentStep = (steps.length > self.currentIndex) ? steps[self.currentIndex] : null;
          
          if (0 < steps.length && !currentStep) return;
          
          if (0 < steps.length && currentStep.submitController) {
            currentStep.submitController.submit();
          } else {
            onForward(currentStep);
          }
        };
        
        var onForward = function(currentStep) {
          
          if (0 < steps.length && 
            currentStep.formController && 
            currentStep.formController.$invalid) return;
          
          wizardElement.bootstrapWizard('next');
        };
        
        this.backward = function () {
          wizardElement.bootstrapWizard('previous');
        };
        
        var onTabChange = function (activeTab, navigation, currentIndex, nextTab) {
          
          self.currentIndex = nextTab;
          self.firstIndex = wizardElement.bootstrapWizard('firstIndex');
          self.navigationLength = wizardElement.bootstrapWizard('navigationLength');
          
          if (!$scope.$$phase) $scope.$apply();
        };
        
        var onTabClick = function (activeTab, navigation, currentIndex, clickedIndex) {
            return false;
        };
        
        var onTabShow = function (activeTab, navigation, currentIndex) {
          
          if (currentIndex > 0) {
            wizardElement
              .find('.nav li:gt(' + (currentIndex - 1) + ')')
              .removeClass("success");
            wizardElement.find('.nav li:lt(' + currentIndex + ')')
              .addClass("success");
          } else {
            wizardElement.find('.nav li').removeClass("success");
          }
          
          // if a rcStep is being used on the current tab, 
          // automatically focus on the first input of the current tab. This
          // allows for easier keyboard-ony navigation.
          if (steps.length > currentIndex && steps[currentIndex].element) {
            steps[currentIndex].element.find('input').first().focus();
          }
        };
        
        var updateWizard = function (options) {
          
          wizardOptions = options;
          
          if (wizardElement) {
            wizardElement.bootstrapWizard(options);
            self.currentIndex = wizardElement.bootstrapWizard('currentIndex');
            self.firstIndex = wizardElement.bootstrapWizard('firstIndex');
            self.navigationLength = wizardElement.bootstrapWizard('navigationLength');
            
            if (!$scope.$$phase) $scope.$apply();
          }
        };
        
        this.setWizardElement = function (element) {
          
          wizardElement = element;
          self = this;
          updateWizard({
            'onTabChange': onTabChange,
            'onTabShow': onTabShow,
            'onTabClick': onTabClick
          });
        };
      }],
      compile: function (cElement, cAttributes, transclude) {
        return {
          pre: function (scope, formElement, attributes, wizardController) {
            // put a reference to the wizardcontroller on the scope so we can 
            // use some of the properties in the markup
            scope.rc = scope.rc || {};
            scope.rc[attributes.rcWizard] = wizardController;
          },
          post: function (scope, element, attributes, wizardController) {
            // let the controller know about the element
            wizardController.setWizardElement(element);
            if (!scope.$$phase) scope.$apply();
          }
        };
      }
    }
  }
};

var rcWizardStepDirective = {
  'rcStep': function () {
    return {
      restrict: 'A',
      require: ['^rcWizard', '?form', '?rcSubmit'],
      link: function (scope, element, attributes, controllers) {
        
        var wizardController = controllers[0];
        
        // find all the optional controllers for the step
        var formController = controllers.length > 1 ? controllers[1] : null;
        var submitController = controllers.length > 2 ? controllers[2] : null;
        
        // add the step to the wizard controller
        var step = wizardController.addStep({ 
          'element': element, 
          'attributes': attributes, 
          'formController': formController,
          'submitController': submitController });
      }
    };
  }
};

angular.module('rcWizard', ['ng'])

.directive(rcWizardDirective)
.directive(rcWizardStepDirective);
var rcSubmitDirective = {
  'rcSubmit': ['$parse', '$q', '$timeout', function ($parse, $q, $timeout) {
    return {
      restrict: 'A',
      require: ['rcSubmit', '?form'],
      controller: ['$scope', function ($scope) {
        
        var formElement = null;
        
        var formController = null;
        var submitCompleteHandlers = [];
        
        this.attempted = false;
        this.submitInProgress = false;
        
        this.setFormElement = function(element) {
          formElement = element;
        }
        
        this.submit = function() {
          if (!formElement) return;
          
          jQuery(formElement).submit();
        }
        
        this.setAttempted = function() {
          this.attempted = true;
        };
        
        this.setFormController = function(controller) {
          
          formController = controller;
        };
        
        this.needsAttention = function (fieldModelController) {
          if (!formController) return false;
          
          if (fieldModelController) {
            return fieldModelController.$invalid && (fieldModelController.$dirty || this.attempted);
          } else {
            return formController && formController.$invalid && (formController.$dirty || this.attempted);
          }
        };
        
        this.onSubmitComplete = function (handler) {
          
          submitCompleteHandlers.push(handler);
        };
        
        this.setSubmitComplete = function (success, data) {
          
          angular.forEach(submitCompleteHandlers, function (handler) {
            handler({ 'success': success, 'data': data });
          });
        };
      }],
      compile: function(cElement, cAttributes, transclude) {
        return {
          pre: function(scope, formElement, attributes, controllers) {
            
            var submitController = controllers[0];
            var formController = (controllers.length > 1) ? controllers[1] : null;
            
            submitController.setFormElement(formElement);
            submitController.setFormController(formController);
            
            scope.rc = scope.rc || {};
            scope.rc[attributes.name] = submitController;
          },
          post: function(scope, formElement, attributes, controllers) {
            
            var submitController = controllers[0];
            var formController = (controllers.length > 1) ? controllers[1] : null;
            var fn = $parse(attributes.rcSubmit);
            
            formElement.bind('submit', function () {
              submitController.setAttempted();
              if (!scope.$$phase) scope.$apply();
              
              if (!formController.$valid) return false;
              
              var doSubmit = function () {
                
                submitController.submitInProgress = true;
                if (!scope.$$phase) scope.$apply();
                
                var returnPromise = $q.when(fn(scope, { $event: event }));
                
                returnPromise.then(function (result) {
                  submitController.submitInProgress = false;
                  if (!scope.$$phase) scope.$apply();
                  $timeout(function() {
                    submitController.setSubmitComplete(true, result);
                  });
                  
                }, function (error) {
                  submitController.submitInProgress = false;
                  if (!scope.$$phase) scope.$apply();
                  submitController.setSubmitComplete(false, error);
                });
              };
              
              if (!scope.$$phase) {
                scope.$apply(doSubmit);
              } else {
                doSubmit();
                if (!scope.$$phase) scope.$apply();
              }
            });
          }
        };
      }
    };
  }]
};
var rcDisabledDirective = {
  'rcDisabled': ['rcDisabled', function (rcDisabled) {
    return {
      restrict: 'A',
      link: function (scope, element, attributes) {
        
        scope.$watch(attributes.rcDisabled, function(isDisabled) {
          rcDisabled.disable(element, isDisabled);
        });
      }
    }
  }]
};

var rcDisabledProvider = function () {
    
  var defaultDisableHandler = function(rootElement, isDisabled) {
    var jElement = jQuery(rootElement);
    
    return jElement
            .find(':not([rc-disabled])')
            .filter(function(index) {
              return jQuery(this).parents().not(jElement).filter('[rc-disabled]').length === 0;
            })
            .filter('input:not([ng-disabled]), button:not([ng-disabled])')
            .prop('disabled', isDisabled);
  };
  
  var customDisableHandler;
  
  this.onDisable = function (customHandler) {
    customDisableHandler = customHandler;
  };
  
  this.$get = function () {
    return {
      disable: function (rootElement, isDisabled) {
        return (customDisableHandler) ? customDisableHandler(rootElement, isDisabled) : defaultDisableHandler(rootElement, isDisabled);
      }
    }
  };
};

angular.module('rcDisabled', [])
.provider('rcDisabled', rcDisabledProvider)
.directive(rcDisabledDirective);

angular.module('rcDisabledBootstrap', ['rcDisabled'])
.provider('rcDisabled', rcDisabledProvider)
.directive(rcDisabledDirective)
.config(['rcDisabledProvider', function(rcDisabledProvider) {
  rcDisabledProvider.onDisable(function(rootElement, isDisabled) {
    var jqElement = jQuery(rootElement);
      
    jqElement = jqElement
                  .find(':not([rc-disabled])')
                  .filter(function(index) {
                    return jQuery(this).parents().not(jqElement).filter('[rc-disabled]').length === 0;
                  })
                  .filter('input:not([ng-disabled]), button:not([ng-disabled]), .btn, li')
                  .add(jqElement);
            
    // if the Bootstrap "Button" jQuery plug-in is loaded, use it on those
    // that have it configured
    if (jqElement.button) {
      jqElement.find('[data-loading-text]').button((isDisabled) ? 'loading' : 'reset');
    }
            
    jqElement.toggleClass('disabled', isDisabled)
    .filter('input, button')
    .prop('disabled', isDisabled);
  });
}]);
angular.module('rcForm', [])
.directive(rcSubmitDirective);

// define module for app
angular.module('SampleWizardApp', ['rcWizard', 'rcForm', 'rcDisabledBootstrap']);
// define controller for wizard
var SampleWizardController = ['$scope', '$q', '$timeout',
function ($scope, $q, $timeout) {
  
  $scope.user = {};
  
  $scope.saveState = function() {
    var deferred = $q.defer();
    
    $timeout(function() {
      deferred.resolve();
    }, 5000);
    
    return deferred.promise;
  };
  
  $scope.completeWizard = function() {
    alert('Completed!');
  }
}];