# Sign-up wizard structure seems too repetitive

I think my current structure is way too repetitive. I feel like I must be missing something that would easily make this sign up wizard work far better.

  <ol class="registerMeter">
<li class="progress-point" ng-click="wiz('step1')"     ng-class="{active: step1.active, done: step1.done, todo: step1.todo}">Step 1</li>
<li class="progress-point" ng-click="wiz('step2')"     ng-class="{active: step2.active, done: step2.done, todo: step2.todo}">Step 2</li>
<li class="progress-point" ng-click="wiz('step3')"     ng-class="{active: step3.active, done: step3.done, todo: step3.todo}">Step 3</li>
</ol>
<section class="row formMain" ng-switch="step">
<section class="row" ng-switch-default>
<form ng-submit="registerSubmit()">
</form>
</section>
<section ng-switch-when="step2">
<form>

</form>
</section>
<section ng-switch-when="step3">
<form>

</form>
</section>
</section>

app.controller('registerCtrl', function($scope,$http, $location, FlashService){$scope.step1 = {active: true, done:false, todo: false};
$scope.step2 = {active: false, done:false, todo: true};$scope.step3 = {active: false, done:false, todo: true};

$scope.wiz = function(step){$scope.step = step;
switch (step) {
case 'step1':
$scope.step1 = {active: true, done:false, todo: false};$scope.step2.active = false;
$scope.step3.active = false;$scope.step2.todo = true;
$scope.step3.todo = true; break; case 'step2':$scope.step1.active = false;
$scope.step1.todo = true;$scope.step2 = {active: true, done:false, todo: false};
$scope.step3.active = false;$scope.step3.active = false;
break;
case 'step3':
$scope.step1.active = false;$scope.step2.active = false;
$scope.step1.todo = true;$scope.step2.todo = true;
$scope.step3 = {active: true, done:false, todo: false}; break default:$scope.step1 = {active: true, done:false, todo: false};
$scope.step2 = {active: false, done:false, todo: true};$scope.step3 = {active: false, done:false, todo: true};
}
}

$scope.registerSubmit = function(){$http.post()
$scope.step = 'step2';$scope.step1 = {active: false, done:true , todo:false}
$scope.step2.active = true; if (data.msg !='') {$scope.msgs.push(data.msg);
} else {
$scope.errors.push(data.error); } }).error(function(data, status){ FlashService.show(response.flash);$scope.errors.push(status);
})
};
});


I'm worried that the switch and ngclass statements are way more than I need. Is there a simpler way to accomplish this? This just doesn't feel DRY at all.

• You have a lot of booleans Are they all required? Could you instead check if values the user enters in the wizard exist (not null) instead of three boolean states? – Sukima Feb 6 '14 at 1:29
• @Sukima That's interesting. I could check if the object from the form is user interacted yet. That would only work one way though and wouldn't allow a user to go back a step. It's a long sign up form. – Patrick Cauley Feb 6 '14 at 3:28
• In that case I think it would be better to wrap your boolean logic into a finite state machine object which manages the state the user is in. A little abstraction can help with readability. – Sukima Feb 6 '14 at 14:08

You can make this DRYer if you can assume that :

• You keep naming each step stepx
• No other variables in $scope start with step In that case you could use a function that sets in a first step the right scope active and then the other steps inactive: function updateScopeSteps($scope , step )
{
//Default to step1
step = step || 'step1';
//Set step
$scope.step = step; //Activate step$scope[ step ] = {active: true, done:false, todo: false};
//De-activate all other steps
for( var name in $scope ){ if( name.substring(0,4) == 'step' && name != step ){$scope[name].active = false;
\$scope[name].todo = true;
}
}
}