1

I am trying to create dynamic rows based on button click. The rows have drop down boxes. The issue is when I add new row and select an option in the new row the options which I selected in previous rows are also changing, I mean the previous rows options are not binding properly.

My HTML code :

<div id="features" ng-controller="featuresCtrl">
    <br>
    <div class="row">
        <div class="form-group col-md-6">
            <table  cellpadding="15" cellspacing="10">
                <thead>
                <tr>
                    <th style="text-align: center;">Feature</th>
                    <th style="text-align: center;">Type</th>
                    <th style="text-align: center;">Value</th>
                    <th></th>
                    <th></th>
                </tr>
                </thead>
                <tbody>

                <tr></tr>
                <tr ng-repeat="r in rows">
                <td>
                    <select ng-model="r.data.model" ng-options="option.name for option in data.availableOptions"
                            ng-change="getValues(r.data.model.name)">
                        <option value="">Select Feature</option>
                    </select>

                    </td>
                    <td>
                        <select ng-model="r.updateData.model" ng-options="option.name for option in updateData.availableOptions"
                                ng-change="getBinSet(r.updateData.model.name)">
                            <option value="">Select Type</option>
                        </select>
                    </td>
                    <td>
                        <select ng-model="r.binData.model" ng-options="option.name for option in binData.availableOptions">
                            <option value="">Select Value</option>
                        </select>
                    </td>
                    <td  ng-if="showAdd">
                        <div class="text-center">
                            <button ng-click="addRow()">Add</button>
                        </div>
                    </td>
                    <td  ng-if="showAdd">
                        <div class="text-center">
                            <button ng-click="remove($index)">Remove</button>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td></td>
                    <td style="align-self: center;">
                        <button style="align-self: center" ng-click="submitForm(rows)">Submit</button>
                    </td>
                    <td></td>
                </tr>

                </tbody>
            </table>
            <br>
        </div>

My angular JS code :

'use strict';

var testControllers = angular.module('testControllers');

testControllers.controller('featuresCtrl', ['$scope','$route','$filter', '$http', '$location','$window','$timeout', 'NgTableParams',
    function($scope, $route, $filter, $http, $location, $window, $timeout, NgTableParams) {

        $scope.rows = [{}];
        $scope.nrows = [];
        $scope.showAdd = false;


        $scope.addRow = function() {
            $scope.rows.push({

            });

        };

        $scope.remove = function(index) {
                $scope.rows.splice(index, 1);
        };

        $scope.submitForm = function(rows) {
            console.log("rows", rows);
        };

        $scope.data = {
            model: null,
            availableOptions: [
                { name: 'TestA'},
                { name: 'TestB'},
                { name: 'TestC'},
                { name: 'TestD'}

            ]
        };

        $scope.getValues = function (featureType) {
            console.log("getValues", featureType);

            $scope.showAdd = false;


            if (featureType != null) {

                $http.get('/getPropensityValues.do', {params: {'featureType': featureType}}).success(function (data) {
                    var test = [];
                    angular.forEach(data, function (item) {
                        test.push({name: item});
                    });
                    $scope.updateData = {
                        model: null,
                        availableOptions : test
                    };
                });
            }
        };

        $scope.getBinSet = function (featureType) {
            console.log("getBinSet", featureType);

            $scope.showAdd = true;

            if (featureType != null) {
                $scope.binData = {
                    model: null,
                    availableOptions: [
                        {name: '1'},
                        {name: '2'},
                        {name: '3'},
                        {name: '4'},
                        {name: '5'},
                        {name: '6_10'},
                        {name: '10_15'},
                        {name: '16_20'},
                        {name: '21_25'},
                        {name: '26_30'},
                        {name: '31_35'},
                        {name: '36_40'},
                        {name: '41_45'},
                        {name: '46_50'},
                        {name: '>50'}
                    ]
                };

            }
        };

    }]);

Can some one tell me what I am doing wrong here ? I tried with another example - https://plnkr.co/edit/Jw5RkU3mLuGBpqKsq7RH?p=preview Even here I am facing same issue when selecting the 2nd row 1st row also changing. Is it wrong to use r.data.model to bind each row's values ?

1 Answer 1

1

I updated your plunker to work:

https://plnkr.co/edit/4sJHHaJPEuYiaHjdnFBp?p=preview

You weren't defining what the model was when you were redefining the options menus (side note: you should leverage underscore.js's difference function within a filter to create the appropriate display options dynamically)

Anyway, in your addRow() function, I changed it from this:

if(val=== 'TestB') {
   $scope.data1 = {
        model: null,
        availableOptions: [
            { name: 'TestA'},
            { name: 'TestC'},
            { name: 'TestD'}

        ]
    };
}

to this:

if(val=== 'TestB') {
   $scope.data1 = {
        model: 'TestB',
        availableOptions: [
            { name: 'TestA'},
            { name: 'TestC'},
            { name: 'TestD'}

        ]
    };
}

Let me know if this helps

UPDATE:

I recreated the functionality from scratch because I think you were overthinking things. All that is needed here is very simple ng-repeat, ng-options, and ng-model bindings.

<tr ng-repeat="r in rows track by $index">
     <td> 
        <select ng-model="r.name" 
               ng-options="option.name as option.name for option 
                                       in availableOptions">
            <option value="">Select Value</option>
        </select>
     </td>
     <td> 
         <input type="button" ng-click="addRow()" value="Add">
     </td>
     <td>
         <input type="button" ng-click="deleteRow($index)" 
             value="Delete">
    </td>
</tr>

and for the angular

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

  $scope.rows = [{name:""}];

  $scope.addRow = function(){
    $scope.rows.push({name:""});
  }

  $scope.availableOptions = [
                { name: 'TestA'},
                { name: 'TestB'},
                { name: 'TestC'},
                { name: 'TestD'}

            ];

  $scope.deleteRow = function(index){
    $scope.rows.splice(index,1);
    }
});

I didn't throw in the difference thing yet, but it should be easy.

Sign up to request clarification or add additional context in comments.

7 Comments

Its still not binding. when I select add and select options in new row, the first row also changes.
Can you let me know what I am doing wrong in my code ? I plunker was just 1 of my tries. The code which I am trying to get it to work is in the question
Alright I made a new plunkr that is much much much simpler than the original because I think you are really overthinking it. plnkr.co/edit/4sJHHaJPEuYiaHjdnFBp?p=preview
Thanks Chris. But the new plunker doesn't show any options in the select. My issue is with multiple drop downs where 1 drop down is based on the another drop down's value. since I am new to AngualJs this concept is very confusing to me. I thought using r.data.model supposed to create new model for each row. Is that wrong ?
@user3407267 sorry i was playing with it, the options show up now!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.