AngularJS, ng-repeat on radio and $scope.watch - angularjs

I'm using this example: https://jsfiddle.net/qnw8ogrk/1/ to create my radio-buttons.
I would like to be able to use $scope.watch on the radio-buttons, but I'm not able to use:
$scope.watch('selected', ...
What should I assign to .watch to be able to detect whenever a user clicks on a radio button?

Actual mistake was $scope.watch should be $scope.$watch Having watcher over a scope variable would not be the good idea. Instead of placing watcher over ng-model I'd suggest you to use ng-change which will only fires up when radio button ng-model value gets changed.
<label ng-repeat="option in options">
<input type="radio" ng-change="test()" ng-model="$parent.selected" ng-value="option" />{{option}}
</label>
And then don't use get rid of $parent notation for accessing outer scope of ng-repeat you could switch to use controllerAs pattern, and then change ng-controller directive to use alias of controller. Also that will change the controller implementation, bind value to this(context) instead of $scope
Markup
<div ng-controller="mainController as vm">
<label ng-repeat="option in vm.options">
<input type="radio" ng-change="vm.test()" ng-model="vm.selected" ng-value="option" />{{option}}
</label>
</div>
Controller
appModule.controller('mainController', function($scope) {
var vm = this;
vm.selected = 'red';
vm.options = ['red', 'blue', 'yellow', 'green'];
vm.test = function() {
alert('Changed');
}
});
Forked Plunkr

I agree with #PankajParker, but it is possible from you controller as well. You just got the syntax wrong, it is $scope.$watch, not $scope.watch
Have a look at this: https://jsfiddle.net/qnw8ogrk/32/

Fiddle: https://jsfiddle.net/stevenng/qnw8ogrk/33/
Markup
<div ng-app="app">
<div ng-controller="mainController">
<label ng-repeat="option in options">
<input type="radio" ng-change="picked(this)" ng-model="$parent.selected" ng-value="option"/>{{option}}
</label>
</div>
</div>
Script
var appModule = angular.module('app', []);
appModule.controller('mainController', function($scope) {
$scope.selected = 'red';
$scope.options = ['red', 'blue', 'yellow', 'green'];
$scope.picked = function($scope) {
alert('you picked: ' + $scope.selected);
}
});

Related

angularjs: forEach in ng-click

I have a problem with implementing "select All" feature for simple list:
Controller:
$scope.numbers = [{v:1},{v:2},{v:3},{v:4}];
Template:
select All
<p ng-repeat='n in numbers'>
<label>
<input type="checkbox" ng-model="n.selected">
Label: {{ n.v }}
</label>
</p>
It seems angular parser cannot process the ng-click statement:
Error: [$parse:syntax]
(...)
at relational (angular.min.js:234)
at r.equality (angular.min.js:233)
at r.logicalAND (angular.min.js:233) "<a href="" ng-click="numbers.forEach(function(v) {v.selected=true;});">"
Plunker demo:
https://plnkr.co/edit/6OZP02SZ5ZYa0iO4PBY3?p=preview
Can I implement that just in the html template or have to use the controller method?
Edit: Controller method works fine, I'm just still interested why in-place code doesn't parse though?
Try like below, numbers.forEach(function(v) {v.selected=true;}); is wrong will throw the error because numbers doesn't have forEach menthod and anonymous function will not work in ng-click
This is the best way to perform select all
<div ng-app="myApp" ng-controller="myCtrl">
<label>
<input type="checkbox" ng-model="all">
Select All
</label>
<p ng-repeat='n in numbers'>
<label>
<input type="checkbox" ng-checked="all">
Label: {{ n.v }}
</label>
</p>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.numbers = [{v:1},{v:2},{v:3},{v:4}];
});
https://fiddle.jshell.net/mspj0z65/1/
HTML
<div ng-app="myApp" ng-controller="myCtrl">
select All
<p ng-repeat='n in numbers'>
<label>
<input type="checkbox" ng-model="n.selected">
Label: {{ n.v }}
</label>
</p>
</div>
Angular script:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.numbers = [{v:1},{v:2},{v:3},{v:4}];
$scope.loop = function(){
angular.forEach(numbers, function(v) {
v.selected=true;
});
}
});
https://fiddle.jshell.net/mspj0z65/
It is better implements the method on controller as:
$scope.selectAll=function() {
$scope.numbers.forEach(function(v) {
v.selected=true
});
}
and in view use ng-click="selecAll()"
Let your view as simple as posible and make the code more readable ans ease to
understand by third parties or own in the future.
I recomend take a view to John Papa Angular style guide

get ng-model in $scope variable angularjs

I have this html code:
<select class="" ng-model="livre_selection" material-select multiple watch>
<option ng-repeat="livre in livres">{{livre.titre }}</option>
</select>
can I get the "livre_selection" in the controller and put it in a variable inside the controller so that I can use it ?
Thank you
Yes, AngularJS has two way data binding. whatever you put in the ng-model will be available in the controller through $scope object.
in your case you can access it by $scope.livre_selection
yes you can get that.follow the example.check ng-change and ng-click functions.you can do it by using both or only one function.
<html>
<body ng-app="myApp" ng-controller="yourCtrl">
<select ng-model="livre_selection" ng-change="a();" material-select multiple watch>
<option ng-repeat="livre in livres">{{livre.titre }}</option>
</select>
<input type="button" value="save" ng-click="b();">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('yourCtrl', function($scope) {
$scope.livres=[{titre:"a"}];
var selectedValue;
$scope.a = function(){
selectedValue = $scope.livre_selection;
}
$scope.b = function(){
alert(selectedValue);
}
});
</script>
</body>
</html>
Try
$scope.livre_selection = '';
Because $scope is basically a map, but more advisable yould be to use upperCase variable naming, like so:
$scope.liveReSelection = '';
After it, you will be able to access this variable in your controller.
You can read more here.
Controller
$scope.livre_selection = ""; <br>
var localVariable = "";
$scope.changeValue=function(changedVal){ localVariable = changedVal; }
HTML
Write an ng-change in the html near to the controller.
<select class="" ng-change="changeValue(livre_selection)" ng-model="livre_selection" material-select multiple watch>
<option ng-repeat="livre in livres">{{livre.titre }}</option>
</select>

