@@ -100,27 +100,22 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
100100
101101 public clear ( ) : void {
102102 this . showMask ( '' ) ;
103- this . value = null ;
104- this . valueChanged . emit ( { oldValue : this . _oldValue , newValue : this . value } ) ;
103+ this . updateValue ( null ) ;
105104 }
106105
107106 public increment ( datePart ?: DatePart ) : void {
108107 const newValue = datePart ? this . calculateValueOnSpin ( datePart , 1 ) : this . calculateValueOnSpin ( this . targetDatePart , 1 ) ;
109108 if ( newValue && this . value && newValue !== this . value ) {
110109 this . updateValue ( newValue ) ;
110+ this . updateMask ( ) ;
111111 }
112-
113- // TODO: update mask
114- // this.updateMask();
115112 }
116113
117114 public decrement ( datePart ?: DatePart ) : void {
118115 const newValue = datePart ? this . calculateValueOnSpin ( datePart , - 1 ) : this . calculateValueOnSpin ( this . targetDatePart , - 1 ) ;
119116 if ( newValue && this . value && newValue !== this . value ) {
120117 this . updateValue ( newValue ) ;
121-
122- // TODO: update mask
123- // this.updateMask(true);
118+ this . updateMask ( ) ;
124119 }
125120 }
126121
@@ -148,9 +143,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
148143 }
149144
150145 if ( event . ctrlKey && event . key === KEYS . SEMICOLON ) {
151- // TODO: emit success & update mask?
152- this . value = new Date ( ) ;
153- this . valueChanged . emit ( { oldValue : this . _oldValue , newValue : this . value } ) ;
146+ this . updateValue ( new Date ( ) ) ;
154147 this . updateMask ( ) ;
155148 }
156149
@@ -172,7 +165,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
172165 }
173166
174167 // TODO: display value pipe
175- // this.updateMask(); TODO: fill in any empty date parts
168+ // this.updateMask();
176169 this . onTouchCallback ( ) ;
177170 super . onBlur ( event ) ;
178171 }
@@ -181,9 +174,18 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
181174 protected handleInputChanged ( ) : void {
182175 // the mask must be updated before any date operations
183176 super . handleInputChanged ( ) ;
177+ if ( this . inputValue === this . maskParser . applyMask ( '' , this . maskOptions ) ) {
178+ this . updateValue ( null ) ;
179+ return ;
180+ }
181+
184182 const parsedDate = this . parseDate ( this . inputValue ) ;
185- if ( parsedDate . state === DateState . Valid && this . inputValue . indexOf ( this . promptChar ) === - 1 ) {
186- this . updateValue ( parsedDate . value ) ;
183+ if ( this . inputValue . indexOf ( this . promptChar ) === - 1 ) { // better way to check for filled input?
184+ if ( parsedDate . state === DateState . Valid ) {
185+ this . updateValue ( parsedDate . value ) ;
186+ } else {
187+ this . validationFailed . emit ( { oldValue : this . value , newValue : parsedDate . value } ) ;
188+ }
187189 }
188190
189191 super . afterInput ( ) ;
@@ -198,6 +200,7 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
198200 }
199201
200202 private valueInRange ( value : Date ) : boolean {
203+ if ( ! value ) { return ; }
201204 const maxValueAsDate = this . isDate ( this . maxValue ) ? this . maxValue : this . parseDate ( this . maxValue ) . value ;
202205 const minValueAsDate = this . isDate ( this . minValue ) ? this . minValue : this . parseDate ( this . minValue ) . value ;
203206 if ( maxValueAsDate && minValueAsDate ) {
@@ -228,6 +231,8 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
228231 return DatePickerUtil . calculateMinutesOnSpin ( delta , newDate , currentDate , this . isSpinLoop ) ;
229232 case DatePart . Seconds :
230233 return DatePickerUtil . calculateSecondsOnSpin ( delta , newDate , currentDate , this . isSpinLoop ) ;
234+ case DatePart . AmPm :
235+ return DatePickerUtil . calculateAmPmOnSpin ( delta , newDate , currentDate ) ;
231236 }
232237 }
233238
@@ -244,47 +249,54 @@ export class IgxDateTimeEditorDirective extends IgxMaskDirective implements OnIn
244249 private updateMask ( ) {
245250 const cursor = this . selectionEnd ;
246251 this . _dateTimeFormatParts . forEach ( p => {
247- // TODO: cycle through the parts and update the mask based on their indices
248- let value : number = this . breakUpDate ( p . type ) ;
249- // TODO: append all date parts from the date object to one another
250- // if a part of that date object's length is less than the expected length (taken from the format) -> prepend prompt chars
251- value = p . type === DatePart . Month ? value + 1 : value ;
252- this . inputValue = this . maskParser . replaceInMask ( this . inputValue , `${ value } ` , this . maskOptions , p . start , p . end ) . value ;
252+ const partLength = p . end - p . start ;
253+ let targetValue : string = this . getMaskedValue ( p . type , partLength ) ;
254+
255+ if ( p . type === DatePart . Month ) {
256+ targetValue = this . prependPromptChars (
257+ parseInt ( targetValue . replace ( new RegExp ( this . promptChar , 'g' ) , '0' ) , 10 ) + 1 , partLength ) ;
258+ }
259+
260+ this . inputValue = this . maskParser . replaceInMask ( this . inputValue , targetValue , this . maskOptions , p . start , p . end ) . value ;
253261 } ) ;
254262 this . setSelectionRange ( cursor ) ;
255263 }
256264
257- private breakUpDate ( datePart : DatePart ) : number {
258- const valueAsDate = this . value as Date ;
265+ private getMaskedValue ( datePart : DatePart , partLength : number ) : string {
266+ let maskedValue ;
259267 switch ( datePart ) {
260268 case DatePart . Date :
261- return valueAsDate . getDate ( ) ;
269+ maskedValue = this . value . getDate ( ) ;
270+ break ;
262271 case DatePart . Month :
263- return valueAsDate . getMonth ( ) ;
272+ maskedValue = this . value . getMonth ( ) ;
273+ break ;
264274 case DatePart . Year :
265- return valueAsDate . getFullYear ( ) ;
275+ maskedValue = this . value . getFullYear ( ) ;
276+ break ;
266277 case DatePart . Hours :
267- return valueAsDate . getHours ( ) ;
278+ maskedValue = this . value . getHours ( ) ;
279+ break ;
268280 case DatePart . Minutes :
269- return valueAsDate . getMinutes ( ) ;
281+ maskedValue = this . value . getMinutes ( ) ;
282+ break ;
270283 case DatePart . Seconds :
271- return valueAsDate . getSeconds ( ) ;
284+ maskedValue = this . value . getSeconds ( ) ;
285+ break ;
286+ case DatePart . AmPm :
287+ maskedValue = this . value . getHours ( ) >= 12 ? 'PM' : 'AM' ;
288+ break ;
272289 }
273- }
274290
275- private updateMaskOnSpin ( parsedValue : number , editedParts : DatePartInfo [ ] , addPromptChar ?: boolean ) {
276- let start = editedParts [ 0 ] . start ;
277- const end = editedParts [ editedParts . length - 1 ] . start ;
278- if ( parsedValue . toString ( ) . length < editedParts . length ) {
279- start += editedParts . length - parsedValue . toString ( ) . length ;
280- if ( addPromptChar ) {
281- this . inputValue = this . maskParser . replaceCharAt ( this . inputValue , start - 1 , this . promptChar ) ;
282- }
291+ if ( datePart !== DatePart . AmPm ) {
292+ return this . prependPromptChars ( maskedValue , partLength ) ;
283293 }
284294
285- this . inputValue = this . maskParser . replaceInMask (
286- this . inputValue , `${ parsedValue } ` , this . maskOptions , start , end ) . value ;
287- this . setSelectionRange ( this . end ) ;
295+ return maskedValue ;
296+ }
297+
298+ private prependPromptChars ( value : number , partLength : number ) : string {
299+ return ( this . promptChar + value . toString ( ) ) . slice ( - partLength ) ;
288300 }
289301
290302 private spin ( event : KeyboardEvent ) : void {
0 commit comments