1

I'm trying to get AngularJS to repeated sets of the same type of input radio fields.

Example:

<form>
     <ul id="group1">
         <li><input type='radio' name='optionRadio'></li>
         <li><input type='radio' name='optionRadio'></li>
     </ul>
     <ul id="group2">
         <li><input type='radio' name='optionRadio'></li>
         <li><input type='radio' name='optionRadio'></li>
     </ul>
</form>

AngularJS I have:

<form name='testForm'>
    <ul ng-repeat='field in fields' ng-form='subForm'>
        <li><input type='radio' ng-model='subForm.optionRadio' name='optionRadio'>field.name</li>
    </ul>
</form>

The problem is when I click the radio button, it will deselect the the radio in another group.

I know the issue is name = optionRadio, but I'm trying to take advantage of $invalid from the form testForm.

If I remove name='optionRadio', I loose track of which form item needs to be highlighted for errors.

I also tried doing separate form tags, but I was having troubles with ng-repeat and form tags.

I also tried appending $index to the name, but the form object takes in the value literally.

Any suggestions on how to do this properly would be much appreciated.

EDIT: http://jsfiddle.net/HB7LU/207/

I've made a jsfiddle. I found a solution, that will work, but won't make use of the form validation.

I can get the same result of having an error message, by checking if the model has a value. The other option is to write a custom directive for validation, then check the sub form for the specific error I'm looking for.

Example:

 <input radioCheck type='radio' name='optionRadio'/>
 <span ng-show='subForm.$error.radioCheck'>Radio check error</span>
2
  • Can you post your model structure for fields? Created a plunkr for messing around but my ul gets repeated and my outputted html structure differs. Commented Aug 14, 2013 at 16:26
  • I second the previous comment. No way to give advice on this without knowing what the "fields" structure is. Commented Aug 14, 2013 at 18:35

1 Answer 1

1

Rather than using $invalid property on the model controller you can use the $invalid property on the form controller. i.e. change <span ng-show="subform.inputRadio.$invalid">Error!!!! missing stuff</span> to <span ng-show="subform.$invalid">Error!!!! missing stuff</span>

I ran into a similar problem with a custom directive I wrote to display validation classes when using nested repeats. The custom directive couldn't use the input name because they cannot be dynamic, so this wouldn't work:

<ul validation-class-for="choice">
    <li ng-repeat="choice in question.choices">
        <label>
            <input type="radio" name="choice" value="{{choice.text}}"
                   ng-model="$parent.response.choices" required/>
            {{choice.text}}
        </label>
    </li>
</ul>

with this custom directive:

angular.module('ngQuestionnaires.validationClassFor', [])
    .directive('validationClassFor', function () {
        return {
            require: '^form',
            link: function (scope, element, attributes, formController) {
                var hasError = 'has-error',
                    hasSuccess = 'has-success';
                scope.$watch(function () {
                    var controller = formController[attributes.validationClassFor] || formController,
                        state;
                    if (controller.$invalid && controller.$dirty) {
                        state = hasError;
                    } else if (controller.$valid && controller.$dirty) {
                        state = hasSuccess;
                    }
                    return state;
                }, function (newState, oldState) {
                    switch (newState) {
                    case hasError:
                    case hasSuccess:
                        element.removeClass(oldState).addClass(newState);
                        break;
                    default:
                        element.removeClass(hasError).removeClass(hasSuccess);
                        break;
                    }
                });
            }
        };
    });

I fixed the problem by using a nested form, removing the name attribute from the radio input, and removing the value from validation-class-for, like this:

<ul validation-class-for ng-form="choiceForm">
    <li ng-repeat="choice in question.choices">
        <label>
            <input type="radio" value="{{choice.text}}" 
                   ng-model="$parent.response.choices" required/>
            {{choice.text}}
        </label>
    </li>
</ul>

The only change required to the link function in the custom directive was a fallback to the form controller if the model controller was undefined within the scope $watch function, like so:

controller = formController[attributes.validationClassFor] || formController
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.