AngularJS: checked attribute in checkbox doesn't work - javascript

Here is my code:
<body ng-app="app">
<div ng-controller="TestController">
<input type="checkbox" checked ng-repeat="num in array track by $index" ng-model="array[$index]" />
</div>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('TestController', function ($scope) {
$scope.array = [1, 2, 3, 4];
});
</script>
I especially add checked attribute to each <input> tag, for the checkbox could checked by default. But the result is none of the four checkbox is checked. Why?
I know if I add ng-checked="num" attribute could make the checked work, But I still wondering why the natural checked arrtibute doesn't work.

From angular docs
By default, ngModel watches the model by reference, not value.
When you say array[$index] it gives integer value which is you model name And its wrong
Please do it in this way
<div ng-controller="TestController">
<input type="checkbox" checked ng-repeat="num in array track by $index" ng-model="array[$index].checked" title="{{array[$index].val}}" />
</div>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('TestController', function ($scope) {
$scope.array = [{val:1,checked:true},{val:2,checked:false},{val:3,checked:true},{val:4,checked:true},{val:5,checked:false}];
});
</script>

ng-model="array[$index]" sets the dom checked property to false

As far as why checked doesn't work: when angular binds to the checkbox using either ng-checked or ng-model, it sets the checked attribute so that the checkbox looks correct in the browser - it doesn't care what the checked attribute is when it first binds.

You shouldn't combine checked with ng-model. Same applies for ng-checked with ng-model. Both modify the checkbox checked state which leads to unpredictable behavior.
If you want your checkbox to be checked by default do it via the ng-model directive.
The structure you are using seems a little bit weird. You checkboxes aren't checked because angular can't match the value.
By default using ng-model on a checkbox will yield true and false in the ng-model value when the user interacts with it. You can change that by using ng-true-value and ng-false-value. Check angular documentation.
If you add let's say ng-true-value="2" to your checkboxes then the second one will be initially selected because it starts with the value 2.

Related

Angular Js- Is there any way to generate dynamically checkbox which are also preselected?

