diff --git a/src/components/datepicker/datePicker.js b/src/components/datepicker/datePicker.js
index e2bc691d207..249a7e51c0a 100644
--- a/src/components/datepicker/datePicker.js
+++ b/src/components/datepicker/datePicker.js
@@ -60,7 +60,9 @@
// This pane will be detached from here and re-attached to the document body.
'
' +
- '
' +
+ '
' +
'
' +
'' +
@@ -134,6 +136,12 @@
/** @type {HTMLElement} Calendar icon button. */
this.calendarButton = $element[0].querySelector('.md-datepicker-button');
+ /**
+ * Element covering everything but the input in the top of the floating calendar pane.
+ * @type {HTMLElement}
+ */
+ this.inputMask = $element[0].querySelector('.md-datepicker-input-mask-opaque');
+
/** @final {!angular.JQLite} */
this.$element = $element;
@@ -262,7 +270,7 @@
Object.defineProperty(this, 'placeholder', {
get: function() { return self.inputElement.placeholder; },
- set: function(value) { self.inputElement.placeholder = value; }
+ set: function(value) { self.inputElement.placeholder = value || ''; }
});
};
@@ -313,6 +321,12 @@
calendarPane.style.top = (elementRect.top - bodyRect.top) + 'px';
document.body.appendChild(this.calendarPane);
+ // The top of the calendar pane is a transparent box that shows the text input underneath.
+ // Since the pane is flowing, though, the page underneath the pane *adjacent* to the input is
+ // also shown unless we cover it up. The inputMask does this by filling up the remaining space
+ // based on the width of the input.
+ this.inputMask.style.left = elementRect.width + 'px';
+
// Add CSS class after one frame to trigger open animation.
this.$$rAF(function() {
calendarPane.classList.add('md-pane-open');
diff --git a/src/components/datepicker/datePicker.scss b/src/components/datepicker/datePicker.scss
index 73d7f1fe054..82cdaf67be5 100644
--- a/src/components/datepicker/datePicker.scss
+++ b/src/components/datepicker/datePicker.scss
@@ -3,6 +3,10 @@ $md-datepicker-button-gap: 12px; // Space between the text input and the calend
$md-datepicker-border-bottom-gap: 5px; // Space between input and the grey underline.
$md-datepicker-open-animation-duration: 0.2s;
+md-datepicker {
+ // Don't let linebreaks happen between the open icon-button and the input.
+ white-space: nowrap;
+}
// The calendar icon button used to open the calendar pane.
// Need absurd specificty to override md-button.md-icon-button.
@@ -62,12 +66,22 @@ $md-datepicker-open-animation-duration: 0.2s;
.md-datepicker-input-mask {
height: 40px;
width: $md-calendar-width;
+ position: relative;
background: transparent;
pointer-events: none;
cursor: text;
}
+.md-datepicker-input-mask-opaque {
+ position: absolute;
+ right: 0;
+ left: 120px;
+ background: white;
+
+ height: 100%;
+}
+
// The calendar portion of the floating pane (vs. the input mask).
.md-datepicker-calendar {
opacity: 0;
@@ -136,7 +150,6 @@ md-datepicker[disabled] {
// Open state for all of the elements of the picker.
.md-datepicker-open {
.md-datepicker-input-container {
- min-width: $md-calendar-width;
margin-left: -$md-datepicker-button-gap;
border: none;
}
diff --git a/src/components/datepicker/datePicker.spec.js b/src/components/datepicker/datePicker.spec.js
index 170e97b6b6a..557e9a4fe05 100644
--- a/src/components/datepicker/datePicker.spec.js
+++ b/src/components/datepicker/datePicker.spec.js
@@ -45,6 +45,7 @@ describe('md-date-picker', function() {
$timeout.flush();
expect(controller.calendarPane.offsetHeight).toBeGreaterThan(0);
+ expect(controller.inputMask.style.left).toBe(controller.inputContainer.clientWidth + 'px');
// Click off of the calendar.
document.body.click();
diff --git a/src/components/datepicker/dateUtil.js b/src/components/datepicker/dateUtil.js
index e8b96bc7d49..97a2451cc6c 100644
--- a/src/components/datepicker/dateUtil.js
+++ b/src/components/datepicker/dateUtil.js
@@ -185,7 +185,7 @@
* @return {boolean} Whether the date is a valid Date.
*/
function isValidDate(date) {
- return date !== null && date.getTime && !isNaN(date.getTime());
+ return date != null && date.getTime && !isNaN(date.getTime());
}
/**
diff --git a/src/components/datepicker/dateUtil.spec.js b/src/components/datepicker/dateUtil.spec.js
index 329a1684c25..dac1d7c86b6 100644
--- a/src/components/datepicker/dateUtil.spec.js
+++ b/src/components/datepicker/dateUtil.spec.js
@@ -303,4 +303,19 @@ describe('$$mdDateUtil', function() {
expect(dayAtMidnight.getSeconds()).toBe(0);
expect(dayAtMidnight.getMilliseconds()).toBe(0);
});
+
+ it('should determine whether dates are valid', function() {
+ expect(dateUtil.isValidDate(null)).toBeFalsy();
+ expect(dateUtil.isValidDate(undefined)).toBeFalsy();
+ expect(dateUtil.isValidDate('')).toBeFalsy();
+ expect(dateUtil.isValidDate(0)).toBeFalsy();
+ expect(dateUtil.isValidDate(NaN)).toBeFalsy();
+ expect(dateUtil.isValidDate(123456789)).toBeFalsy();
+ expect(dateUtil.isValidDate('123456789')).toBeFalsy();
+ expect(dateUtil.isValidDate(new Date(''))).toBeFalsy();
+ expect(dateUtil.isValidDate(new Date('Banjo'))).toBeFalsy();
+ expect(dateUtil.isValidDate(new Date(NaN))).toBeFalsy();
+
+ expect(dateUtil.isValidDate(new Date())).toBe(true);
+ });
});