1

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

2 Answers2

1

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"/>
Jared Reeves
  • 1,390
  • 2
  • 15
  • 29
  • Thank you Jared for your help on this unfortunately we tried your idea and it doesn't seem to work. We have attached our latest snippet. Would you be able to review just incase we're breaking your code. –  Oct 07 '14 at 14:49
  • Sorry I forgot to attach the updated HTML, does this now look correct ? –  Oct 07 '14 at 14:59
  • Even with both updates it now just displaying a blank black screen? –  Oct 07 '14 at 15:08
  • We now get the following error: SyntaxError: missing } after property list one: {color: 'red', isSelected: 'false'}, –  Oct 07 '14 at 15:11
  • Would it help if I upload it online and share the url ? –  Oct 07 '14 at 15:11
  • You are missing the , after a few of your name properties after name: 'Oil Empty' and name: 'Spark Plug' – Jared Reeves Oct 07 '14 at 15:28
  • after I fixed these then the page loads updated [Plnker](http://plnkr.co/edit/hABzQK?p=info) – Jared Reeves Oct 07 '14 at 15:34
  • I realised this when uploading it onto Plnkr, The page is loading fine but the data from the radio options are not been collected like previous radio button on the site. ??? –  Oct 07 '14 at 15:36
  • I've also noticed when trying to select e.g Amber for Fuel Empty and Oil Empty this doesn't seem to work either. –  Oct 07 '14 at 15:42
  • with the changes I suggested the binding is now working, and all you need to do is figure out how to add that data to the formData object. you might use an ngclick check if selected then add to object. – Jared Reeves Oct 07 '14 at 15:50
0

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

gearsdigital
  • 13,915
  • 6
  • 44
  • 73
Ahmed Hosny
  • 1,162
  • 10
  • 21
  • How would we go around binding the radio buttons within a different model? We are pretty much rookies with Angular JS at the moment. –  Oct 07 '14 at 14:56
  • I've edited the code in the link you have provided by adding a special model for each item. Then, bind this model in each iteration. so an item should be `{ id:'1', name: 'Fuel Empty', one: 'red', two: 'amber', three: 'green',model:'one'}` bind your html to the model `visualItem.model` – Ahmed Hosny Oct 07 '14 at 17:54
  • Are we adding this correctly ? as it looks like its gone three steps back and not forward. http://embed.plnkr.co/Dve2jQJ4tHN0y8AUKT2Z/preview –  Oct 08 '14 at 09:44
  • This link is not working in the preview, I do not know why!. Anyway, I'll upload the suggested solution and post the link here immediately. – Ahmed Hosny Oct 08 '14 at 13:12