Mutual effect of model variables

I have a simple GUI I would like to implement via pure AngularJS - there are two (or more) groups of checkboxes like here: http://jsbin.com/cemitubo/2/edit
Here is the code from the link below:
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js"></script>
<div ng-app="myApp" ng-controller="MyController">
<div class="group">
<input type="checkbox" ng-model="tag.aaa"/>
<input type="checkbox" ng-model="tag.ccc"/>
</div>
<div class="group">
<input type="checkbox" ng-model="tag.zzz"/>
</div>
{{tag}}
</div>
JS:
angular.module('myApp', [])
.controller('MyController', function($scope){
$scope.tag = {aaa: true};
});
Once A checkbox of one of the groups is checked all the checkboxes of the other groups should be unchecked (and the change obviously should be reflected in the model).
I tried to $watch the tag model variable and setting false to the variables of the other groups in $watch callback. The problem is that it fires the $watch callback each time tag is changed by $watch callback.
What is the proper AngularJS solution?
Thanks in advance!
Use ng-change instead $watch:
Something like:
$scope.changed = function(item, type){
console.log(item);
if((type == 'aaa' || type == 'ccc') ){
$scope.tag.zzz = !item;
}
else if(type == 'zzz'){
$scope.tag.aaa = !item;
$scope.tag.ccc = !item;
}
}
HTML
<div class="group">
<input type="checkbox" ng-model="tag.aaa" ng-change="changed(tag.aaa,'aaa')"/>
<input type="checkbox" ng-model="tag.ccc" ng-change="changed(tag.ccc,'ccc')"/>
</div>
<div class="group">
<input type="checkbox" ng-model="tag.zzz" ng-change="changed(tag.zzz, 'zzz')"/>
</div>
Demo JSBIN

AngularJs Modal set default value from rootScope

I have problem with angular modal value.
I have $rootScope and on button im opening modal which contains , and I can't set default / selected value to that
<form>
<input type="button" class="mobileUpdate" ng-click="openMobileUpdateModal()" />
<script type="text/ng-template" id="mobileModal.html">
<form name="modalForm">
<div class="modal-body">
<p>Country</p>
<select id="countryMobile" ng-model="countryMobile" class="select-styled" name="countryMobile" required>
<option ng-repeat="country in countries" value="{{country.id}}">{{country.name}}</option>
</select>
</div>
</div>
<div class="modal-footer">
<input type="button" ng-click='confirm()' value="OK"/>
<input type="button" ng-click='cancel()' value="Cancel"/>
</div>
</form>
</script>
</form>
$rootScope.openMobileUpdateModal = function () {
$rootScope.countryMobile = $rootScope.country;
var modalInstance = $modal.open({
templateUrl: 'mobileModal.html',
controller: ModalInstanceCtrl
});
};
var ModalInstanceCtrl = function ($rootScope, $modalInstance) {
$rootScope.confirm = function () {
//do something
$modalInstance.close();
};
$rootScope.cancel = function () {
$modalInstance.dismiss();
};
};
Anyone know how to send value from $rootScope to modal, and set that value as default?
Thanks
First of all there is syntax error you have double quote twise in you select tag code. Update it as below then try. And use $root in your ng-model.
<select id="countryMobile" ng-model="$root.countryMobile" class="select-styled" name="countryMobile" required>
<option ng-repeat="country in countries" value="{{country.id}}">{{country.name}}</option>
</select>
I'm not sure that I understand your problem correct but try do not use rootScope or modify and avoid rootScope modification.
If you need use some value from rootScope:
extract this value to local scope of particular controller and
after that use it
Use WATCH operator to avoid situations when you
render some value before it initialised.
<option ng-repeat> does not work in angularjs.
you should use
<select id="countryMobile" ng-model="countryMobile" class="select-styled" name="countryMobile" required ng-options="country.id as country.name for country in contries"></select>
http://docs.angularjs.org/api/ng/directive/select

Why does this state get reset?

In the following code, why $scope.text get reset when a new area is switched in? I think its value should be persisted because its defined in the top level scope.
<div ng-controller="Ctrl">
<select ng-model="selection" ng-options="item for item in items">
</select>
<hr/>
<div ng-switch on="selection" >
<div ng-switch-when="settings" ng-controller="Ctrl1">
Enter val :
<input ng-model="text" />{{text}}
</div>
<span ng-switch-when="home" ng-controller="Ctrl2">Home Span</span>
<span ng-switch-default>default</span>
</div>
</div>
Controllers:
var myApp = angular.module('myApp',[]);
function Ctrl($scope) {
$scope.items = ['settings', 'home', 'other'];
$scope.selection = $scope.items[0];
$scope.text = "Enter val";
}
function Ctrl1($scope) {
console.log('hi')
}
function Ctrl2($scope) {
console.log('hi2')
}
http://jsfiddle.net/KDWh8/
When you are working with primitive values in angular scopes, you cannot overwrite a value in a parent scope from a child scope. This is because angular uses javascript prototypal inheritance.
What you could do in this case is create an object in the parent scope, then you can update the values on that in the child scope. Because you are not overwriting the object (only properties attached to it) the references work.
"the rule of thumb is, if you use ng-model there has to be a dot somewhere." Miško Hevery

Resources