diff options
Diffstat (limited to 'src/directive/form.js')
| -rw-r--r-- | src/directive/form.js | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/directive/form.js b/src/directive/form.js index 6bb1b4d6..47274589 100644 --- a/src/directive/form.js +++ b/src/directive/form.js @@ -35,6 +35,7 @@ FormController.$inject = ['name', '$element', '$attrs']; function FormController(name, element, attrs) { var form = this, parentForm = element.parent().inheritedData('$formController') || nullFormCtrl, + invalidCount = 0, // used to easily determine if we are valid errors = form.$error = {}; // init state @@ -49,11 +50,27 @@ function FormController(name, element, attrs) { parentForm.$addControl(form); + // Setup initial state of the control + element.addClass(PRISTINE_CLASS); + toggleValidCss(true); + + // convenience method for easy toggling of classes + function toggleValidCss(isValid, validationErrorKey) { + validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : ''; + element. + removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey). + addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey); + } + + if (parentForm) { + parentForm.$addControl(form); + } + form.$addControl = function(control) { if (control.$name && !form.hasOwnProperty(control.$name)) { form[control.$name] = control; } - } + }; form.$removeControl = function(control) { if (control.$name && form[control.$name] === control) { @@ -66,11 +83,15 @@ function FormController(name, element, attrs) { if (isValid) { cleanupControlErrors(errors[validationToken], validationToken, control); - if (equals(errors, {})) { + if (!invalidCount) { + toggleValidCss(isValid); form.$valid = true; form.$invalid = false; } } else { + if (!invalidCount) { + toggleValidCss(isValid); + } addControlError(validationToken, control); form.$valid = false; @@ -79,16 +100,19 @@ function FormController(name, element, attrs) { }; form.$setDirty = function() { + element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS); form.$dirty = true; form.$pristine = false; - } + }; function cleanupControlErrors(queue, validationToken, control) { if (queue) { control = control || this; // so that we can be used in forEach; arrayRemove(queue, control); if (!queue.length) { - delete errors[validationToken]; + invalidCount--; + errors[validationToken] = false; + toggleValidCss(true, validationToken); parentForm.$setValidity(validationToken, true, form); } } @@ -100,6 +124,8 @@ function FormController(name, element, attrs) { if (includes(queue, control)) return; } else { errors[validationToken] = queue = []; + invalidCount++; + toggleValidCss(false, validationToken); parentForm.$setValidity(validationToken, false, form); } queue.push(control); @@ -211,14 +237,6 @@ var formDirective = [function() { if (!attr.action) event.preventDefault(); }); - forEach(['valid', 'invalid', 'dirty', 'pristine'], function(name) { - scope.$watch(function() { - return controller['$' + name]; - }, function(value) { - formElement[value ? 'addClass' : 'removeClass']('ng-' + name); - }); - }); - var parentFormCtrl = formElement.parent().inheritedData('$formController'); if (parentFormCtrl) { formElement.bind('$destroy', function() { |
