Generate dynamic form input fields and collect field data in an array
Solution 1
Right now you are iterating $scope.fields
. When you are adding a new field you push an empty object into $scope.fields
, but every input's ng-model points to $scope.table.fields
(which is non-existing until first input writes to it - then it will hold a string variable).
For this simple use case you could try:
app.controller('NewTableCtrl', function($scope) {
$scope.table = { fields: [] };
$scope.addFormField = function() {
$scope.table.fields.push('');
}
$scope.submitTable = function() {
console.log($scope.table);
}
});
And:
<input ng-repeat="field in table.fields track by $index" type='text' ng-model='table.fields[$index]' placeholder='Field:'>
Demo: http://plnkr.co/edit/6iZSIBa9S1G95pIMBRBu?p=preview
Solution 2
Take a look at this
html
<body>
<div ng-app=''>
<div ng-controller="questionCtrl">
<div>
<ul>
<li ng-repeat="elemnt in questionelemnt">
<div>
<div id={{elemnt.id}} style="display:inline" >
<span ng-model="elemnt.question" ng-hide="editorEnabled" ng-click="editorEnabled=true">
{{elemnt.question}}
</span>
<div ng-show="editorEnabled">
<input ng-model="elemnt.question" ng-show="editorEnabled" >
<button href="#" ng-click="editorEnabled=false">Done editing</button>
</div>
</div>
<div style="display:inline">
<span>
<input type="text" ng-model="elemnt.answer" placeholder="Answer" required/>
</span>
</div>
<span ng-hide="elemnt.length == 1">
<button ng-click="questionelemnt.splice($index, 1)">Remove</button>
</span>
</div>
<hr/>
</li>
<li>
<button ng-click="addFormField($event)">Add</button>
</li>
</ul>
</div>
<div>
<button ng-click="showitems($event)">Submit</button>
</div>
<div id="displayitems" style="visibility:hidden;">
{{questionelemnt}}
</div>
</div>
</div>
</body>
script
function questionCtrl($scope) {
var counter = 0;
$scope.questionelemnt = [{
id: counter,
question: 'Question-Click on me to edit!',
answer: ''
}];
$scope.addFormField = function ($event) {
counter++;
$scope.questionelemnt.push({
id: counter,
question: 'Question-Click on me to edit!',
answer: ''
});
$event.preventDefault();
}
$scope.showitems = function ($event) {
$('#displayitems').css('visibility', 'none');
}
}
r.sendecky
I am a network engineer working for a financial company in Sydney. In my spare time I enjoy programming Ruby and learning Haskell. Also, I love hunting, camping and mat/ring fighting (Ju-Jitsu, Boxing)
Updated on October 24, 2020Comments
-
r.sendecky over 3 years
I am stuck with this little task. I need to generate form input fields dynamically by clicking 'add' button on the form. The form is supposed to create DB table schema. So every input field is a DB table field name.
I am OK generating the fields dynamically but have trouble with gathering the actual data.
<form ng-controller="NewTableCtrl" ng-submit="submitTable()"> <input type='text' ng-model='table.title' placeholder='Title:'> <input ng-repeat="field in fields" type='text' ng-model='table.fields' placeholder='Field:'> <div> <button type='submit'>Submit</button> <button ng-click="addFormField()">Add</button> </div> </form>
.. and the controller
.controller('NewTableCtrl', function($scope) { $scope.fields = []; $scope.table = {}; $scope.addFormField = function () { $scope.fields.push({}); } $scope.submitTable = function () { console.log($scope.table); } });
Looks simple. When I click 'Add' button it generates the new input field but it does it with the same model object (obveously). And that's where my misunderstanding lies. I thought that if I declare
$scope.fields = [];
in the controller then repeating field data will just go into the array. But it just echoes the input in every repeating input field. I understand now that this is how it is supposed to be with two way binding.The reason I thought like this is by the analogy with an ordinary form submission where the repeating input field names become an array in the URL encoded form data.
So how do I solve this? The server needs to get an array of fields like this:
fields: [field1, field2 ...]
Do I need to generate input fields with different scope variable for each field? How do I do this?Is this more complex then I thought and it needs to be a directive? If yes, please, show me how to do this.
Thanks.