I have been wandering for two to three hours and I found chunks of relevant questions but my scenario just take a little curve. I have to generate a number of checkboxes which obviously would be generated through ng-repeat. How can I show the preselected values which I am getting from Api. Here is the kind of data I am receiving.
Pre-selected data
$scope.categoriess = [{"id":1,"name":"Garden Cleaning"},{"id":3,"name":"Home Cleaning"}].
and this is the data over which I am using ng-repeat.
ng-repeat data
$scope.categories = [{"id":1,"name":"Garden Cleaning"},{"id":2,"name":"Gutter Cleaning"},{"id":3,"name":"Home Cleaning"},{"id":4,"name":"Pool Cleaning"}
HTML
<div ng-repeat="cats in categories">
<input type="checkbox" ng-model="categoriess.id[cats.id]">
<label>{{cats.name}}</label>
</div>
Now how would i tell ng-repeat to check the preselected data, plus if I want to check few more boxes they should also be checked and I want them to store in $scope.categoriess. I have tried a number of solution either with ng-checked or by make a function call in ng-checked I got no expected results.
Why don't u format your data to have another property, something like
{"id":1,"name":"Garden Cleaning", "checked": true}
Such way, when u iterate through the data, you can check the checkbox
<div ng-repeat="cats in categories">
<input type="checkbox" ng-checked="cats.checked">
<label>{{cats.name}}</label>
</div>
I saw this but i did not know how it works god it saved my life. see this checklist-model. Its so simple , no need to use ng-checked or something dynamic , preselected and gets updated easily
[1]: http://jsfiddle.net/iem_usman/v3k6pwrj/1/
Change your html like this :
<div ng-repeat="cats in categories">
<input type="checkbox" ng-model="categoriess.id[cats.id]" ng-checked="isChecked(cats.id);">
<label>{{cats.name}}</label>
</div>
Add this function in your controller :
$scope.selectedCategoriess = [{"id":1,"name":"Garden Cleaning"},{"id":3,"name":"Home Cleaning"}].
$scope.isChecked = function(id){
for (var i = 0; i < $scope.selectedCategoriess.length; i++) {
if ($scope.selectedCategoriess[i].id == id) {
return true;
}
}
return false;
}
If id is available checked value will be "true".

Angular ng model requires 2 click when using ng true and ng false

I'm using checkbox with ng model and ng-true-value and ng-false-value.
It works fine but when its value comes 1 and it checked by default then it will take 2 clicks to change the value.
Is there any way to do it with first click
Code Example :
<input type="checkbox" ng-checked="CreateUpdateCat.IsDiscussionAllowed=='1'" ng-model="CreateUpdateCat.IsDiscussionAllowed" ng-true-value="1" ng-false-value="2" >
Controller Code :
angular.forEach($scope.CategoryData,function(v,k){
if(v.id == id)
{
$scope.CreateUpdateCat = {IsDiscussionAllowed:v.IsDiscussionAllowed,Name:v.Name};
};
});
here is plunkr url : https://plnkr.co/edit/JApepZfvNrlqDj9vine0?p=preview
value is 1 by default but checkbox is not showing checked
Either use ng-checked or ng-model otherwise angular will get confused to do it. and it may be possible that you will get unpredicted results.
Do use only one directive ng-checked or ng-model
ng-checked should not be used with ng-model other wise you will get unexpected bihavior,
ng-check docs: https://docs.angularjs.org/api/ng/directive/ngChecked
either use
<input type="checkbox" ng-model="checkboxModel.value"
ng-true-value="'YES'" ng-false-value="'NO'">
OR
<input type="checkbox" ng-checked="checkboxModel.value"
ng-true-value="'YES'" ng-false-value="'NO'">
Try to put your input like this
<input type="checkbox" ng-model="CreateUpdateCat.IsDiscussionAllowed" ng-true-value="'1'" ng-false-value="'2'">
On your plunker, de scope CreateUpdateCat values are strings.
Some times angualrjs scope stays dirt, you may want to use this:
$timeout(function(){
angular.forEach($scope.CategoryData,function(v,k){
if(v.id == id){
$scope.CreateUpdateCat = {IsDiscussionAllowed:v.IsDiscussionAllowed,Name:v.Name};
};
});
});
This way the model updates itself to the dom element's valeue

Difference between ng-model and angular expression - {{}}

{{}} is working fine but ng-model is not, at the same place.
I am using the following html-
<body ng-app="crud">
Gray input fields will not be visible.
<div ng-controller="ctrl">
<input type="text" value="sdf" ng-model="asdf"/>
<h1 ng-model="asdf"></h1> <!-- this doesn't work-->
<h1>{{asdf}}</h1> <!-- this work-->
</div>
</div>
</body>
asdf is defined in this js app like this
var app = angular.module("crud", []);
app.controller("ctrl", ['$scope', function($scope) {
$scope.asdf="ankur";
}]);
Can someone explain why is it so ?
The ng-model directive is to be used on the input fields such as input, select for two way data binding and to get an input from a user.
Where as the one way data binding expression {{}} or ng-bind directive is used to output the data in the view.
var app = angular.module("crud", []);
app.controller("ctrl", ['$scope', function($scope) {
$scope.asdf="ankur";
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="crud">
Gray input fields will not be visible.
<div ng-controller="ctrl">
<input type="text" value="sdf" ng-model="asdf"/>
<h1 ng-bind="asdf"></h1>
<h1>{{asdf}}</h1>
</div>
</div>
Use ng-bind for display purposes, instead of ng-model.
<h1 ng-bind="asdf"></h1>
You only want to use ng-model when binding to an element that will be editing the variable, such as a text field.
From documentation:
The ngModel directive binds an input, select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
You are trying to use it on a <h1>. Use ng-bind instead.
According the doc
the ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.
so you will not use it for display an H1
For the brackets they will be dirty checked and refreshed in every $digest, even if it's not necessary. So it's slower. Plus thez may appear while your angularjs is bootstrapping
ng-model : This directive binds the values of AngularJS application data to HTML input controls.
{{}} This use For Printing purpose only. you can put expression also like {{2*2}} it prints 4
Refer This for study basic syntax https://angularjs.org/

HTML input has both {{}} and ng-model

I have a form which contains two input fields, I want to sync the next input field when user is typing in the first input field by default, and user can edit the second field as they like, below code works fine:
<input type="text" ng-model="name">
<input type='text' value='{{name}}'>
<button ng-click='submit()'>submit</button>
However, to be able to get the value of second field, I need to put ng-model to the second field, and once I put ng-model, it won't sync anymore.
This is the example
How should I get the second field's value if I don't put a ng-model to it.
Thank you.
You can use ng-change. When user changes input 1 the ng-change method will be called and input2 will be updated .but when user change input 2 nothing will be called .
<DIV ng-app='app'>
<form ng-controller='myController'>
<input type='text' ng-model='name' ng-change="callMe()"/>
<input type='text' ng-model="name2" />{{name2}}
</form>
</DIV>
and controller js
var app = angular.module('app', []);
app.controller('myController', function($scope){
$scope.callMe =function(){
$scope.name2=$scope.name;
}
//$scope.name
//$scope.name2
})
update fiddle example
You could use the $scope.$watch Method for your needings.
I have updatet your fiddle.
What i did is easy, everytime the model changes, the $watch will be called with the new value of the model, then you just need to copy the value into the second model.
First approach that came to my mind was to ng-bind a property with a setter that would do what you want:
<input type='text' ng-model='nameModel' />
then
app.controller('myController', function($scope) {
Object.defineProperty($scope, 'nameModel', {
get: function() { return $scope.name1; },
set: function(x) { $scope.name1 = $scope.name2 = x; }
});
});
This causes any edit to nameModel to affect both name1 and name2.
Fiddle
You could do a similar wrapper around name2 to track whether it has ever been modified (dirty/pristine), and have nameModel only change scope.name2 if it is pristine.
Fiddle with better user experience
(If you're using Angular forms, it tracks the field status for you, so you could directly look at form.name2.$pristine.)
It seems that what you need is to set the value to the scope variable.
So your code would then look like this:
<input type="text" ng-model="name">
<input type='text' value="{{name}}" ng-model="somethingelse">
<button ng-click='submit()'>submit</button>
Hope that helps.

AngularJS checkbox model value is undefined

I have a problem where I'm attempting to post the value of a checkbox in my model to the server and as the checkbox has not been interacted with on the form, angular seems to have not assigned it a value, when I ask for the value of the checkbox it comes back as undefined.
Here is my markup:
<div class="form-group">
<input id="templateDisable" type="checkbox" ng-model="template.disabled" />
<label for="templateDisable">Disabled</label>
</div>
And here's a reduced version of my save action on my controller:
$scope.save = function (form) {
if (form.$valid) {
var formData = new FormData();
// this is the problem line of code
formData.append("disabled", $scope.template.disabled);
// ... some other stuff
}
};
Actually, ticking then unticking the checkbox before I hit the save action results in the template.disabled property being false, which is what I would have expected without any manual intervention.
I've seen other related questions, e.g. AngularJS: Initial checkbox value not in model but surely stuff like a simple checkbox should be baked in? I shouldn't have to be writing directives to manage checkboxes surely?
This is per design. If you want a default value on your model than you should initialise it inside the controller (recommended), or make use of ng-init.
app.controller('AppController',
[
'$scope',
function($scope) {
$scope.template = {
disabled = false
};
}
]
);
<div class="form-group">
<input type="checkbox" ng-model="template.disabled" ng-init="template.disabled=false" />
<label>Disabled</label>
</div>
The following will always set the state back to "unchecked" when the page is loaded (or refreshed). In other words it will overwrite the user's actual selection whenever the page is refreshed.
<input type="checkbox" ng-model="template.disabled"
ng-init="template.disabled=false" />
If, however, you want the checkbox state set to a default state initially and you also want it to remember user interactions, then the following is what you want.
<input type="checkbox" ng-model="template.disabled"
ng-init="template.disabled = template.disabled || false" />

Categories

Resources