Join the Stack Overflow Community
Stack Overflow is a community of 6.5 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have two checkboxes in my Angular JS form, like this...

<input id="isBackground" type="checkbox" ng-model="addTemplate.data.isBackground">
<input id="repeats" type="checkbox" ng-model="addTemplate.data.repeats">

If I tick both boxes then write the $scope to the console, both values are set to true, but if I only tick one of them then one appears in the $scope (set to true) and the other one is simply missing. It should be in the $scope and set to 'false' surely?

share|improve this question
up vote 6 down vote accepted

If a property assigned to ng-model is undefined, ng-model will automatically create the property after the value is changed for the first time. It means from second time on, you will see both properties.

DEMO

To avoid this, you could set the default false for both properties:

app.controller('MainCtrl', function($scope) {
  $scope.isBackground = false;
  $scope.repeats = false;
});

DEMO

share|improve this answer
    
Thanks Khanh, I'm surprised they made it that way, and it does cause some problems, but your solution worked. I wonder why they chose to bind it to the model only after you've checked it then unchecked it. Nobody would do that with a checkbox and having to set a default on the scope makes it very difficult to create dynamic form. Thanks for your help though. – jonhobbs Jan 26 '14 at 12:50
    
You're referencing their ids for each input, is that intended? – user393219 Jun 17 '15 at 15:13
    
@Shawn Strickland: no, the ids are not necessary, copied and pasted from the question, forgot to remove them. – Khanh TO Jun 18 '15 at 13:40
    
neat but doesn't really work if the check boxes are created dynamically – Astronaut Mar 8 at 9:30
    
@Astronaut: What do you mean by "created dynamically"? Do you use ng-repeat to generate the checkboxes dynamically or just insert a html snippet. In later case, you need to compile your snippet ($compile service) – Khanh TO Mar 9 at 12:48

You can use ngTrueValue, and ngFalseValue. I have use 1/0 use it accordingly

<input id="isBackground" ng-true-vale="1" ng-false-value="0" type="checkbox" ng-model="addTemplate.data.isBackground">
<input id="repeats" ng-true-vale="1" ng-false-value="0" type="checkbox" ng-model="addTemplate.data.repeats">

From Docs

ngTrueValue: The value to which the expression should be set when selected.

ngFalseValue: The value to which the expression should be set when not selected.

OR

You can use ngChecked, If the expression is truthy, then special attribute "checked" will be set on the element

<input id="isBackground" ng-checked="addTemplate.data.isBackground == true" type="checkbox" ng-model="addTemplate.data.isBackground">
<input id="repeats" ng-checked="addTemplate.data.repeats == true" type="checkbox" ng-model="addTemplate.data.repeats">
share|improve this answer
1  
I tried setting both to ng-false-value="false", but if you don't tick them they don't appear in the model. If you tick them both and untick them, then they appear in the model. – jonhobbs Jan 26 '14 at 12:17
1  
I want them both to appear in the model, even before you have ticked or un-ticked them. – jonhobbs Jan 26 '14 at 12:19
    
Does that work 2 ways though? I know it will check the box if the model is set to true, but by default will it put it in the model and set it to false before the user interacts with the checkbox. I'm not sure you understand my original question. – jonhobbs Jan 26 '14 at 12:26
1  
Sorry Satpal but that still doesn't work. If I submit the form without ticking either of them then they are missing from the model. If I tick both of them then they both appear in the model. It is like they are defaulting to null instead of false. – jonhobbs Jan 26 '14 at 12:42
1  
Thanks for your help Satpal, but Khanh seems to have found the problem. – jonhobbs Jan 26 '14 at 12:51

A more flexible solution is to set a ng-init value, this works for dynamic proprieties as well as fixed, something that the accepted solution does not do.

<div class="checkbox">
    <label><input type="checkbox" value="" ng-init="formData[field.checkBox]=false" ng-model="formData[field.checkBox]">{{field.name}}</label>
</div>
share|improve this answer
    
Love it - +1 dynamic properties. – Nick Grealy Sep 21 at 14:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.