user3999667
user3999667

Reputation:

AngularJS multiple radio options

Good afternoon,

We are currently trying to learn AngularJS and although we're picking up some pretty cool codes we can't seem to figure this issue out.

We are wanting to display a list of product options relative to the selected product within the dropdown feature from here we want to be able to tick one radio button on each row but at the moment when we tick one of the radio buttons it seems to be selecting all within each of the columns.

We've attached our code snippets and screenshots, if anyone could help us we'd greatly appreciate it.

Thank you. Original Plnkr http://embed.plnkr.co/bpMoLNnf4zs5VK4kx1JJ/preview

Original HTML

 <div class="form-group">
    <h3>Product</h3>
</div>

<div class="form-group">
    <div>
        <select ng-model="formData.product" ng-options="product.name for product in products" style="color:#000;"></select>
    </div>

    <div ng-show="formData.product.name=='Petrol Lawnmower'">
        <div ng-repeat="visualItem in visualItems">
            <label for="">{{visualItem.name}}</label>
            <input type="radio" name="{{visualItem.id}}" ng-model="formData.visualItems.one" ng-value="visualItem.one"/>
            <input type="radio" name="{{visualItem.id}}" ng-model="formData.visualItems.two" ng-value="visualItem.two"/>
            <input type="radio" name="{{visualItem.id}}" ng-model="formData.visualItems.three" ng-value="visualItem.three"/>
        </div>
    </div>
</div>

<div class="form-group row">
<div class="col-xs-6 col-xs-offset-3">
    <a ui-sref="{{formData.product.url}}" class="btn btn-block btn-info">
        Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
    </a>
    <a ui-sref="form.usage" class="btn btn-block btn-info">
        <span class="glyphicon glyphicon-circle-arrow-left"></span> Previous Section
    </a>
    <br/>
</div>
</div>

Original JS

 // Products
    $scope.products = [
        {id: '1', name: 'Petrol Lawnmower' },
        {id: '2', name: 'Electric Lawnmower'},
        {id: '3', name: 'Petrol Chainsaw'},
        {id: '4', name: 'Electric Chainsaw'},
        {id: '5', name: 'Petrol Timmer'},
        {id: '6', name: 'Electric Timmer'},
        {id: '7', name: 'Etc'}
    ];
    $scope.product = {
        productItems: [{
            Product: $scope.products[0]
        }]
    }
    // Visual Test
    $scope.visualItems = [
        { id:'1', name: 'Fuel Empty', one: 'red', two: 'amber', three: 'green'},
        { id:'2', name: 'Oil Empty', one: 'red', two: 'amber', three: 'green'},
        { id:'3', name: 'Spark Plug', one: 'red', two: 'amber', three: 'green'},
        { id:'4', name: 'Air Filter', one: 'red', two: 'amber', three: 'green'},
        { id:'5', name: 'Blade', one: 'red', two: 'amber', three: 'green'},
        { id:'6', name: 'Pull Start', one: 'red', two: 'amber', three: 'green'},
        { id:'7', name: 'Deck', one: 'red', two: 'amber', three: 'green'},
        { id:'8', name: 'Wheels', one: 'red', two: 'amber', three: 'green'},
        { id:'9', name: 'Handles', one: 'red', two: 'amber', three: 'green'},
        { id:'10', name: 'Throttle/Pull Cable', one: 'red', two: 'amber', three: 'green'},
        { id:'11', name: 'Primer Bulb', one: 'red', two: 'amber', three: 'green'},
        { id:'12', name: 'Grass Box', one: 'red', two: 'amber', three: 'green'},
        { id:'13', name: 'Fuel Pipe', one: 'red', two: 'amber', three: 'green'}
    ];
    $scope.visualItem = {
        visual: [{
            VisualItem: $scope.visualItems[0]
        }]
    }

enter image description here enter image description here enter image description here

Updated HTML

<div class="form-group">
    <h3>Product</h3>
</div>

<div class="form-group">
    <div>
        <select ng-model="formData.product" ng-options="product.name for product in products" style="color:#000;"></select>
    </div>

    <div ng-show="formData.product.name=='Petrol Lawnmower'">
        <div ng-repeat="visualItem in visualItems">
            <label for="">{{visualItem.name}}</label>
            <input type="radio" name="{{visualItem.id}}" ng-model="visualItem.one.isSelected" ng-value="visualItem.one"/>
            <input type="radio" name="{{visualItem.id}}" ng-model="visualItem.one.isSelected" ng-value="visualItem.one"/>
            <input type="radio" name="{{visualItem.id}}" ng-model="visualItem.one.isSelected" ng-value="visualItem.one"/>
        </div>
    </div>
</div>

<div class="form-group row">
<div class="col-xs-6 col-xs-offset-3">
    <a ui-sref="{{formData.product.url}}" class="btn btn-block btn-info">
        Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
    </a>
    <a ui-sref="form.usage" class="btn btn-block btn-info">
        <span class="glyphicon glyphicon-circle-arrow-left"></span> Previous Section
    </a>
    <br/>
