This might be a duplicate but couldn't get any useful answer googling myself... if duplicated, sorry. Go haed and delete this post.
I have the following form in AngularJS:
<form novalidate
class="form-group css-form"
name="submissionForm"
ng-submit="submit(submissionForm.$valid)">
<form-portion content="data.piece1"></form-portion>
<form-portion content="data.piece2"></form-portion>
<form-portion content="data.piece3"></form-portion>
<form-portion content="data.piece4"></form-portion>
<form-portion content="data.piece5"></form-portion>
<form-portion content="data.piece6"></form-portion>
<form-portion content="data.piece7"></form-portion>
<form-portion content="data.piece8"></form-portion>
<form-portion content="data.piece9"></form-portion>
<div class="row text-center">
<button type="submit" class="btn btn-success" ng-disabled="submissionForm.$invalid">Submit</button>
<button type="reset" class="btn btn-warning" ng-click="reset()">Reset</button>
</div>
</form>
The formPortion directive is defined as follow:
directives.directive('formPortion', function () {
return {
restrict: 'AE',
require: '^form',
templateUrl: 'partials/form_template.html',
scope: {
content: '='
},
link: function ($scope) {
$scope.submissionForm = $scope.$parent.submissionForm;
$scope.someSelected = function (in_dict) {
for (var k in in_dict) {
if (in_dict[k]) {
return true
}
}
return false
};
}
}
});
The form_template.html looks like:
<div ng-repeat="(i,row) in content | orderBy : 'order' track by row.field">
<div ng-switch="row.field1">
<-- a bunch of other switches -->
<div ng-switch-when="array">
<div ng-switch="row.field2">
<div ng-switch-when="checkbox" class="row form-group">
<div ng-include="'partials/template1.html'"></div>
</div>
<-- other cases -->
</div>
</div>
</div>
</div>
In the template1.html, the checkbox array implementation is defined:
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-3">
<label>
{{row.name}}
</label>
</div>
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-9" ng-init="row.user_input = {}">
<div ng-repeat="value in row.allowed_values" class="checkbox-inline">
<input type="checkbox"
name="{{row.field}}"
value="{{value}}"
ng-model="row.user_input[value]"
ng-required="{{row.mandatory_field && !someSelected(row.user_input)}}"
>{{value}}
</div>
</div>
Thanks to the ng-init directive, it is easy to implement the independent selection of the checkboxes. What I still cannot do is the validation. The ng-required directive get triggered correctly (the ng-required value changes as soon as the one checkbox is clicked) but the submit button does not get activated. This means that the ngModelController.$invalid flag does not get triggered. Here is a snippet of the ngModelController object of my form:
...,
"$error": {
"required": [{
"$viewValue": "",
"$validators": {},
"$asyncValidators": {},
"$parsers": [null, null],
"$formatters": [null],
"$viewChangeListeners": [],
"$untouched": true,
"$touched": false,
"$pristine": false,
"$dirty": true,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "A",
"$options": null
}, {
"$viewValue": null,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [],
"$formatters": [],
"$viewChangeListeners": [],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "B",
"$options": null
}, {
"$viewValue": null,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [],
"$formatters": [],
"$viewChangeListeners": [],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "B",
"$options": null
}, {
"$viewValue": null,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [],
"$formatters": [null],
"$viewChangeListeners": [],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "C",
"$options": null
}, {
"$viewValue": false,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [null],
"$formatters": [null],
"$viewChangeListeners": [null],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "D",
"$options": null
}, {
"$viewValue": false,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [null],
"$formatters": [null],
"$viewChangeListeners": [null],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "D",
"$options": null
}, {
"$viewValue": false,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [null],
"$formatters": [null],
"$viewChangeListeners": [null],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "D",
"$options": null
}, {
"$viewValue": false,
"$modelValue": null,
"$validators": {},
"$asyncValidators": {},
"$parsers": [null],
"$formatters": [null],
"$viewChangeListeners": [null],
"$untouched": true,
"$touched": false,
"$pristine": true,
"$dirty": false,
"$valid": false,
"$invalid": true,
"$error": {
"required": true
},
"$name": "D",
"$options": null
}, ...
The $name
field gets replicated for each checkbox/radio. How can I implement some validation, triggering the general $invalid
flag when at least one checkbox is checked?