Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've tried to use the html5 required attribute for my group of checkboxes but I don't find a nice way to implement it with ng-form.

When a checkbox is checked I want the value of that input-element to be pushed to an array of values.

The angular required validator seems to watch the ng-model associated with the input element, but how can I link several checkboxes to the same model and update it's value with the value of the input field?

Right now the implementation is like this fiddle.

<div ng-controller="myCtrl">
  <ng-form name="myForm">
    <span ng-repeat="choice in choices">
      <label class="checkbox" for="{{choice.id}}">
        <input type="checkbox" required="required" value="{{choice.id}}" ng-click="updateQuestionValue(choice)" ng-model="choice.checked" name="group-one" id="{{choice.id}}" />
        {{choice.label}}
      </label>
    </span>
    <input type="submit" value="Send" ng-click="submitSurvey(survey)" ng-disabled="myForm.$invalid" />
  </ng-form>
</div>​

The updateQuestionValue-function handles the adding or removing from the array of values but each checkbox has it's own model and that is why each checkbox needs to be checked in order for the form to be valid.

I've got it to work on a group of radio buttons, but they all work on the same model as only one can be selected.

share|improve this question
    
I banged my head against a wall for an hour with this using Angular v1.2.1 until trying it on 1.2.10. Seems to be fixed now. –  alalonde Mar 5 at 17:59

4 Answers 4

up vote 7 down vote accepted

If you want the submit button disabled if no choice is selected the easiest way is to check the length of the array in the ng-disabled attribute, without setting the required attribute

<input type="submit" value="Send" ng-click="submitSurvey(survey)" 
 ng-disabled="value.length==0" />

See here for updated fiddle

Another way to do this would be to check the array length in the ng-required attribute of the checkboxes

<input type="checkbox" value="{{choice.id}}" ng-click="updateQuestionValue(choice)"
  ng-model="choice.checked" name="group-one" id="{{choice.id}}" 
  ng-required="value.length==0" />

Second fiddle

share|improve this answer
    
Thanks! I went with your second solution to fix this problem for now. –  Tryggve Nov 27 '12 at 12:53

A few things:

  • I would go with an approach that just updated the entire array in this case, as it would simplify the code a little. (You might not want to do this if you're doing anything stateful with the $scope.value array contents, but it doesn't look like you are).
  • you can just use <form> rather than <ng-form>.
  • move the submit function off of the button's ng-click and into the form's ng-submit. This makes validation management a little easier with angular's built-in validation (if you care about that)
  • If your <label> wraps your <input> you don't need the for="" attribute.

Here is an updated fiddle for you

And here's the code:

<div ng-controller="myCtrl">
    <form name="myForm" ng-submit="submitSurvey(survey)">
        <span ng-repeat="choice in choices">
            <label class="checkbox">
            <input type="checkbox" required="required" value="{{choice.id}}" ng-change="updateQuestionValues()" ng-model="choice.checked" name="group-one" />
                {{choice.label}}
            </label>
        </span>
        <input type="submit" value="Send" ng-disabled="myForm.$invalid" />
    </form>
    {{value}}
</div>​

JS

function myCtrl($scope) {

    $scope.choices = [{
        "id": 1,
        "value": "1",
        "label": "Good"},
    {
        "id": 2,
        "value": "2",
        "label": "Ok"},
    {
        "id": 3,
        "value": "3",
        "label": "Bad"}];

    $scope.value = [];

    $scope.updateQuestionValues = function() {
        $scope.value = _.filter($scope.choices, function(c) {
            return c.checked;
        });
    };
}​
share|improve this answer
    
Hi! Thanks for your thoughts, I will refactor my final implementation. But I don't see how this helps me with my initial problem? I still need to get all three checkboxes checked before myForm.$invalid == false –  Tryggve Nov 27 '12 at 12:42

I just added a hidden input with ng-model that's the same as your ng-model for the radio button:

 <div class="radio" ng-repeat="option in item.AnswerChoices | orderBy: DisplayOrder">
        <input type="radio" ng-model="item.Answer" name="mulchoice" value="{{option.DisplayName}}" />
        <span>{{option.DisplayName}}</span>
    <input type="hidden" ng-model="item.Answer" name="hiddenradiobuttoninput" required/>
 </div>
share|improve this answer

Why not make your checkbox models the array

<input type="checkbox" ng-model="value[$index]" value="{{choice.id}}/>

Fiddle: http://jsfiddle.net/thbkA/1/

share|improve this answer
    
Thanks, that's a nice solution but it still doesn't help with my initial problem that in order to make Angular mark my form as valid I need to make all three checkboxes checked. –  Tryggve Nov 27 '12 at 12:45
    
@Tryggve, checkout this question: stackoverflow.com/questions/16289248/… –  b1r3k Jul 5 '13 at 11:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.