</div>
</div>

Updated JS

angular.module('formApp', ['ngAnimate', 'ui.router'])

.config(function($stateProvider, $urlRouterProvider) { 
    $stateProvider
        .state('form', {
            url: '/form',
            templateUrl: 'form.html',
            controller: 'formController'
        })

        .state('form.packaging', {
            url: '/packaging',
            templateUrl: 'form-packaging.html'
        })
        .state('form.usage', {
            url: '/usage',
            templateUrl: 'form-usage.html'
        })
        .state('form.product', {
            url: '/product',
            templateUrl: 'form-product.html'
        })   
        .state('form.payment', {
            url: '/payment',
            templateUrl: 'form-payment.html'
        });
    $urlRouterProvider.otherwise('/form/packaging');
})

.controller('formController', function($scope) {

    // Products
    $scope.products = [
        {id: '1', name: 'Petrol Lawnmower' },
        {id: '2', name: 'Electric Lawnmower'},
        {id: '3', name: 'Petrol Chainsaw'},
        {id: '4', name: 'Electric Chainsaw'},
        {id: '5', name: 'Petrol Timmer'},
        {id: '6', name: 'Electric Timmer'},
        {id: '7', name: 'Etc'}
    ];
    $scope.product = {
        productItems: [{
            Product: $scope.products[0]
        }]
    }
    // Visual 
    $scope.visualItems = [
        { 
            id:'1', 
            name: 'Fuel Empty', 
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'2', 
            name: 'Oil Empty'
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'3', 
            name: 'Spark Plug'
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'4', 
            name: 'Air Filter',
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'5', 
            name: 'Blade',
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'6', 
            name: 'Pull Start', 
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'7', 
            name: 'Deck', 
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'8', 
            name: 'Wheels',
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'9', 
            name: 'Handles',
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'10', 
            name: 'Throttle/Pull Cable',
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'11', 
            name: 'Primer Bulb', 
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'12', 
            name: 'Grass Box', 
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        },
        { 
            id:'13', 
            name: 'Fuel Pipe', 
            one: {color: 'red', isSelected: 'false'},
            two: {color: 'amber', isSelected: 'false'},
            three: {color: 'green', isSelected: 'false'}
        }
    ];
    $scope.visualItem = {
        visual: [{
            VisualItem: $scope.visualItems[0]
        }]
    }



    // we will store all of our form data in this object
    $scope.formData = {};
    // function to process the form
    $scope.processForm = function() {
        alert('awesome!');  
    };

});

enter image description here

Updated Plnkr http://plnkr.co/edit/Dve2jQJ4tHN0y8AUKT2Z

Upvotes: 1

Views: 4887

Answers (2)

Jared Reeves
Jared Reeves

Reputation: 1390

After looking at your code, your issue is that you are binding the radio buttons to the same object in each repeat cycle.

Lets take a look at what is currently happening, First you have an ng-repeat that is repeating a section of html from the $scope.visualItems, which is working as expected. However, if you look at the ng-model you are using to bind the selection of the radio button too:

 <input type="radio" name="{{visualItem.id}}" 
        ng-model="formData.visualItems.one"
        ng-value="visualItem.one"/>

In each repeat the the ng-model is being bound to the same value, thus every other section in the repeat will change when one you select one radio button, which is the way the two way binding should work.

To fix this issue you need to bind each radio button to a unique model, I suggest creating an in selected property in the list that is repeated so that each radio button can bind to its own unique value.

One thing that you could do, and not knowing the full process in your code, would be to bind the radio buttons to one - two - thee and change those values Boolean. You could do this if you know that for each one there is a corresponding color and might need to be stored in the list. This is only a suggestion.

You could also restructure your object so each one - two - three is an object with an isSelected property and a color value.

one: {color:'red', isSelected: false}

And then in you ngrepeat you could do this:

input type="radio" name="{{visualItem.id}}" 
      ng-model="visualItem.one.isSelected"
      ng-value="visualItem.one"/>

Upvotes: 1

Ahmed Hosny
Ahmed Hosny

Reputation: 1172

I think the problem resides in binding your radio buttons to the same ng-model.

First suggestion: is to bind the radio buttons to different models

ng-model="visualItem.three"

for each group. At first all items will be selected, then it will change as normal. Such:

<div ng-show="product.name=='Petrol Lawnmower'">
    <div ng-repeat="visualItem in visualItems">
        <label for="">{{visualItem.name}}</label>
        <input type="radio" ng-value="visualItem.one" name="{{visualItem.id}}" ng-model="visualItem.one" />
        <input type="radio" ng-value="visualItem.two" name="{{visualItem.id}}" ng-model="visualItem.two" />
        <input type="radio" ng-value="visualItem.three" name="{{visualItem.id}}" ng-model="visualItem.three" />
    </div>
</div>

Second suggestion: is to remove ng-model and get the data using regular javascript function

Third suggestion: is to use ng-change to write an expression when selecting an option

Upvotes: 0

Related Questions