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

Commit 2a05176

Browse files
crisbetoThomasBurleson
authored andcommitted
fix(datepicker): mark the input as invalid on submit, add missing import
* Fixes invalid datepickers not being highlighted when their parent form is submitted. * Fixes $mdAria not being imported and causing a JS error occasionally. Fixes #8411. Closes #9050
1 parent 9506c45 commit 2a05176

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/components/datepicker/js/datepickerDirective.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
* </hljs>
5454
*
5555
*/
56-
function datePickerDirective($$mdSvgRegistry) {
56+
function datePickerDirective($$mdSvgRegistry, $mdUtil, $mdAria) {
5757
return {
5858
template: function(tElement, tAttrs) {
5959
// Buttons are not in the tab order because users can open the calendar via keyboard
@@ -142,7 +142,8 @@
142142
}
143143

144144
scope.$watch(mdInputContainer.isErrorGetter || function() {
145-
return ngModelCtrl.$invalid && ngModelCtrl.$touched;
145+
var parentForm = mdDatePickerCtrl.parentForm;
146+
return ngModelCtrl.$invalid && (ngModelCtrl.$touched || (parentForm && parentForm.$submitted));
146147
}, mdInputContainer.setInvalid);
147148
}
148149
}
@@ -276,6 +277,9 @@
276277
/** @final */
277278
this.mdInputContainer = null;
278279

280+
/** @final */
281+
this.parentForm = angular.element($mdUtil.getClosest($element, 'form')).controller('form');
282+
279283
/**
280284
* Element from which the calendar pane was opened. Keep track of this so that we can return
281285
* focus to it when the pane is closed.
@@ -322,6 +326,18 @@
322326
}
323327
});
324328
}
329+
330+
if (self.parentForm) {
331+
// If invalid, highlights the input when the parent form is submitted.
332+
var parentSubmittedWatcher = $scope.$watch(function() {
333+
return self.parentForm.$submitted;
334+
}, function(isSubmitted) {
335+
if (isSubmitted) {
336+
self.updateErrorState();
337+
parentSubmittedWatcher();
338+
}
339+
});
340+
}
325341
}
326342

327343
/**

src/components/datepicker/js/datepickerDirective.spec.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ describe('md-datepicker', function() {
126126
}).not.toThrow();
127127
});
128128

129-
describe('ngMessages suport', function() {
129+
describe('ngMessages support', function() {
130130
it('should set the `required` $error flag', function() {
131131
pageScope.isRequired = true;
132132
populateInputElement('');
@@ -243,6 +243,31 @@ describe('md-datepicker', function() {
243243

244244
expect(formCtrl.$error['filtered']).toBeTruthy();
245245
});
246+
247+
it('should add the invalid class when the form is submitted', function() {
248+
// This needs to be recompiled, in order to reproduce conditions where a form is
249+
// submitted, without the datepicker having being touched (usually it has it's value
250+
// set to `myDate` by default).
251+
ngElement && ngElement.remove();
252+
pageScope.myDate = null;
253+
pageScope.isRequired = true;
254+
255+
createDatepickerInstance('<form>' + DATEPICKER_TEMPLATE + '</form>');
256+
257+
var formCtrl = ngElement.controller('form');
258+
var inputContainer = ngElement.controller('mdDatepicker').inputContainer;
259+
260+
expect(formCtrl.$invalid).toBe(true);
261+
expect(formCtrl.$submitted).toBe(false);
262+
expect(inputContainer).not.toHaveClass('md-datepicker-invalid');
263+
264+
pageScope.$apply(function() {
265+
formCtrl.$setSubmitted(true);
266+
});
267+
268+
expect(formCtrl.$submitted).toBe(true);
269+
expect(inputContainer).toHaveClass('md-datepicker-invalid');
270+
});
246271
});
247272
});
248273

0 commit comments

Comments
 (0)