Using angular.js, I have a dynamic list of form fields I want to display to the user for editing (and later submission):
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
$scope.fields = {
foo: "foo",
bar: "bar",
baz: "baz"
};
});
And the HTML:
<div ng-app="app" ng-controller="Ctrl">
<table>
<th>key</th>
<th>value</th>
<th>fields[key]</th>
<tr ng-repeat="(key,value) in fields">
<td>{{key}}:</td>
<td><input type="text" ng-model="value"/></td>
<td><input type="text" ng-model="fields[key]"/></td>
</tr>
</table>
</div>
See this fiddle. For a reason I don't understand, the text input boxes aren't editable. I've tried two different ways as seen above: value
and fields[key]
. value
isn't editable at all, and fields[key]
will allow one keystroke and then it blurs. What am I doing wrong? Thank you.
SET answered why it's happening, but a work-around to achieve the desired behavior would be to maintain a separate array of your keys, and run ng-repeat off those keys. I added some text fields for testing to add more properties to $scope.fields
You could use $watch to dynamically set the keys when the property count changes, if your requirements were that the field count may change.
http://jsfiddle.net/aERwc/10/
markup
<div ng-app="app" ng-controller="Ctrl">
<table>
<th>key</th>
<th>value</th>
<tr ng-repeat="key in fieldKeys">
<td>{{key}}:</td>
<td><input type="text" ng-model="fields[key]"/></td>
</tr>
</table>
<div><h6>Add a field</h6>
key: <input type="text" ng-model="keyToAdd" /><br />
value: <input type="text" ng-model="valueToAdd" />
<button ng-click="addField()">Add Field</button>
</div>
</div>
controller
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
$scope.fields = {
foo: "foo",
bar: "bar",
baz: "baz"
};
$scope.fieldKeys = [];
$scope.setFieldKeys = function() {
var keys = [];
for (key in $scope.fields) {
keys.push(key);
}
$scope.fieldKeys = keys;
}
$scope.addField = function() {
$scope.fields[$scope.keyToAdd] = $scope.valueToAdd;
$scope.setFieldKeys();
$scope.keyToAdd = '';
$scope.valueToAdd = '';
}
$scope.setFieldKeys();
});
It is editable but after each key press your text field losing focus so that you have to click on it again to put another char.
And that happens because whole you template being re-rendered after each change in any of models. And after template re-rendered, currently there is no way to know which input should be focused. So you should create that way and you may want to write directive to hold focus on selected input.
You need to use an array of objects. Hopefully you can rework your model:
$scope.fields = [
{label: "foo", value: "foov"},
{label: "bar", value: "barv"},
{label: "baz", value: "bazv"}
];
<tr ng-repeat="field in fields">
<td>{{field.label}}:</td>
<td><input type="text" ng-model="field.value">
Fiddle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With