Search code examples
angularjsangularjs-ng-repeatangular-ngmodelangularjs-ng-options

ng-options inside ng-repeat (with similar looking object) unexpected behavior, weird behavior


This is my first ever stackoverflow question therefore some help will be highly appreciated. I am working on an angular application where on one ui section, user is given a chance to multiple different choices which can be duplicate. e.g

A list of devices from the list. User can create multiple and they can even be all same types.

Working fiddle: http://jsfiddle.net/mrafaqi/dpLd85ep/5/

<table id="devices-table" class="table">
<tr ng-repeat="item in requiredDevices track by $index"  height="30">
    <td>
        <select 
            id="deviceList_{{$index}}"
            name="deviceList_name_{{$index}}"
            ng-model="item"
            ng-options="d.name for d in devices track by d.id"
            ng-change="deviceChanged($index, item)"
            >{{item}}
        </select>

        <div id="device-options" ng-show="item.id > -1">
            <label for="all_{{$index}}">1. Choose all</label><input     id="all_{{$index}}" type="radio" name="type_{{$index}}" value="1" ng-model="item.amountType" checked><br>
            <label for="some_{{$index}}">2. Choose some</label><input id="some_{{$index}}" type="radio" name="type_{{$index}}" value="2" ng-model="item.amountType" ><br>
            <label for="amount_{{$index}}">3. Choose amount</label><input id="amount_{{$index}}" type="radio" name="type_{{$index}}" value="3" ng-model="item.amountType" ><br>


      </div>
      <br>
  </td>
  </tr>

<tr id="add-device">
  <td>
  <br>
      <button id="add-device-button" ng-click="addDevice();">Add more</button>
      <button id="add-device-button" ng-click="showRequiredDevices();">Show required devices</button>
  </td>

  </tr>
</table>

The corresponding javascript for this code is

var new_test_controller = app.controller('new_test_controller', function($scope) {
$scope.init = function() {
    $scope.current_customer = $scope.customers[0].first_name;

    $scope.addDevice();
};

$scope.test1_text = "";

$scope.customers = 
                [
                 { "uid": 1, "first_name": "Rizwan", "last_name": "Zia" },
                 { "uid": 2, "first_name": "Laura", "last_name": "Zia" },
                 { "uid": 3, "first_name": "Sara", "last_name": "Zia" },
                ];

$scope.devices = [
                    {"id" : 1, "name": "scissors", "amount": 3, "amountType": -1},
                    {"id" : 2, "name": "jumppapallo", "amount": 3, "amountType": -1},
                    {"id" : 3, "name": "gymstick", "amount": 3, "amountType": -1},
                 ];

$scope.requiredDevices = [

                ];

$scope.addDevice = function() {
    var device = new Object();

    device.tid = $scope.requiredDevices.length;
    device.id = -1;
    device.name = "";
    device.amount = 0;
    device.amountType = -1;

    console.log(device);
    $scope.requiredDevices.push(device);
};

$scope.showRequiredDevices = function() {
    console.log($scope.requiredDevices);
};

$scope.deviceChanged = function($index, item) {
    console.log('Device changed at index: ' + $index);
    console.log(item);
    //$scope.requiredDevices[$index] = item;
};

//console.log('Controller must have been initialized');
$scope.init();
});

Now, the problem is that I can't choose same devices with different attributes. To generate this behavior

  1. Click add more button twice or more (create at least 2 devices)
  2. Choose gymstick in first and second combo box
  3. Choose any other device in third combo box
  4. Now if you try to click radio button for gymstick, it will update the value of the other item as well which I do not want. It seems to be some behavior of angular. I tried to use $index (t.id was try to hack it). Any help will be greatly appreciated :)

Solution

  • There is a conflict between two item variable

    1. item in ng-repeat.
    2. item model in select box

    you can change the select box model

    ex :

    <select 
    id="deviceList_{{$index}}"
    name="deviceList_name_{{$index}}"
    ng-model="item1"                         
    ....
    </select>
    

    and change ng-show to

    <div id="device-options" ng-show="item1.id > -1">
    

    here is the Demo Fiddle