Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 108a69b

Browse files
nicoabierodyhaddad
authored andcommitted
feat(form): Add new $submitted state to forms
The $submitted state changes - to true when the form is submitted - to false when $setPristine is called on the form A .ng-submitted class is added to the form when $submitted=true Closes #8056
1 parent 52b77b6 commit 108a69b

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

src/ng/directive/form.js

+24-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
'use strict';
22

3-
/* global -nullFormCtrl */
3+
/* global -nullFormCtrl, -SUBMITTED_CLASS */
44
var nullFormCtrl = {
55
$addControl: noop,
66
$removeControl: noop,
77
$setValidity: noop,
88
$setDirty: noop,
9-
$setPristine: noop
10-
};
9+
$setPristine: noop,
10+
$setSubmitted: noop
11+
},
12+
SUBMITTED_CLASS = 'ng-submitted';
1113

1214
/**
1315
* @ngdoc type
@@ -60,6 +62,7 @@ function FormController(element, attrs, $scope, $animate) {
6062
form.$pristine = true;
6163
form.$valid = true;
6264
form.$invalid = false;
65+
form.$submitted = false;
6366

6467
parentForm.$addControl(form);
6568

@@ -228,16 +231,29 @@ function FormController(element, attrs, $scope, $animate) {
228231
* saving or resetting it.
229232
*/
230233
form.$setPristine = function () {
231-
$animate.removeClass(element, DIRTY_CLASS);
232-
$animate.addClass(element, PRISTINE_CLASS);
234+
$animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
233235
form.$dirty = false;
234236
form.$pristine = true;
237+
form.$submitted = false;
235238
forEach(controls, function(control) {
236239
control.$setPristine();
237240
});
238241
};
239-
}
240242

243+
/**
244+
* @ngdoc function
245+
* @name ng.directive:form.FormController#$setSubmitted
246+
* @methodOf ng.directive:form.FormController
247+
*
248+
* @description
249+
* Sets the form to its submitted state.
250+
*/
251+
form.$setSubmitted = function () {
252+
$animate.addClass(element, SUBMITTED_CLASS);
253+
form.$submitted = true;
254+
parentForm.$setSubmitted();
255+
};
256+
}
241257

242258
/**
243259
* @ngdoc directive
@@ -287,6 +303,7 @@ function FormController(element, attrs, $scope, $animate) {
287303
* - `ng-invalid` is set if the form is invalid.
288304
* - `ng-pristine` is set if the form is pristine.
289305
* - `ng-dirty` is set if the form is dirty.
306+
* - `ng-submitted` is set if the form was submitted.
290307
*
291308
* Keep in mind that ngAnimate can detect each of these classes when added and removed.
292309
*
@@ -423,6 +440,7 @@ var formDirectiveFactory = function(isNgForm) {
423440
var handleFormSubmission = function(event) {
424441
scope.$apply(function() {
425442
controller.$commitViewValue();
443+
controller.$setSubmitted();
426444
});
427445

428446
event.preventDefault

test/ng/directive/formSpec.js

+34-4
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ describe('form', function() {
404404

405405
child.$setDirty();
406406
expect(parent.$dirty).toBeTruthy();
407+
408+
child.$setSubmitted();
409+
expect(parent.$submitted).toBeTruthy();
407410
});
408411

409412

@@ -681,14 +684,42 @@ describe('form', function() {
681684
expect(nestedInputCtrl.$dirty).toBe(false);
682685
});
683686
});
687+
688+
describe('$setSubmitted', function() {
689+
beforeEach(function() {
690+
doc = $compile(
691+
'<form name="form" ng-submit="submitted = true">' +
692+
'<input type="text" ng-model="name" required />' +
693+
'<input type="submit" />' +
694+
'</form>')(scope);
695+
696+
scope.$digest();
697+
});
698+
699+
it('should not init in submitted state', function() {
700+
expect(scope.form.$submitted).toBe(false);
701+
});
702+
703+
it('should be in submitted state when submitted', function() {
704+
browserTrigger(doc, 'submit');
705+
expect(scope.form.$submitted).toBe(true);
706+
});
707+
708+
it('should revert submitted back to false when $setPristine is called on the form', function() {
709+
scope.form.$submitted = true;
710+
scope.form.$setPristine();
711+
expect(scope.form.$submitted).toBe(false);
712+
});
713+
});
684714
});
685715

686716
describe('form animations', function() {
687717
beforeEach(module('ngAnimateMock'));
688718

689-
function assertValidAnimation(animation, event, className) {
719+
function assertValidAnimation(animation, event, classNameAdded, classNameRemoved) {
690720
expect(animation.event).toBe(event);
691-
expect(animation.args[1]).toBe(className);
721+
expect(animation.args[1]).toBe(classNameAdded);
722+
expect(animation.args[2]).toBe(classNameRemoved);
692723
}
693724

694725
var doc, scope, form;
@@ -741,8 +772,7 @@ describe('form animations', function() {
741772

742773
form.$setPristine();
743774

744-
assertValidAnimation($animate.queue[0], 'removeClass', 'ng-dirty');
745-
assertValidAnimation($animate.queue[1], 'addClass', 'ng-pristine');
775+
assertValidAnimation($animate.queue[0], 'setClass', 'ng-pristine', 'ng-dirty ng-submitted');
746776
}));
747777

748778
it('should trigger custom errors as addClass/removeClass when invalid/valid', inject(function($animate) {

0 commit comments

Comments
 (0)