This is one of those bugs which has you tearing your hair out.
I have written a directive to perform a custom validation on either a time, distance or points total according to the value chosen in the select box. Here it is working nicely:
http://plnkr.co/edit/FECdILYtahR0HjoWysTr?p=preview
The problem starts when I apply the directive to my application. The form's $invalid property is set to true but the $error.mymeasure, although apparently set to true in the debugger, does not have any effect on the view.
Chrome debugger output screenshot: http://prntscr.com/2peomt
Code to output the $error and $invalid properties:
entriesForm.savedcurvalue.$error.mymeasure: {{ entriesForm.savedcurvalue.$error.mymeasure }}
/ $invalid: {{ entriesForm.$invalid }} <br/>
Actual output in the view:
entriesForm.savedcurvalue.$error.mymeasure: / $invalid: true
As far as I can tell the relevant code is identical to the test... here's the html: (The input with the directive is at the bottom)
<form name="entriesForm" class="css-form" novalidate>
<div class="grey-border" ng-show="entriesData.currentAthleteIndex != undefined">
<!--******** ALREADY SAVED ********-->
<div ng-show="entriesData.showEventListGroup=='saved'">
<ul class="inline entry-table-head">
<li class="entry-col-1">{{ 'entries.class' | i18n }}</li>
<li class="entry-col-2">{{ 'entries.event.curValue' | i18n }}</li>
<li class="entry-col-3">{{ 'entries.event.curWeightHeight' | i18n }}</li>
<li class="entry-col-4">{{ 'entries.event.datDate' | i18n }}</li>
<li class="entry-col-5">{{ 'entries.event.strTown' | i18n }}</li>
<li class="entry-col-6">{{ 'entries.event.bolindoor' | i18n }}</li>
</ul>
<span ng-show="entriesForm.measurement.$error.measure">{{ measurementFormat }} </span>
entriesForm.savedcurvalue.$error.mymeasure: {{ entriesForm.savedcurvalue.$error.mymeasure }} / $invalid: {{ entriesForm.$invalid }} <br/>
<ul class="unstyled">
<li ng-repeat="event in currentEditItem.athleteList[entriesData.currentAthleteIndex].events"
ng-show="event.selected && !event.isRelay">
<ul class="inline">
<li class="entry-col-1"
ng-class="{requestStatusGreen:event.ownEvents && event.ownSex, requestStatusYellow:!event.ownEvents && event.ownSex, requestStatusRed:!event.ownEvents && !event.ownSex}">
<label class="checkbox inline">
<input type="checkbox" ng-model="event.selected" ng-click="setIntStateSave(event,currentEditItem.athleteList[entriesData.currentAthleteIndex])"/>
{{ event.strIdClass }} - {{ event.strName }}
</label>
</li>
<li class="entry-col-2 control-group" ng-class="{error:entriesForm.saved_curValue.$error.measure}">
<input class="input-mini" type="text" ng-model="event.curValue" ng-change="setChecked(event)" name="savedcurvalue"
smart-measurement="event.intType" errorformat="measurementFormat" decimal="DECIMAL" />
</li>
And the directive:
app.directive('smartMeasurement', function () {
return {
require: 'ngModel',
scope: {
ngModel: '=',
smartMeasurement: '=',
errorformat: '=',
decimal: '='
},
link: function (scope, elm, attrs, ctrl) {
var REGEX;
var TIME_REGEXP;
var LENGTH_REGEXP;
var MULTI_REGEXP = /^(?:\d{1,5})?$/;
if (scope.decimal == ",") {
TIME_REGEXP = /^(?:\d+:)?(?:[0-5]\d:|[0-9]:)?(?:[0-5]\d|\d|^\d\d\d)(?:[.,]\d\d?)?$/;
LENGTH_REGEXP = /^(?:\d{1,3})(?:[,]\d)(\d)?$/;
} else {
TIME_REGEXP = /^(?:\d+:)?(?:[0-5]\d:|[0-9]:)?(?:[0-5]\d|\d|^\d\d\d)(?:[.,]\d\d?)?$/;
LENGTH_REGEXP = /^(?:\d{1,3})(?:[.]\d)(\d)?$/;
}
ctrl.$parsers.unshift(function (viewValue) {
switch (scope.smartMeasurement) {
case 3:
REGEX = LENGTH_REGEXP;
scope.errorformat = "00" + scope.decimal + "00";
break;
case 4:
REGEX = MULTI_REGEXP;
scope.errorformat = "00000";
break;
default:
REGEX = TIME_REGEXP;
scope.errorformat = "[hh:mm:]ss" + scope.decimal + "t[h] / [s]ss" + scope.decimal + "t[h]";
break;
}
if (REGEX.test(viewValue)) {
ctrl.$setValidity('mymeasure', true);
return viewValue;
} else {
ctrl.$setValidity('mymeasure', false);
return undefined;
}
});
}
};
});
I am using Angular 1.06 - The project was started almost a year ago so upgrading to 1.2 is not really an option at the moment. I am thinking that perhaps one on the dependencies could prevent it working. I will test this although I find it unlikely. But that is the only thing I can think of that might be wrong.
If anybody can sport an error or suggest a place I should look, it would be very much appreciated.