15
votes

In my HTML page, I have two sets of Boolean based radio buttons: Labeled: "Yes" and "No" / Values: True and False respectively. I'm populating a full form from a PostgreSQL database table to allow the authenticated user to view the form with populated data and edit the populated fields including the radio buttons, then save the form which will save the data to the DB. All of the other text fields populate without issue; it's both collection of radio buttons I am having an issue with pre-checkmarking the radio buttons.

The below does not pre-populate the checked on front end (but adds the correct attribute of checked in HTML source):

    <input id="billing-no" type="radio" name="billing" ng-model="person.billing" value="FALSE" ng-checked="person.billing == 'false'" />
    <input id="billing-yes" type="radio" name="billing" ng-model="person.billing" value="TRUE" ng-checked="person.billing == 'true'" />

However, this does check the correct radio button on load:

    <input id="billing-no" type="radio" name="billing" value="FALSE" ng-checked="person.billing == 'false'" />
    <input id="billing-yes" type="radio" name="billing" value="TRUE" ng-checked="person.billing == 'true'" />

Note: I needed to check against the string boolean value in the directive ng-checked since the boolean value always comes back as a string from PostgreSQL. This, apparently, was a part of PostgreSQL's design when querying data from columns that have boolean data types.

When adding the ng-model directive, the radio button no longer is checked (at least in the rendered browser view). The odd part is that I looked at the source and it clearly checks the correct one. What's even more odd, is that I have to click on the radio button twice to 'check' it. I've tested this in latest version of Chrome, FF, and IE and it all results in the same issue.

The question is: when adding the ng-model directive, why would the HTML source add 'checked' in the radio button attribute, but seemingly does not mark the radio button? Furthermore, why would I have to click twice on the radio button that IS supposed to be checked?


Solution: To fix this, I removed the ng-checked directive from the radio buttons and only used ng-model as suggested by @Cypher and @aet. I then replaced the attribute value with the directive ng-value "true" & "false". After, I set the values in the controller.

HTML

<input id="billing-no" type="radio" name="billing" ng-model="person.billing" ng-value="false" />
<input id="billing-yes" type="radio" name="billing" ng-model="person.billing" ng-value="true" />

Angular JS

app.controller('peopleCtrl', function($scope, peopleFactory){
    ...
    peopleFactory.getPerson(personParams).then(function(data){
        $scope.person = data;
        /* moved from ng-checked */
        $scope.person.billing = data.billing == 'true';
    });
    ...
};
4
You really should not need to use ng-model and ng-checked at the same time. ng-checked is more like for a read-only checkbox thats reflecting some other value. If you just want it to start out checked set the model to true.aet

4 Answers

36
votes

I think you should only use ng-model and should work well for you, here is the link to the official documentation of angular https://docs.angularjs.org/api/ng/input/input%5Bradio%5D

The code from the example should not be difficult to adapt to your specific situation:

<script>
   function Ctrl($scope) {
      $scope.color = 'blue';
      $scope.specialValue = {
         "id": "12345",
         "value": "green"
      };
   }
</script>
<form name="myForm" ng-controller="Ctrl">
   <input type="radio" ng-model="color" value="red">  Red <br/>
   <input type="radio" ng-model="color" ng-value="specialValue"> Green <br/>
   <input type="radio" ng-model="color" value="blue"> Blue <br/>
   <tt>color = {{color | json}}</tt><br/>
</form>
7
votes

I solved my problem simply using ng-init for default selection instead of ng-checked

<div ng-init="person.billing=FALSE"></div>
<input id="billing-no" type="radio" name="billing" ng-model="person.billing" ng-value="FALSE" />
<input id="billing-yes" type="radio" name="billing" ng-model="person.billing" ng-value="TRUE" />
3
votes

[Personal Option] Avoiding using $scope, based on John Papa Angular Style Guide

so my idea is take advantage of the current model:

(function(){
  'use strict';
  
   var app = angular.module('way', [])
   app.controller('Decision', Decision);

   Decision.$inject = [];     

   function Decision(){
     var vm = this;
     vm.checkItOut = _register;

     function _register(newOption){
       console.log('should I stay or should I go');
       console.log(newOption);  
     }
   }

     
     
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div ng-app="way">
  <div ng-controller="Decision as vm">
    <form name="myCheckboxTest" ng-submit="vm.checkItOut(decision)">
 <label class="radio-inline">
  <input type="radio" name="option" ng-model="decision.myWay"
                           ng-value="false" ng-checked="!decision.myWay"> Should I stay?
                </label>
                <label class="radio-inline">
                    <input type="radio" name="option" ng-value="true"
                           ng-model="decision.myWay" > Should I go?
                </label>
  
</form>
  </div>
  
</div>

I hope I could help ;)

1
votes

Please explain why same ng-model is used? And what value is passed through ng- model and how it is passed? To be more specific, if I use console.log(color) what would be the output?