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

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.

Related

ng-if not working with ng-repeat and radio button

I have the following html template:
<div ng-app ng-controller="Ctrl">
<div class="cont">
<table>
<tr><th ng-repeat="column in columns">{{column}}</th></tr>
<tr ng-repeat="(i, row) in people">
<td ng-repeat="(j, column) in columns">
<input type="radio" name="select" ng-if="column === 'id'">
<span>{{row[column]}}</span>
</td>
</tr>
</table>
</div>
</div>
Then I define my Ctrl as follow
function Ctrl($scope) {
$scope.selectedId = 'aaaaa';
$scope.columns = ['id','name', 'age'];
$scope.people=[
{
'id':'aaaaa', 'name':'rachit', 'age':11
},
{
'id':'bbbbb', 'name':'gulati', 'age':12
},
{
'id':'ccccc', 'name':'rocks', 'age': 13
}
]
}
https://jsfiddle.net/en91zuxb/
it's showing radio input for all the item, while my intention is to only show the radio button on the first column, because the 1st column is the id column... ...
It seems that your angular version is old, this was an error related to angularjs < 1.2. Try upgrading your angularjs version or use ng-show instead.
Following code worked for me.
<input type="radio" name="select" ng-show="column == 'id' ">

How to get values of current table row's html controls on button click?

Not getting the values of table row's HTML controls after binding the table by angularjs ng-repeat, by below code
$(".btnAddToCartClass").click(function () {
var item = $(this).closest("tr").find(".ddlCategoryClass").val();
var itemQty = $(this).closest("tr").find(".txtQuantityClass").val();
var itemCondition = $(this).closest("tr").find(".chkUrgentClass").is(':checked');
alert(item + ' ' + itemQty + ' ' + itemCondition);
});
<table id="TblAdminDash">
<tbody ng-repeat="IL in ItemsListForOrder">
<tr>
<td ng-bind="IL.ItemName"></td>
<td>
<select class="ddlCategoryClass" id="ddlCategory"
ng-model="ddlCategory">
<option value="" disabled>Select Category</option>
<option value="DryClean">Dry Clean</option>
</select>
</td>
<td>
Qty
<input id="txtQuantity" class="txtQuantityClass"
type="number" max="10000" min="1" value="1" />
</td>
<td>
<input type="checkbox" id="chkUrgent" ng-model="chkUrgent"
class="chkUrgentClass"/> Urgent
</td>
<td>
<input type="button" class="btnAddToCartClass" value="Add"/>
</td>
</tr>
</tbody>
</table>
I tried by jquery like above before binding its worked as expected but after bind the table its not working..
Use the ng-click directive to specify a function in the controller to add the item:
<tbody ng-repeat="IL in ItemsListForOrder">
<tr>
<!-- ... -->
<td>
<input type="button" class="btnAddToCartClass" value="Add"
ng-click="addItem(IL) />
</td>
</tr>
</tbody>
JS
$scope.addItem = function(item) {
console.log(item);
//...
};
For more information, see
AngularJS ng-click Directive API Reference
I need clicked button's current rows other Html control values like I getting mentioned jquery code.
Bind the model to the ng-repeat iterator:
<tbody ng-repeat="IL in ItemsListForOrder">
<tr>
<td>
<input type="checkbox" id="chkUrgent" ng-model="IL.chkUrgent"
class="chkUrgentClass"/> Urgent
</td>
<!-- ... -->
</tr>
</tbody>
$scope.addItem = function(item) {
console.log(item);
console.log(item.chkUrgent);
//...
};
New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the data hiding problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)
This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
For more information, see
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
I got it by like below
<input type="button" class="btnAddToCartClass"
data-ng-click="AddToCart($event)" value="Add" />
$scope.AddToCart = function (event) {
var item = $(event.target).closest("tr").find(".ddlCategoryClass").val();
var itemQty = $(event.target).closest("tr").find(".txtQuantityClass").val();
var itemCondition = $(event.target).closest("tr").find(".chkUrgentClass").is(':checked');
alert(item + ' ' + itemQty + ' ' + itemCondition);
};

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.

AngularJS: Iterating over object properties and two way binding

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>

AngularJS NG-Repeat Select and set selected on page load?

