Richard
Richard

Reputation: 65510

How do I switch views in Angular?

I am new to Angular, and have read all the tutorials, but am just starting out building my own app, so I am at the steep bit of the learning curve!

I am building a questionnaire. I would like to show one question at a time, along with occasional optional content on each screen (depending on the answers given to the questions).

My question is about the cleanest way to structure this in my controller.

Currently my HTML looks like this:

<div ng-show="showIntro"> <!-- Intro, shown by default -->
  Intro
  <button ng-click="nextIntro">Next</button>
</div>

<div ng-show="showQ1"> <!-- Question 1, shown after the user clicks Next -->
  Question 1

<label class="checkbox-inline"> <!-- Radio buttons for user response -->
  <input type="radio" name="ast-adh-p1-q1" ng-model="q1aVal" 
   ng-change='answerQ1(q1aVal)' value="yes"> Yes
</label>
<label class="checkbox-inline">
  <input type="radio" name="ast-adh-p1-q1" ng-model="value" 
  ng-change='answerQ1(value)' value="no"> No
</label>

 <div ng-show="showQ1extra"> <!-- Shown if user answers yes to question 1 -->
   some extra content if the user answers yes to question 1 here
 </div>

 <button ng-click="nextQ1">Next</button>

</div>

<div ng-show="showQ2"> <!-- Question 2, shown after completing question 1 -->
  Question 2 ...
</div>

And my controller looks like this:

    $scope.showIntro = true;
    $scope.showQ1 = false;
    $scope.showQ1extra = false;
    $scope.showQ2 = false;

    $scope.nextIntro = function() {
      $scope.showIntro = false;
      $scope.showQ1 = true;
    }

    $scope.answerQ1 = function(q1aVal) {
      $scope.showQ1extra = (q1aVal === 'yes') ? true : false;
    }

    $scope.nextQ1 = function() {
      $scope.showQ1 = false;
      $scope.showQ1extra = false;
      $scope.showQ2 = true;
    }

It works, but is inelegant and not scalable. Is there a more sensible, Angular way to do it?

My own feeling is that there should be a $scope.activeSection parameter, that is a number, and that is initially set to 0. Then showIntro should return $scope.activeSection === 0, etc, and there should be a single Next button that increments activeSection by 1 each time. Does that sound like an Angular-friendly way of doing things?

Update: Here is a plunker with sample code: http://plnkr.co/edit/Ursyhc7YJYbJS5OCGYEr?p=preview

Upvotes: 0

Views: 1675

Answers (1)

meriadec
meriadec

Reputation: 2983

You can resolve this with a quite small amount of code using the "ngSwitch" directive.

HTML:

<div ng-switch="step">
    <div ng-switch-when="1">
        <p>This is step 1</p>
        <button ng-click="setStep(2)" class="btn btn-success">Go to step 2</button>
    </div>
    <div ng-switch-when="2">
        <p>This is step 2</p>
        <button ng-click="setStep(3)" class="btn btn-success">Go to step 3</button>
    </div>
    <div ng-switch-when="3">
        <p>This is step 3</p>
        <button ng-click="setStep(1)" class="btn btn-success">Back to start</button>
    </div>
</div>

And in you controller :

$scope.step = 1;
$scope.setStep = function (num) {
    $scope.step = num;
};

You can check the result here : http://jsfiddle.net/Gg92r/

Upvotes: 1

Related Questions