AngularJS Radio group not setting $dirty on field
Asked Answered
C

2

1

I'm trying to use Angular's $dirty flag to submit only the changed fields in a form.

When I ran into radio button groups, I was missing the changes in the list of changed fields. I have a fiddle that reproduces the problem I am seeing.

<div ng-app="form-example" ng-controller="MainCtrl">
    <form name="form" novalidate>
        <input type="radio" name="myRadio" ng-model="myRadio" value="one" required>One<br />
        <input type="radio" name="myRadio" ng-model="myRadio" value="two" required>Two<br />
        <input type="radio" name="myRadio" ng-model="myRadio" value="three" required>Three<br />
        <input type="radio" name="myRadio" ng-model="myRadio" value="four" required>Four<br />
        <input type="radio" name="myRadio" ng-model="myRadio" value="five" required>Five<br /><br />
       Form $dirty: {{form.$dirty}}<br />
       Field $dirty: {{form.myRadio.$dirty}}<br />
       Value: {{myRadio}}
    </form>
</div>

The field's $dirty flag will only change when the last radio button is clicked even though the form $dirty updates properly.

Am I missing something fundamental here? and is there a workaround for this behavior?

Cilium answered 26/2, 2014 at 20:39 Comment(2)
Does the novalidate attribute have anything to do with the FormController not setting input states?Bobbi
I've tried both with and without, novalidate just disables HTML5 validation, and only on submit.Cilium
T
4

Each ng-model actually instantiates a controller. When you click any radio button, the controller sets $dirty field to true and sets form.$dirty to true.

The problem is that form.myRadio holds the reference to the last radio button's model.

As a workaround you can use nested forms with ng-form. See here: http://jsfiddle.net/UM578/

Takashi answered 26/2, 2014 at 21:23 Comment(1)
Thanks Mr_Mig, and to anyone else with this issue, give the form the same name as your field, and change the inner input names (I appended .inner)Cilium
C
0

I gave each radio input a unique name. Maybe you can give a broader view of what you are trying to do.

<div ng-app="form-example" ng-controller="MainCtrl">
<form name="form" novalidate>
    <input type="radio" name="myRadio1" ng-model="myRadio" value="one" required>One<br />
    <input type="radio" name="myRadio2" ng-model="myRadio" value="two" required>Two<br />
    <input type="radio" name="myRadio3" ng-model="myRadio" value="three" required>Three<br />
    <input type="radio" name="myRadio4" ng-model="myRadio" value="four" required>Four<br />
    <input type="radio" name="myRadio5" ng-model="myRadio" value="five" required>Five<br /><br />
   Form $dirty: {{form.$dirty}}<br />
   Field 1 $dirty: {{form.myRadio1.$dirty}}<br />
   Field 2 $dirty: {{form.myRadio2.$dirty}}<br />
   Field 3 $dirty: {{form.myRadio3.$dirty}}<br />
   Field 4 $dirty: {{form.myRadio4.$dirty}}<br />
   Field 5 $dirty: {{form.myRadio5.$dirty}}<br />
   Value: {{myRadio}}
</form>

Confessedly answered 26/2, 2014 at 20:50 Comment(2)
I'm trying to automate the collection of the dirty elements in a form, and having HTML names different than the model's name means I can't directly check that the whole group's value has changed with (formName[fieldName].$dirty).Cilium
The only thing I can think to work around this is check against what the value of $scope.myRadio rather than checking against $dirty = true from each input.Confessedly

© 2022 - 2024 — McMap. All rights reserved.