Paul Smith
Paul Smith

Reputation: 435

AngularJS required radio buttons needs two click events to be valid

I have a very simple form where a radio button is required to be selected in order for a form to be valid. The radio buttons are generated by ngRepeat.

As you can see from this fiddle, while the desired behavior is that when the radio button is clicked for the first time, that should validate the form (being the only element), however notice that it takes an additional click (on the same radio button or any other) to validate the form:

http://jsfiddle.net/Xsk5X/3/

What am I missing?

Upvotes: 18

Views: 17381

Answers (8)

hbear
hbear

Reputation: 97

For IONIC v1, add name="" to prevent ionic auto-generate attribute name. Then, I can change the selected item with only one click.

<ion-radio class="label-ticket" 
    ng-repeat="topic in vm.listTopic track by $index"
    ng-value="topic"
    ng-model="vm.topicSupport"
    name="">
    {{ topic.title }}
</ion-radio>

Upvotes: 0

Preston Badeer
Preston Badeer

Reputation: 2717

All the other solutions are work-arounds: All you have to do is remove the name attribute, when you use the ng-model attribute you don't need it and they conflict.

Specifying the name causes Angular to get confused because it changes the value once for the angular model and another time for the form element name.

Upvotes: 40

Justin Moore
Justin Moore

Reputation: 827

I had this problem because a colleague had copied the radio buttons in the same page and hidden them for temporary reference, so duplicate radio inputs with the same name

Upvotes: 2

Daniel
Daniel

Reputation: 922

Try adding the ng-click attribute to your radio button input.

Credit to Manny D for noting this first. Yes, this is a little hackish, but it works. E.g.,

<input type="radio" 
       name="groupName"  
       ng-model="editObject.Property"                             
       ng-value="someValue"
       ng-click />

Upvotes: 1

user2680352
user2680352

Reputation: 1

The problem of the scope not getting updated still occurs in 1.1.5

A simple work around is to just add <span ng-show="false"> {{name}} </span>

Fiddle: http://jsfiddle.net/jonyschak/xaQJH/

Upvotes: 0

Alfonso
Alfonso

Reputation: 147

Some times the $digest cycle dosen't $apply(fn) because you have two o more instances. For fix this you need $apply this trick manually, so put this in your directives:

angular.('myApp',[])
.directive('ngRadioExtend', ['$rootScope', function($rootScope){
        return {
            require: 'ngModel',
            restrict: 'A',
            link: function(scope, iElm, iAttrs, controller) {
                iElm.bind('click', function(){
                    $rootScope.$$phase || $rootScope.$apply()
                });
            }
        };
    }])

and use it as:

<input type="radio" name="input_name" ng-model="some" value="F" ng-required="true" ng-radio-extend>

<input type="radio" name="input_name" ng-model="some" value="M" ng-required="true" ng-radio-extend>

DONE it's the correct way!

Upvotes: 1

Gilad Peleg
Gilad Peleg

Reputation: 2010

Seems like an AngularJS 1.0.3 $scope.$apply update problem. Tested your exact Fiddle in 1.0.2 (check it out yourself) and it works the way you expect it too.

It doesn't seem like there's anything wrong with your code, just that $scope.$apply(or $digest) isn't working as expected on the first select.

A very simple fix is to force the $scope to also update on every select, try changing the following line of code in your form:

<p>Favorite Beatle</p>

change it too:

<p>Favorite Beatle: {{name}}</p>

And you will see how myForm.$invalid is updated even after the first click.

I would try it out with the latest AngularJs version and let us know if that happens there too. Another solution I can think of it setting the default selected radio, which will cause myForm.$invalid to be false from the beginning. you can do this by adding the following line in your controller code:

$scope.name = "John";

or any default name you want.

Upvotes: 1

Oddman
Oddman

Reputation: 3959

The reason why this is breaking - is because you're setting all radio boxes to be required. As a result, depending on how you write it - angularjs is saying it's invalid because not all have been selected at some point.

The way around this is to do something like the following:

Using checkboxes and required with AngularJS

(check the 1st and 2nd answers). This will resolve your problem.

Upvotes: 1

Related Questions