DeLac
DeLac

Reputation: 1122

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

Upvotes: 0

Views: 3521

Answers (3)

Larry Foulkrod
Larry Foulkrod

Reputation: 2294

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.

Upvotes: 1

Pankaj Ladhar
Pankaj Ladhar

Reputation: 155

    <div class="btn-group btn-group-justified" 
             data-toggle="buttons">

data-toggle="buttons" is making radio buttons hidden. If you remove this, it will be shown

Upvotes: -1

Manegan
Manegan

Reputation: 26

I've made it work:

<div ng-app="myApp">
  poiType is initialized to 0, so the first button should be selected
  <div ng-controller="TodoCtrl"
       style="margin-bottom: 5px; padding: 5px; width:100%;">
    <div class="btn-group btn-group-justified" 
         data-toggle="buttons">
       <label class="btn btn-default">
          <input type="radio"  ng-value="TYPE_POI"
               ng-model="poiType" 
               ng-change="popup()"/>POI
        </label>
        <label class="btn btn-default">
           <input type="radio" autocomplete="off" 
                  ng-value="TYPE_TRIP ||
                            TYPE_WAYPOINT "
                  ng-model="poiType"  
                  ng-change="popup()"/>itinerari
        </label>
        <label class="btn btn-default">
          <input type="radio" autocomplete="off"  
                 ng-value="TYPE_EVENT"
                 ng-model="poiType" 
                 ng-change="popup()"/>eventi
        </label>    
     </div>         
   </div>         
</div>

You need to create a module for your angular app to refer to, here I called it myApp and declared it in the main div (usually, you want to do it in the body tag). Then you can create a controller and use the scope module to initialise data then use it as shown above. Here is the js.

var myApp = angular.module("myApp", []);

myApp.controller("TodoCtrl", function ($scope) {
    var that = $scope;

    $scope.poiType = 0;

    $scope.TYPE_POI = 0;
    $scope.TYPE_TRIP = 1;
    $scope.TYPE_WAYPOINT = 2;
    $scope.TYPE_EVENT = 3;

    $scope.popup = function () {
        alert(that.poiType);
    };
});

jsfiddle

Upvotes: 0

Related Questions