Reputation: 6425
I have a situation where I want the user to dynamically add <input>
rows when they want to enter a new item. As shown below, the user clicks the "Add Input Item" button and a new input element is added where the user may add text.
I'm trying to associate each input element value to the model $scope.items
(an array) in app.js
. In my index.html
, I load the $scope.items
using an ng-repeat
.
What I do not understand is how I can get each input/row to automatically be added to & managed by the model defined as $scope.items
.
Is it possible to map each input element to an ng-model that relates to the items
array and, if so, how? Or, should directives be used in this situation?
The full code and runtime is on Plunker here (so that you can view the weird output).
Snippet from index.html
:
<body ng-controller="MainCtrl">
<button ng-click="addInputItem()">+ Add Input Item</button>
<div ng-repeat="item in items">
<input ng-model="items" type="text" value="{{item}}" size="40">
</div>
<pre>items = {{items | json}}</pre>
</body>
The app.js
code:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.items = ['First Item', 'Second Item'];
$scope.addInputItem = function() {
$scope.items.push('');
};
});
Upvotes: 0
Views: 7275
Reputation: 5290
The first problem is with the binding on the input boxes. Due to the ng-repeat
surrounding the input box, each input box has an item
value available to bind to, and that is what your ng-model
should be. You shouldn't be assigning anything to the value
attribute.
<input ng-model="item.value" type="text" size="40">
Making that change will at least get the input boxes to display the items. But typing in the boxes won't update the underlying array. That's the second problem.
The ng-repeat
directive prototypically inherits the scope from your controller (read more about scope here). Since your items are primitive strings, the elements in your ng-repeat
effectively get copies of the data from the controller, and typing in the boxes updates those copies, not the actual data in the controller.
To fix this, just make your items an array of objects instead of an array of strings.
$scope.items = [
{value:'First Item'},
{value: 'Second Item'}
];
Then you would bind your textboxes like this:
<input ng-model="item.value" type="text" size="40">
Here's a Plunker showing how it works.
Upvotes: 2