7

I am having a problem binding Angular ng-check to ng-model, that is ng-model does do not recognize the selected state of my check boxes.

Here is a description(Its a much larger code base but I have tailored to minimize code).

On page load in JavaScript I initialize my products and set the default values:

$scope.products = {}
$scope.SetProductsData = function() {
    var allProducts;
    allProducts = [
      {
        id: 1,
        name: "Book",
        selected: true
      }, {
        id: 2,
        name: "Toy",
        selected: true
      }, {
        id: 3,
        name: "Phone",
        selected: true
      }]

I have a master control in my view that list a check box for each 3 products(Book,Toy and phone):These are checked by default

<div style="float:left" ng-init="allProducts.products = {}" >
    <div ng-repeat="p in Data.products">
        <div style="font-size: smaller">
            <label><input id="divPlatorm"  ng-model="products[p.name]" ng-init="products[p.name] = true" type="checkbox"/>
                {{p.name}}</label>
        </div>
    </div>
</div>

Then a table that have the same products repeated in rows:

<div ng-repeat="line in lineProducts" ng-init="line.products = {}">
    <div id="sc-p-enc" ng-repeat="p in Data.products">
        <div id="sc-p-plat" style="font-size: smaller">
            <label id="pl-label"><input ng-checked="products[p.name]"  ng-model="line.products[p.name]"  ng-init="line.products[p.name] = true" type="checkbox"/>                                    
                {{p.name}}</label>
        </div>
    </div>
</div>

When I check/unchecked the master products the corresponding check boxes changes in the rows. So if I have 100 rows with (Book,Toy and phone) the unchecked Toy I can see where all toys are unchecked in the rows.

When I send the data to my controller I can still see all Toys = true even though they were unchecked.

If I physically go to the row then unchecked each toy and send the data to my controller Toys = False.

How can I get the check boxes selected state to change when controlled from the master check-boxes?

I have followed the post found here but I dont think this applies to my scenario: AngularJS: ng-model not binding to ng-checked for checkboxes

Community
  • 1
  • 1
Milligran
  • 3,031
  • 9
  • 44
  • 56
  • There are parts of the code missing. A fiddle/plunk would help. Other than that: you are reusing ids inside `ng-repeat`; it will result in many elements with the same id in the document. And you are using `ng-init` extensively. I believe `ng-init` inserts procedural logic in the view which is generally not a best practice. – Nikos Paraskevopoulos Oct 02 '13 at 18:01

4 Answers4

5

It seems the ng-checked in the table is binding to products[p.name], which the ng-model in your master control in the view also binding to. But the ng-model in your table is binding to another property, line.products[p.name].

I think you probably don't need ng-checked in the table since each item has its own ng-model. So you might change your table view to

<label id="pl-label"><input ng-model="line.products[p.name]" type="checkbox"/>{{p.name}}</label>

and in the controller, change the corresponding value of line.products[p.name] every time the value of products[p.name] is changed.

Ethan Wu
  • 938
  • 9
  • 17
3

I just solved this problem myself by using "ng-init" and "ng-checked" ---

  • ng-checked - 'checked' the checkbox as form was loaded
  • ng-init- bound my checkbox html value attribute to the model

There is a comment above stating that its not good to use ng-init in this manner, but not other solution was provided.

Here is an example using ng-select instead of ng-checked:

<select ng-model="formData.country"> 
<option value="US" ng-init="formData.country='US'" ng-selected="true">United States</option>
</select>

This binds "US" to model formData.country and selects the value on page load.

Don F
  • 1,963
  • 2
  • 15
  • 18
  • It's a bit late but you should be able to add `$scope.formData.country = 'US';` in your controller to perform the same functionality. – Bryce Siedschlaw Sep 10 '15 at 15:25
0

If I understand the functionality you are trying to cover the following fiddle might help you. Here is the code:

<div style="float:left" ng-app ng-init="products = [
  {
    id: 1,
    name: 'Book',
    line: 'Books',
    selected: true
  }, {
    id: 2,
    name: 'Another Book',
    line: 'Books',
    selected: true
  }, {
    id: 3,
    name: 'Toy',
    line: 'Toys',
    selected: false
  }, {
    id: 4,
    name: 'Another Toy',
    line: 'Toys',
    selected: false
  }, {
    id: 5,
    name: 'Phone',
    selected: true
  }];lineProducts = ['Toys', 'Books']" >
<div style="float:left">
    <div ng-repeat="p in products">
        <div style="font-size: smaller">
            <label>
                <input ng-model="p.selected" type="checkbox"/>
                {{p.name}}
            </label>
        </div>
    </div>
</div>
<div ng-repeat="line in lineProducts">
    {{line}}
    <div ng-repeat="p in products | filter:line">
        <div style="font-size: smaller">
            <label>
                <input ng-model="p.selected" type="checkbox"/>                                    
                {{p.name}}
            </label>
        </div>
    </div>
 </div>
</div>

Also why do you have ids in your html? With angular there is no need in ids, and considering that they are inside ng-repeats they will be ambiguous and therefore useless anyway.

I also agree with Nikos about usage of the ng-init. I used it in my jsfiddle because I am lazy, I would not use it in the production code

mfeingold
  • 7,094
  • 4
  • 37
  • 43
0

You should use ng-model there that would provide you two way binding. Checking and unchecking the value would update the value of product.selected

<input type="checkbox" ng-model="p.selected"/>
Wekerle Tibor
  • 457
  • 2
  • 7
  • 19