AngularJS: Iterating over object properties and two way binding - angularjs

I want to loop over an object's property. Also, there should be a two-way data binding so that any change will change the Object as well.
Both key and value of the object property can be changed from UI and should reflect in the object's structure.
I am able to do it for object's value with ng-model="contents[index]"
but how to do that with object property key e.g. interface in the object will change if I change it on UI.
$scope.contents = {
"interface": "GigabitEthernet",
"interfaceNumber": "1",
"BGPneighborIp": "00.0.112.499",
"BGPremoteAs_[1]": "701",
"BGPneighborIp_[2]": "8.3.112.170",
"BGPremoteAs_[2]": "702"
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<tbody>
<tr ng-repeat="(index, p1) in contents">
<td>
<input class="form-control" type="text" ng-model="index">
</td>
<td>
<input class="form-control" type="text" ng-model="contents[index]">
</td>
</tr>
</tbody>

Try this solution:
angular.module('app',[]).controller('test',['$scope', function($scope){
$scope.contents = {
"interface": "GigabitEthernet",
"interfaceNumber": "1",
"BGPneighborIp": "00.0.112.499",
"BGPremoteAs_[1]": "701",
"BGPneighborIp_[2]": "8.3.112.170",
"BGPremoteAs_[2]": "702"
};
$scope.arr = [];
for(var prop in $scope.contents)
$scope.arr.push({oldKey:prop, newKey:prop});
$scope.change = function(item){
$scope.contents[item.newKey] = $scope.contents[item.oldKey];
delete $scope.contents[item.oldKey];
item.oldKey = item.newKey;
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='test'>
<input ng-repeat-start='item in arr' type='text' ng-model="item.newKey" ng-change='change(item)'>
<input type='text' ng-model="contents[item.oldKey]" >
<br ng-repeat-end>
<p>{{contents|json}}</p>
</div>

Related

AngularJS dynamic form input with fieldset via ng-repeat

Please click on the demo below
www.jsfiddle.net/rnnb32rm/1370
My problem is: "Add input" is working fine. But whenever i invoke "Add
Fields", the subsequent field will be sync with the first one. I want
the subsequent to be filled with only one input. Stuck for hours already. Please guide!
Picture to illustrate:
May be help you.
var app = angular.module("app",[]);
app.controller("MyCtrl" , function($scope){
$scope.data ={
items:[{ name:"",family:"",age:""}]
};
$scope.addRow = function(index){
var item = { name:"",family:"",age:""};
if($scope.data.items.length <= index+1){
$scope.data.items.splice(index+1,0,item);
}
};
$scope.deleteRow = function($event,item){
var index = $scope.data.items.indexOf(item);
if($event.which == 1)
$scope.data.items.splice(index,1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<table>
<tr ng-repeat="name in data.items track by $index">
<td> <input type="text" ng-model="data.items[$index].name"></td>
<td> <input type="text" ng-model="data.items[$index].family"></td>
<td> <input type="text" ng-model="data.items[$index].age"></td>
<td> <input type="button" ng-click="addRow($index)" value="Add" ng-show="$last"></td>
<td> <input type="button" ng-click="deleteRow($event,name)" value="Delete" ng-show="$index != 0"></td>
</tr>
</table>
<span>{{data|json}}</span>
</div>
I answered this the first time you posted this question, but you deleted it.
You only have one choices array, and you are using it over and over:
$scope.addNewChoice = function() {
// ...
// Same array each time
$scope.choices.push({'id':'choice'+newItemNo});
};
<fieldset data-ng-repeat="choice in choices2">
<div data-ng-repeat="choice in choices "> <!-- Same array each time -->
You probably want one array for each entry in the choices2 array.
Also, both of your ng-repeat elements use the same variable name (choice) which is confusing.

passing the value from table to textbox in angularjs

I am trying to pass the value from table to text box in angularjs. value should be pass when i click 'pass the value' button. can anyone help me with this?
my code is shared below:
angular.module('app', [])
.controller('controller', function($scope) {
$scope.array = [{
id:1,
name: 'name1',
address: 'address1'
}, {
id:2,
name: 'name2',
address: 'address2'
}, {
id:3,
name: 'name3',
address: 'address3'
}];
$scope.edit=function(id){
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<body ng-app="app" ng-controller="controller" class="container">
<table class="table table-condensed">
<tr>
<th>id</th>
<th>name</th>
<th>address</th>
</tr>
<tr ng-repeat="item in array" >
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.address}}</td>
<td><button ng-click="edit(item.id)">pass the value</button></td>
</tr>
</table>
<form>
name <input type="text" ng-model="item.name" />
address <input type="text" ng-model="item.address"/>
</form>
</body>
Instead of just passing the id, pass the whole item to the edit function:
<button ng-click="edit(item)">
Then you can set the item on scope to the passed item:
$scope.edit=function(item){
$scope.item = item;
};
Plunkr
You should assign your index in a variable in click function. Like
<button ng-click=" newIndex = $index; ">pass the value</button>
And fetch this indexed value from array. Like
name <input type="text" ng-value="array[newIndex].name" />
address <input type="text" ng-value="array[newIndex].address"/>
Make sure to declare newIndex in your controller first. Like
$scope.newIndex = null;

How to add checkbox values to an array in AngularJS?

Someone help me please!
Lets say I have an a list of a checkboxes, each checkbox have an ID.
I would like to $scope an array with checked checkboxes IDs.
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<table>
<tr ng-repeat="(key, value) in providers">
<td><input type="checkbox" ng-model="ids[value.Id]"> {{value}} </td>
</tr>
</table>
{{ids}}
</div>
And my controller:
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.providers = [{Id:5},{Id:6},{Id:8},{Id:10}];
$scope.ids = {};
});
Now my array output (if all check boxes are checked) is: {"5":true,"6":true,"8":true,"10":true}
And I would like: [{Id:5},{Id:6},{Id:8},{Id:10}]
this is a possible solution:
<input type="checkbox" ng-model="ids[$index]" ng-true-value="
{{value}}" ng-false-value="{{undefined}}"/>{{value}}
In this way, you will have an array of objects, because you are assigning ids[$index] = value.
There is a cons however: when you double check a checkbox, you will have an empty element in the array.
var app = angular.module('myapp', []);
app.controller('ctrlParent', function($scope) {
$scope.providers = [{
Id: 5
}, {
Id: 6
}, {
Id: 8
}, {
Id: 10
}];
$scope.ids = [];
$scope.$watchCollection('ids', function(newVal) {
for (var i = 0; i < newVal.length; ++i) {
console.log(newVal[i]);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<table>
<tr ng-repeat="(key,value) in providers">
<td>
<input type="checkbox" ng-model="ids[$index]" ng-true-value="{{value}}" ng-false-value="{{undefined}}" />{{value}}
</td>
</tr>
</table>{{ids}}</div>
</div>
http://jsfiddle.net/b9jj0re2/3/
<input type="checkbox" ng-model="ids[$index]" ng-true-value="{{value}}" >
Addign the ng-true-value directive will solve the problem
and in controller change the ids from object to array
plunker

Angular Js two way binding

I have few text boxes and would like to implement the simple calculation like:
Value of (TextBox1 + TextBox2 + textBox3) = Value of TextBox4.
(TextBox4 + TextBox5)= value of TextBox6
How can achieve this in AngularJS?
See below for an example:
<table ng-app="" ng-controller="acadController">
<tr ng-repeat="x in semone">
<td>{{ x.SubjectName }}</td>
<td>{{ x.Credit }}</td>
<td><input type="number" ng-model="pt1" /></td>
<td><input type="number" ng-model="pt2"/></td>
<td><input type="number" ng-model="ia"/></td>
<td><input type="number" value="{{pt1+pt2+ia}}" ng-model="semMarks" class="marks_catotal" /></td>
<td><input type="number" ng-model="endSemMarks" class="marks_endsem" /></td>
<td><input type="text" class="marks_total" value="{{ semMarks + endSemMarks }}"/></td>
</tr>
<table>
You can use use $scope.watch to watch those variables and their sum and if it changes add it to $scope.marks
$scope.$watch('pt1 + pt2', function(v) {$scope.marks = v;});
See this plnkr: http://embed.plnkr.co/p0rQkUBMfEmYZkKh4Nrt/
You can use the $watch function to react to user changes :
Inside your controller, you can fire a function when a value is modified.
function calculateResult(){
$scope.semMarks = $scope.pt1 + $scope.pt2 + $scope.ia;
}
$scope.$watch('pt1', calculateResult);
$scope.$watch('pt2', calculateResult);
Instead of your watch, you could also have registered a function that will be fired directly when you modify a value :
$scope.calculateResult = calculateResult;
And then, inside your view, you would just have to call this function when an input is modified.
<td><input type="number" ng-model="pt2" ng-change="calculateResult()"/></td>
Most of the time, using an event consumes less processor than using a $watch. Angular evaluates every $watch and check if there were any changes during each $digest cycle. Angulars uses also a lot of $watches itself, so adding too much $watches can significally decrease performances.
Consider introducing a controller for endSemMarks and marks_total.
You should simply bind to a function that evaluates the sum of the values. As mentioned above, $watch is more expensive and a little harder to understand.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.tb1 = 0;
$scope.tb2 = 0;
$scope.tb3 = 0;
$scope.tb5 = 0;
$scope.sum123 = function() {
return $scope.tb1 + $scope.tb2 + $scope.tb3;
}
$scope.sum45 = function() {
return $scope.tb1 + $scope.tb2 + $scope.tb3 + $scope.tb5;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div>1 :
<input type="number" ng-model="tb1">
</div>
<div>2 :
<input type="number" ng-model="tb2">
</div>
<div>3 :
<input type="number" ng-model="tb3">
</div>
<div>4 :
<input type="number" ng-value="sum123()">
</div>
<div>5 :
<input type="number" ng-model="tb5">
</div>
<div>6 :
<input type="number" ng-value="sum45()">
</div>
</body>

How to watch ng-model included in ng-repeat?

This is my html code:
<table>
<tr ng-repeat="park in parkOptions.parks">
<td>
<label for="{{park.park_id}}">
<input id="{{park.park_id}}" type="radio" name="connection" ng-model="$parent.currentPark" value="{{park.park_id}}" ng-click="selectValue('park',park)"/>{{park.park_name}}
</label>
</td>
</tr>
</table>
How can i watch the changes in my model( I mean i want to see in $watch another park when i click radio button)
I've got a working version to help you - Fiddle.
HTML
<div ng-app ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
<table>
<tr ng-repeat="park in parkOptions.parks">
<td>
<label for="{{park.park_id}}">
<input id="{{park.park_id}}" type="radio" name="connection" ng-model="parkOptions.currentPark" value="{{park.park_id}}" ng-click="selectValue(park)"/> {{park.park_name}}
</label>
</td>
</tr>
</table>
</div>
</div>
JS
function ParentCtrl($scope) {
}
function ChildCtrl($scope) {
$scope.parkOptions = {};
$scope.parkOptions.parks = [
{park_id: '01', park_name: 'England Park'},
{park_id: '02', park_name: 'France Park'}
];
$scope.$watch('parkOptions.currentPark', function(newValue) {
if (newValue != undefined) {
console.log(newValue);
}
});
}
This may not be exactly what you want (as I see $parent in your code) but we can come to the right solution with any further information from you.
I don't use $parent and prefer sending and receiving events.

Resources