javascriptangularjsangular-ngmodelangularjs-ng-value

Angular ng-value doesn't work with input radio


I have 3 radio inputs bound to ctrl.poiType , where ctrl is the controller and poiType is an integer. ctrl.poiType can have one of the 3 values specified by four constants (ctrl.TYPE_TRIP, ctrl.TYPE_EVENT, ctrl.TYPE_POI).

So I've created three input radio, using ng-model and ng-value like this:

<label class="btn btn-default">
    <input type="radio" autocomplete="off" 
           ng-value="ctrl.TYPE_TRIP"
           ng-model="ctrl.poiType"  
           ng-change="ctrl.alert()"/>itinerari
</label>

The radio should be checked if the value of ng-model is equal to ng-value, but it's not working. I don't know why.

[UPDATE] This is the right JS Fiddle of the example


Solution

  • I'm assuming the problem you are trying to solve is to have the selected button appear active when you click it. Since you are using the Bootstrap styles without using the Bootstrap javascript component you will need to make this work yourself within Angular.

    To make the radio button appear "checked" you must apply the active style to the label's class list.

    Preselected options need .active

    For preselected options, you must add the .active class to the input's label yourself.

    The way to modify an element's class list dynamically in Angular is to use ng-class. You'll need to read the documentation for the directive as there are several options to how to make it work.

    I've updated your example to make use of the ng-class directive and it is now making the button appear active when you click it.

    I wouldn't recommend doing it exactly like this, especially the part about having your controller be responsible for CSS classes, but this is a good starting point for you to figure out the best way to do it in your situation.

    View

    <div>poiType is initialized to 0, so the first button should be selected
        <div ng-controller="TodoCtrl as ctrl" style="margin-bottom: 5px; padding: 5px; width:100%;">
            <div class="btn-group btn-group-justified">
                <label ng-class="ctrl.class(ctrl.TYPE_POI)">
                    <input type="radio" ng-value="ctrl.TYPE_POI" ng-model="ctrl.poiType" />POI</label>
                <label ng-class="ctrl.class(ctrl.TYPE_TRIP)">
                    <input type="radio" autocomplete="off" ng-value="ctrl.TYPE_TRIP" ng-model="ctrl.poiType" />itinerari</label>
                <label ng-class="ctrl.class(ctrl.TYPE_EVENT)">
                    <input type="radio" autocomplete="off" ng-value="ctrl.TYPE_EVENT" ng-model="ctrl.poiType" />eventi</label>
            </div>ctrl.poiType = {{ctrl.poiType}}</div>
    </div>
    

    Controller

    angular.module('epoiApp', [])
    
        .controller('TodoCtrl', function () {
        this.poiType = 0; // first button should be selected
    
        this.TYPE_POI = 0;
        this.TYPE_TRIP = 1;
        this.TYPE_WAYPOINT = 2;
        this.TYPE_EVENT = 3;
        this.class = function (poiType) {
            if (poiType == this.poiType) {
                return 'btn btn-default active';
            } else {
                return 'btn btn-default';
            }
        }
    });
    

    Here is a link to the working fiddle.