StackOverflow_24227903: angular-form-validation-but-not-using-inputs
Illustration of answer to http://stackoverflow.com/questions/24227903/angular-form-validation-but-not-using-inputs.
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular-messages.min.js"></script>
<div ng-controller="myCtrl">
<form name="myForm" ng-submit="sendMessage()" novalidate>
<div>
Email:
<input type="text" name="rcpEmail" ng-model="recipient.email"
placeholder="Send email to..." required-any="msgType" />
<div ng-messages="myForm.rcpEmail.$error" ng-if="myForm.$submitted">
<div class="error" ng-message="requiredAny">At least one recipient method must be chosen</div>
</div>
<br />
Modile:
<input type="text" name="rcpMobile" ng-model="recipient.mobile"
placeholder="Send SMS to..." required-any="msgType" />
<div ng-messages="myForm.rcpMobile.$error" ng-if="myForm.$submitted">
<div class="error" ng-message="requiredAny">At least one recipient method must be chosen</div>
</div>
<br />
Address:
<input type="text" name="rcpAddress" ng-model="recipient.address"
placeholder="Send card to..." required-any="msgType" />
<div ng-messages="myForm.rcpAddress.$error" ng-if="myForm.$submitted">
<div class="error" ng-message="requiredAny">At least one recipient method must be chosen</div>
</div>
</div>
<hr />
<button type="submit">Send message</button>
<br/>
</form>
</div>
JavaScript
var app = angular.module('myApp', ['ngMessages']);
app.controller('myCtrl', function ($scope) {
$scope.sendMessage = function () {
$scope.myForm.$submitted = true;
if ($scope.myForm.$valid) {
alert('Message sent !');
}
};
});
app.directive('requiredAny', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function postLink(scope, elem, attrs, ctrl) {
// If there is no 'ngModel' or no groupName has been specified,
// then there is nothing we can do
if (!ctrl || !attrs.requiredAny) { return };
// If this is the first time we've used this directive in this scope,
// create a section for it's data. If you need / want to make use of
// an isolate scope you'll need to make 'var groups' scoped to the directive;
// but then you may want to look in to clearing out group entries yourself
if (!scope.__requiredAnyGroups) {
scope.__requiredAnyGroups = {}
}
var groups = scope.__requiredAnyGroups;
// Create a bucket for this group if one does not yet exist
if (!groups[attrs.requiredAny]) {
groups[attrs.requiredAny] = {};
}
var group = groups[attrs.requiredAny];
// Create the entry for this control
group[attrs.ngModel] = {
ctrl: ctrl,
hasValue: false
};
ctrl.$validators.requiredAny = function(view, value) {
var thisCtrl = group[attrs.ngModel],
ctrlValue = (typeof value !== 'undefined') && value,
oneHasValue = false;
thisCtrl.hasValue = ctrlValue;
// First determine if any field in the group has a value
for (var prop in group) {
if...