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); + }); }); diff --git a/src/components/input/demoBasicUsage/script.js b/src/components/input/demoBasicUsage/script.js index 1e1ff5c6c60..f27bff63777 100644 --- a/src/components/input/demoBasicUsage/script.js +++ b/src/components/input/demoBasicUsage/script.js @@ -4,7 +4,6 @@ angular $scope.user = { title: 'Developer', email: 'ipsum@lorem.com', - submissionDate: new Date(), firstName: '', lastName: '' , company: 'Google' ,