SirTophamHatt
SirTophamHatt

Reputation: 1581

Angular - Toggling element class inside an ng-repeat based on radio input selection

I'm using Angular to write a questionnaire where the questions are retrieved from a resource. Based on the design, I have to toggle a custom icon instead of the standard radio button icon. The solution I've come up with is to hide the radio input (using opacity/filter) and absolutely position a div over the input with the same dimensions as the radio input. Clicking the radio input will toggle a background image which is the custom icon. Unfortunately, this has to work in IE8 so conventional CSS :checked tactics are out.

The question blocks will look something like this:

    <h2>{{ quiz.questions[asked].questionText }}</h2>
    <ul>
        <li ng-repeat="answer in quiz.questions[asked].answers">
            <label>
                <input type="radio" ng-model="$parent.picked" name="answer" value="{{ answer.answerID }}"/>
                <div class="radio-mimic {{ checked }}"></div>
                {{ answer.answerText }}.
            </label>
        </li>
    </ul>
    <a class="btn" ng-click="submitAnswer()" ng-show="picked != null">
        Submit
    </a>

Here is a stripped down version of my controller for reference:

app.controller('QuizController', function($scope, Quiz) {
    $scope.quiz = Quiz.get({quizID = X}); // Angular $resource
    $scope.picked = null;
    $scope.asked = 0;
    $scope.answers = [];

    $scope.submitAnswer = function() {
        $scope.asked++;
        $scope.picked = null;

        // Push answer selected onto answers array
        // Check if # asked == number of questions in quiz to determine flow
        // If another question, $scope.quiz = Quiz.get({quizID = newQuizID});
        // Else show results    
    };
});

For each answer I receive to a question, I'm outputting the radio input and the div icon wrapped in a label with the answer text. Clicking on an answer will change the value of 'picked' in the parent scope of the repeat, thus only displaying the submit button when a user has picked an answer.

The problem I'm having is how to handle the logic of {{ checked }} for the div class to show when an input is selected. When I click on an input, the div within its scope needs to get a class called 'checked'. Additionally, if I click on a different answer outside that scope, the other scopes in the ng-repeat need to know in order to reset their 'checked' values to null or ''. I know some value will have to go into the parent scope like 'picked' but the overlap of the parent and ng-repeat scopes is causing me some confusion. I can do this easily enough with jQuery but wanted to keep this purely Angular as part of my learning.

Upvotes: 0

Views: 2079

Answers (1)

SirTophamHatt
SirTophamHatt

Reputation: 1581

I found a solution to my issue by using ng-class and an expression to compare the parent scope's 'picked' with the answerID of the inner scope:

<div class="radio-mimic" ng-class="{checked: $parent.picked == answer.answerID}"></div>

Upvotes: 0

Related Questions