I am generating a grid thru Angular and each row will have a dropdown. I want the dropdown to populate with data from the server which is working but during page load, it needs to set the selected item of each dropdown to the value of the property it's bound to. Simple example below...
Class CategoryField
ID
Name
CategoryID = 2
Select
Option1 text=Category A value=1
Option2 text=Category B value=2 <--- This item should be selected on load.
The code i have appears to have a selected attribute on an item in each dropdown from page source but the dropdown is loading and selecting the blank item angular adds. Code below for grid...UPDATED CODE BELOW
<div ng-app="CategoryFieldsApp">
Search:<input ng-model="search" type="text" placeholder="Search" />
#using (Html.BeginForm("CategoryFields", "Maintenance", FormMethod.Post))
{
<div ng-controller="CategoryFieldsCtrl">
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th width="200">Category</th>
<th ng-click="sort('Name')" width="200">Name</th>
<th width="150">Active</th>
</tr>
</thead>
<tbody id="CategoryFieldGrid">
<tr dir-paginate="categoryField in categoryFields|orderBy:sortKey:reverse|filter:search|itemsPerPage:10">
<td>
<input type="hidden" name="CategoryFields[{{$index}}].CategoryFieldID" ng-model="categoryField.CategoryFieldID" />
</td>
<td>
<input class="hdnCategoryID" type="hidden" name="CategoryFields[{{$index}}].CategoryID" />
<select ng-model="categoryField.CategoryID" ng-options="category.CategoryID as category.Name for category in categories"></select>
</td>
<td>
<input type="text" name="CategoryFields[{{$index}}].Name" ng-model="categoryField.Name" />
</td>
<td>
<input type="checkbox" class="active checkBox checkbox-inline" value="{{categoryField.Active}}" ng-model="categoryField.Active" name="CategoryFields[{{$index}}].Active" />
</td>
<td>
<input type="button" ng-click="remove($index)" value="Remove" />
</td>
</tr>
</tbody>
</table>
<dir-pagination-controls max-size="5"
direction-links="true"
boundary-links="true">
</dir-pagination-controls>
<br />
<a class="btn btn-default" ng-click="add()">Add Category Field</a>
<input class="btn-primary btn-sm" type="submit" value="Save" />
</div>
}
<script>
var App = angular.module('CategoryFieldsApp', ['angularUtils.directives.dirPagination']).controller('CategoryFieldsCtrl', function ($scope, $http) {
$http.get("#Url.Action("GetCategoryFields", "Maintenance")").success(function (response) {
$scope.categoryFields = response; //ajax request to fetch data into $scope.data
});
$http.get("#Url.Action("GetCategories", "Maintenance")").success(function (response) {
$scope.categories = response; //ajax request to fetch data into $scope.data
});
$scope.sort = function (keyname) {
$scope.sortKey = keyname; //set the sortKey to the param passed
$scope.reverse = !$scope.reverse; //if true make it false and vice versa
}
$scope.remove = function (index) {
$scope.categoryFields.splice(index, 1);
};
$scope.add = function () {
$scope.categoryFields.push({
CategoryFieldID: 0,
CategoryID: 0,
Name: '',
Active: true,
ShowRemove: true
});
};
});
//$(document).ready(function () {
// $('#CategoryFieldGrid tr').each(function (i, row) {
// var categoryID = $(row).find('.hdnCategoryID').val();
// console.log(categoryID);
// $(row).find('.ddlCategories').val(categoryID);
// });
// $('.ddlCategories').on('change', function (e) {
// var hidden = $(e.target).closest('tr').find('.hdnCategoryID');
// $(hidden).val($(e.target).closest('tr').find('.ddlCategories').val());
// });
//});
Have you considered using ng-options? It could be used to replace the explicit definition of your options:
<select ng-model="categoryField.CategoryID" ng-options="category.CategoryID as category.Name for category in categories"></select>
if you break down the expression we pass to ng-options, we're setting the value of the selected item to the CategoryID property, the visible name of each option to the category Name property, and we're passing in all the categories defined $scope.categories as options:
"category.CategoryID as category.Name for category in categories"
Here's a working example I put together: http://plnkr.co/edit/CXZaUYfqcIv7PbeUrT9j?p=preview
I was able to figure out the other side of the bindings so that the mvc model was updated for post back. I simply created a hidden field that was bound to the same property. When angular's ng-model updates, it updated the value of the hidden field also. Below is the syntax for those who needs it.
<input class="hdnCategoryFieldID" type="hidden" name="CategoryFieldApprovers[{{$index}}].CategoryFieldID" value="{{categoryFieldApprover.CategoryFieldID}}" />
<select ng-model="categoryFieldApprover.CategoryFieldID" ng-options="categoryField.CategoryFieldID as categoryField.Name for categoryField in categoryFields"></select>

Resources