AngularJS radio buttons not marked $dirty until last button selected

angularjs, radio-button, validation

Solution

You either need to give each radio button input a different name, or you need to wrap each radio button in an ng-form (each of which have a different name). If you use two inputs with the same name in the same form, only the last one will be bound to the property on the FormController. If you use different names, then each input will have its own property on the FormController.

Example with different names for each radio button: http://jsfiddle.net/BEU3V/

<form name="form" novalidate>
    <input type="radio" 
        name="myRadio1" 
        ng-model="myRadio" 
        ng-click="" 
        value="Rejected"
        required>Rejected<br />
    <input type="radio" 
        name="myRadio2" 
        ng-model="myRadio"
        ng-click=""
        value="Approved"
        required>Approved<br />
   Form $dirty: {{form.$dirty}}<br />
   Field1 $dirty: {{form.myRadio1.$dirty}}<br />
   Field1 $dirty: {{form.myRadio2.$dirty}}<br />
   Value: {{myRadio}}
</form>

Example wrapping with ng-form: http://jsfiddle.net/39Rrm/1/

<form name="form" novalidate>
    <ng-form name="form1">
    <input type="radio" 
        name="myRadio" 
        ng-model="myRadio" 
        ng-click="" 
        value="Rejected"
        required>Rejected<br />
        </ng-form>
    <ng-form name="form2">    
    <input type="radio" 
        name="myRadio" 
        ng-model="myRadio"
        ng-click=""
        value="Approved"
        required>Approved<br />
        </ng-form>
   Form $dirty: {{form.$dirty}}<br />
   Field1 $dirty: {{form.form1.myRadio.$dirty}}<br />
   Field2 $dirty: {{form.form2.myRadio.$dirty}}<br />
   Value: {{myRadio}}
   </form>

If you'd like a single check for the radio group, you can wrap all the radio buttons in their own ng-form and call it something like name="radioGroup".

http://jsfiddle.net/6VVBL/

<form name="form" novalidate>
    <ng-form name="radioGroup">
    <input type="radio" 
        name="myRadio1" 
        ng-model="myRadio" 
        ng-click="" 
        value="Rejected"
        required>Rejected<br />
    <input type="radio" 
        name="myRadio2" 
        ng-model="myRadio"
        ng-click=""
        value="Approved"
        required>Approved<br />
        </ng-form>
   Form $dirty: {{form.$dirty}}<br />
   Group $valid: {{form.radioGroup.$valid}}<br />
   Group $dirty: {{form.radioGroup.$dirty}}<br />
   Value: {{myRadio}}
   </form>

Problem

I created this simple example: http://jsfiddle.net/5Bh59/. If you switch between AngularJS 1.2.1 and 1.1.1, you'll see the radio buttons don't work properly in either version. If you watch the radio button's `$dirty` field, 1) for version 1.1.1, it will only be set when the first button is clicked, and 2) for version 1.2.1, it will only be set when the last button is clicked. I read this answer: AngularJS Radio group not setting $dirty on field but I don't really understand the answer. Not only that but the fiddler example demonstrates the same behavior. So, is this a bug in AngularJS and how can I work around it?

Original source