watchCollection on ng-model does not fire when checkbox is toggled - angularjs

When I click the checkbox, the $scope.$watchCollection('classes' does not fire. Any suggestions?
<div class="filter-column">
<div class="filter-title">Class</div>
<div class="bottom-line"></div>
<div class="overflow-container">
<div ng-repeat="class in classes | orderBy">
<input type="checkbox"
ng-model="class.checked" >
{{class.description}}
</div>
</div>
</div>
$scope.$watchCollection('classes', function(newValue) {
console.log('sss')
});

To fixed your code, follow answer from #Sajeetharan for deep watch collection. But I think ng-change should be used in your case to capture event
<input type="checkbox" ng-model="class.checked" ng-change="chkChecked(class);"> {{class.description}}

You can have a deepwatch in that case,
$scope.$watch(function($scope) {
return $scope.classes.
map(function(obj) {
return obj.checked
});
}, function(newVal) {
$scope.checked = true;
alert("css chagned");
}, true);
DEMO

// Code goes here
angular
.module('myApp', [])
.controller('testController', ['$scope',
function($scope) {
$scope.classes = [{
description: 'label1',
}, {
description: 'label2',
}];
$scope.$watch('classes', function(newValue) {
console.log("watcher called");
}, true);
}
]);
<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body data-ng-controller="testController">
<div class="filter-column">
<div class="filter-title">Class</div>
<div class="bottom-line"></div>
<div class="overflow-container">
<div ng-repeat="class in classes | orderBy">
<input type="checkbox" ng-model="class.checked" ng-change="call(class)">{{class.description}}
</div>
</div>
</div>
</body>
</html>
$watch is able to get the changes.

Related

angular-virtual-keyboard not opening on focus

var myApp = angular.module('myApp',['angular-virtual-keyboard']);
myApp.controller('MyCtrl',MyCtrl);
function MyCtrl($scope) {
document.getElementsByTagName('input')[0].focus();
}
<link href="https://rawgit.com/the-darc/angular-virtual-keyboard/master/release/angular-virtual-keyboard.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script src="https://rawgit.com/the-darc/angular-virtual-keyboard/master/release/angular-virtual-keyboard.js"></script>
<body ng-app='myApp'>
<div ng-controller="MyCtrl">
<input type='text' ng-model="textValue" ng-virtual-keyboard/>
</div>
</body>
If I click on input then virtual keyboard is opening. But how can I open the keyboard without click. I tried using input.focus() that didn't work.
Just find a working fiddle Here with an directive auto focus
var myApp = angular.module('myApp',['angular-virtual-keyboard']);
myApp.controller('MyCtrl',function($scope) {
});
myApp.directive('autoFocus', function($timeout) {
return {
restrict: 'AC',
link: function(_scope, _element) {
$timeout(function(){
_element[0].focus();
}, 0);
}
};
});
<link href="https://rawgit.com/the-darc/angular-virtual-keyboard/master/release/angular-virtual-keyboard.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script src="https://rawgit.com/the-darc/angular-virtual-keyboard/master/release/angular-virtual-keyboard.js"></script>
<body ng-app='myApp'>
<div ng-controller="MyCtrl">
<input type='text' ng-model="textValue" auto-focus ng-virtual-keyboard/>
</div>
</body>
You are doing change outside angularJS framework, so you need to apply it by $scope.$apply();
var myApp = angular.module('myApp',['angular-virtual-keyboard']);
myApp.controller('MyCtrl',MyCtrl);
function MyCtrl($scope) {
document.getElementsByTagName('input')[0].focus();
$scope.$apply();
}

json input validation with angularjs

I want to validate JSON input. I know it can be done with a custom directive, but I am not capable of writing it on my own. Now I am trying to do it with ng-change.
my html:
<div class="row">
<div class="form-group col-xs-12">
<label>Custom data:</label>
<textarea class="form-control" rows="10" name="customData" ng-model="application.customDataString" ng-change="validateJSON()"></textarea>
</div>
</div>
my script
$scope.validateJSON = function () {
try {
JSON.parse($scope.application.customDataString);
} catch (e) {
$scope.applicationForm.customData.$setValidity = false;
}
return true;
}
but I am getting an error: Cannot read property '$setValidity' of undefined
Check this
var app = angular.module('myApp', []);
app.controller('mainCtrl', function($scope) {
$scope.application = {
customDataString: ""
};
$scope.validateJSON = function() {
try {
JSON.parse($scope.application.customDataString);
$scope.myForm.customData.$valid = true;
// or
// myForm.customData.$setValidity('valid', true);
} catch (e) {
$scope.myForm.customData.$valid = false;
// or
// myForm.customData.$setValidity('valid', false);
}
return true;
}
})
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#1.6.5" data-semver="1.6.5" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="mainCtrl">
<div class="row" name="myForm" ng-form>
<div class="form-group col-xs-12">
<label>Custom data:</label>
<textarea class="form-control" rows="10" name="customData" ng-form ng-model="application.customDataString" ng-change="validateJSON(myForm)"></textarea>
</div>
</div>
<br>
IS JSON VALID: {{myForm.customData.$valid}}
</body>
</html>
Check this plunker too. Using ng-form https://plnkr.co/edit/0BFO08fYU0op6z2W9Vh4?p=preview

Pass $dirty flag from child form in directive to parent form

I am new to angular JS. I have main form it has text box and one directive which has checkboxes. If user addded some text to textbox or modify inital status of checkboxes, when user click on ok button I have to check dirty flag and prompt user for unsaved changes. This is my plunk.
I have to use angular 1.3.16 version.
script.js:
// Code goes here
(function() {
"Use Strict";
angular.module('myapp', []);
angular.module('myapp').
controller('myappctrl', function($scope) {
$scope.user = {
list: [{
id: 1,
value: 'chkbox1',
selectedReturnType: false
}, {
id: 2,
value: 'chkbox2',
selectedReturnType: true
}, {
id: 3,
value: 'chkbox3',
selectedReturnType: false
}, {
id: 4,
value: 'chkbox4',
selectedReturnType: true
}, ]
};
$scope.ok = function() {
if ($scope.mainform.$dirty) {
alert('form modified');
}
};
});
angular.module('myapp').directive('checkboxdir', function() {
return {
templateUrl: "checkboxdir.html",
restrict: 'EA',
scope: {
user: '='
}
}
});
}());
Index.html:
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<link rel="stylesheet" href="style.css" />
<script data-require="jquery#*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script data-require="angular.js#1.3.16" data-semver="1.3.16" src="https://code.angularjs.org/1.3.16/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="myappctrl">
<form name="mainform" novalidate>
<checkboxdir user='user'></checkboxdir>
<input type="text" />
<input type="button" value="ok" ng-click="ok()"/>
</form>
</body>
</html>
Directive:
<div>
<form name='returntypeform' novalidate>
<div ng-repeat='item in user.list'>
<input type='checkbox' ng-checked="item.selectedReturnType" />
<label>{{item.value}}</label>
</div>
</form>
</div>
Need to pass checkbox check/uncheck from child directive to parent. Any idea why this is not working?
You have missed ng-model.
I have updated the plunker :
plunker
<body ng-controller="myappctrl">
<div ng-form="mainform">
<checkboxdir user='user'></checkboxdir>
<input type="text" data-ng-model="model" name="text"/>
<input type="button" value="ok" ng-click="ok()"/>
</div>
</body>
<div>
<form name='returntypeform' novalidate>
<div ng-repeat='item in user.list'>
<input type='checkbox'
name="$index"
data-ng-model="item.selectedReturnType"
ng-checked="item.selectedReturnType" />
<label>{{item.value}}</label>
</div>
</form>
</div>

Angular, data in one controller filter to this data in other

At start i want to say im new in angular. Lets say my page look like this:
index.html:
<body ng-app="application">
<div class="container">
<div class="row">
<div class="col-sm-3 sideBar" ng-controller="NavController">
<input ng-model"search">
</div>
<div class="col-sm-9 content" ng-controller="ContentController">
<div ng-repeat="meet in meets | filter:search">
{{ meet.someData }}
</div>
</div>
</div>
</div>
</body>
And how can i make that input in NavController could filter data from ContentController? I want to do this in two controllers.
I'm not sure why you want to do this in two controllers, but it will be considerably more difficult. The Search functionality acts on the data in the content controller. I am guessing that your layout is driving your controller design.
There are numerous posts here that discuss techniques for this. This one: Share data between AngularJS controllers is well-regarded.
Actually you can just do that in a single controller.
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.name = [{
"id":1
},{
"id":2
},{
"id":3
}]
});
<!DOCTYPE html>
<html ng-app="angularjs-starter">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//code.angularjs.org/1.1.1/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl"><input ng-model='find' />
<div ng-repeat="x in name | filter : find">
{{x.id}}
</div>
</body>
</html>
For understanding, i used numbers as data. :) Hope it helps you
You can have a parent controller over the other two controllers. If you use the controllerAs method you can have controllers inside each other, see Angular Style Guide for helpful information about controllers and controllerAs.
You could write it like that and bind the search model to the ParentController.
Edit: I added another solution that I think is better
var app = angular.module('app', []);
app.controller('ParentController', function() {
this.search = 'p'; //set default just for fun
});
app.controller('NavController', function() {
//nav stuff
});
app.controller('ContentController', function() {
this.meets = [{
data: 'hi'
}, {
data: 'potato'
}, {
data: 'help me'
}, {
data: 'pie'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div class="container" ng-controller="ParentController as parentVm">
<div class="row">
<div class="col-sm-3 sideBar" ng-controller="NavController as navVm">
<input ng-model="parentVm.search">
</div>
<div class="col-sm-9 content" ng-controller="ContentController as contentVm">
<div ng-repeat="meet in contentVm.meets | filter:parentVm.search">
{{ meet.data }}
</div>
</div>
</div>
</div>
</body>
I stepped away from this for a bit and thought of another idea that doesn't involve using another controller. Here you are using a factory instead to communicate between the controllers. You have to share an object so that when you change the search.term in the input it will change for every reference.
var app = angular.module('app', []);
app.factory('Searcher', function() {
return {
search: {
term: 'p'
}
};
});
app.controller('NavController', function(Searcher) {
//nav stuff
this.search = Searcher.search;
});
app.controller('ContentController', function(Searcher) {
this.search = Searcher.search;
this.meets = [{
data: 'hi'
}, {
data: 'potato'
}, {
data: 'help me'
}, {
data: 'pie'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div class="container">
<div class="row">
<div class="col-sm-3 sideBar" ng-controller="NavController as navVm">
<input ng-model="navVm.search.term">
</div>
<div class="col-sm-9 content" ng-controller="ContentController as contentVm">
<div ng-repeat="meet in contentVm.meets | filter:contentVm.search.term">
{{ meet.data }}
</div>
</div>
</div>
</div>
</body>

Loading image at the time of onclick event using angularjs is not working

I want to add data at the time of onclick event. Need to load image at the time of onclick event, after a small time interval add data. But my image is continuously loading. Any body give any suggestion.
My code is:
<!DOCTYPE html>
<head>
<title>Learning AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js" type="text/javascript"></script>
<script language="javascript">
function ContactController($scope) {
$scope.contacts = [];
$scope.items = [ ];
$scope.add = function() {
setTimeout(function() {
$scope.$apply(function() {
$scope.items[0].lateLoader = ' xxxx ';
});
}, 1000);
$scope.count=$scope.count+1;
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
}
}
</script>
</head>
<body >
<div ng-app="" ng-controller="ContactController">
<p>{{items.lateLoader}}
<i ng-hide="items.lateLoader"><img src="Filling broken ring.gif"></i>
</p>
{{ contacts.length }}
Content:<input type="text" ng-model="newcontact" />
<button ng-click="add()">Add</button>
<ul style="list-style-type: none;">
<li ng-repeat="contact in contacts"> <input name="" type="checkbox" value="">{{ contact }}</li>
</ul>
</div>
</body>
</html>
In your example I found a lot of mistakes. The HTML tag is not defined at the top, wrong use of angularJs and Angular module is not created properly etc.
I fixed all the mistakes. I hope it can help you.
Plunkr link: http://plnkr.co/edit/no8WOHdEc9wc3dHzzITv?p=preview
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Learning AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script >
angular.module("app",[]).controller('ContactController',['$scope',
function($scope) {
$scope.contacts = [];
$scope.items = [];
$scope.add = function() {
setTimeout(function() {
$scope.$apply(function() {
$scope.items.lateLoader = 'xxxx ';
});
}, 1000);
//$scope.count=$scope.count+1;
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
}
}
]);
</script>
</head>
<body >
<div ng-controller="ContactController">
<p>{{items.lateLoader}}
<i ng-hide="items.lateLoader">
<img src="https://encrypted-tbn1.gstatic.com
/images?q=tbn:ANd9GcQTaHe0F0J39SXbiRF43pz2wtyfD6kypCMrLxhWPkq9EACNgwO0iaMbJFM">
</i>
</p>
{{contacts.length}}
Content:<input type="text" ng-model="newcontact" />
<button ng-click="add()">Add</button>
<ul style="list-style-type: none;">
<li ng-repeat="contact in contacts">
<input name="" type="checkbox" value="">{{ contact }}
</li>
</ul>
</div>
</body>
</html>
And for more detail of angularJs please visit these links:(https://angularjs.org/)
(http://www.w3schools.com/angular/default.asp)

Resources