3

I am adding inputs dynamically by pressing an add button

here is a JSBin example so you can check my issue.

Everytime I press the button I mentioned, a new input should comes up, as you can see I have in the same view 2 forms/boxes there generated by a ng-repeat with separate inputs and a separate add more button, the issue is that when I play that button, 2 new inputs comes up in the 2 different forms I have, that shouldn't be happening, the new input must be add it only in the current form.

    <div>
        <div ng-repeat="op in operation track by $index">
            <p>{{op.title}} | {{op.duration}} | {{op.status}}</p>
            <input ng-model="operation.detailText" type="text"></input>
            <div>
                <div ng-repeat="operation in operations track by $index">

                    <input ng-model="operation.detailText" type="text"></input>

                </div>
                <button ng-click="operations.push({})">Add one more</button>
            </div>
        </div>
    </div>

JS:

angular.module('ionicApp',[])

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

    $scope.operations = [];

    $scope.operation = [];

    $scope.operation = [{
                    title    : 'Operación 170794',
                    duration : '3600',
                    status   : '0'
                  }, {
                    title    : 'Operación 981922',
                    duration : '60',
                    status   : '0'
                  }];

});

3 Answers 3

3

Be clear in your code about the concepts you're using (i.e. operations vs operationTypes) and don't mix them together. Avoid naming things too similarly as it creates unnecessary confusion.

jsbin.com/hujerurivu/1/edit?html,css,js,output

angular.module('ionicApp',[]).controller('mainCtrl', function($scope) {
    $scope.operationTypes = [{
                    title    : 'Operación 170794',
                    duration : '3600',
                    status   : '0'
                  }, {
                    title    : 'Operación 981922',
                    duration : '60',
                    status   : '0'
                  }];

    $scope.operations = {};
    angular.forEach($scope.operationTypes, function(operationType){
        $scope.operations[operationType.title] = [];
    });
});

--

    <div class="panel panel-default">
        <div class="panel-body" ng-repeat="operationType in operationTypes track by $index">
            <p>{{operationType.title}} | {{operationType.duration}} | {{operationType.status}}</p>
            <div>
                <div ng-repeat="operation in operations[operationType.title] track by $index">
                    <input ng-model="operation.detailText" type="text"></input>
                </div>
                <button ng-click="operations[operationType.title].push({})">Add one more</button>
            </div>
        </div>
    </div>
Sign up to request clarification or add additional context in comments.

Comments

2

You can't have 2 things point to the same array and have a different output. JavaScript objects are by reference and an array is an object. So both of your lists were reading from the same array. If you add a key operations to each of the objects and push to that it will keep the lists separate.

You want to add a key operations to your operation objects like so:

angular.module('ionicApp',[])

.controller('mainCtrl', function($scope) {
    $scope.operation = [{
      title    : 'Operación 170794',
      duration : '3600',
      status   : '0',
      operations: []
    }, {
      title    : 'Operación 981922',
      duration : '60',
      status   : '0',
      operations: []
    }];

});

Then change your loops like so:

<div class="panel-body" ng-repeat="op in operation track by $index">
                <p>{{op.title}} | {{op.duration}} | {{op.status}}</p>
                <input ng-model="operation.detailText" type="text"></input>
                <div>
                    <div ng-repeat="operation in op.operations track by $index">

                        <input ng-model="operation.detailText" type="text"></input>

                    </div>
                    <button ng-click="op.operations.push({})">Add one more</button>
                </div>
            </div>

You can also add an index to each operation you push to operations and filter by it with ng-if:

<div class="panel-body" ng-repeat="op in operation track by $index">
    <p>{{op.title}} | {{op.duration}} | {{op.status}}</p>
    <input ng-model="operation.detailText" type="text"></input>
    <div>
        <div ng-repeat="operation in operations track by $index" ng-if="operation._index === $index">

            <input ng-model="operation.detailText" type="text"></input>

        </div>
        <button ng-click="addOperation($index)">Add one more</button>
    </div>
</div>

angular.module('ionicApp',[])

.controller('mainCtrl', function($scope) {
    $scope.operations = [];

    $scope.operation = [{
      title    : 'Operación 170794',
      duration : '3600',
      status   : '0'
    }, {
      title    : 'Operación 981922',
      duration : '60',
      status   : '0'
    }];

    $scope.addOperation = function(index){
        $scope.operations.push({
            _index: index
        });
    };
});

3 Comments

Is it out of the question to manage them this way on the front end then concat the operation.operations array into 1 array before sending it to the server?
Ok, I will work on it this way for now, once I get the real data from the DB, probably I will need your help, thank you :)
Updated answer with a 2nd thing you can try
1

If you add an array to each of the 'operation' objects you can loop through those separately as seen below:

This will keep the forms and inputs separate.

http://jsbin.com/tapeje/5/edit

Comments

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.