import React from 'react' ; import ReactDOM from 'react-dom' ; import './DateSelector.scss' ; import SoftKey from '../SoftKey/SoftKey' ; import TriColListView from '../../views/TriColumnListView/TriColumnListView' ; import BodyTextListItem from '../BodyTextListItem/BodyTextListItem' ; import { getDaysInMonth } from '../../utils/dates' ; interface LocalProps { onOK : ( res ? : Date | null ) => void ; onCancel : ( ) => void ; header : React . ElementType | string | undefined ; inputOptions : any ; minDate : Date ; maxDate : Date ; initialDate : Date ; } const Months = { Jan : 1 , Feb : 2 , Mar : 3 , Apr : 4 , May : 5 , June : 6 , Jul : 7 , Aug : 8 , Sep : 9 , Oct : 10 , Nov : 11 , Dec : 12 } ; Object . freeze ( Months ) ; interface DateSelectorEvents { close : ( ) => void ; } type Props = LocalProps & DateSelectorEvents ; interface LocalState { isLoading : boolean ; years : number [ ] ; months : string [ ] ; days : number [ ] ; selectedMonth : number ; selectedDay : number ; selectedYear : number ; } class DateSelector extends React . Component < Props , LocalState > { private input : HTMLInputElement | null = null ; constructor ( props ) { super ( props ) ; this . state = { isLoading : true , years : [ ] , days : [ ] , months : [ ] , selectedMonth : - 1 , selectedDay : - 1 , selectedYear : - 1 } ; } componentDidMount ( ) { const minYear = this . props . minDate . getFullYear ( ) ; const maxYear = this . props . maxDate . getFullYear ( ) ; const years = [ ] ; for ( let i = minYear ; i <= maxYear ; i ++ ) { years . push ( i ) ; } const minDay = 1 ; const maxDay = getDaysInMonth ( this . props . initialDate . getMonth ( ) , this . props . initialDate . getFullYear ( ) ) ; const days = [ ] ; for ( let i = minDay ; i <= maxDay ; i ++ ) { days . push ( i ) ; } const months = Object . keys ( Months ) ; this . setState ( { years , months , days , selectedDay : this . props . initialDate . getDate ( ) , selectedMonth : this . props . initialDate . getMonth ( ) , selectedYear : this . props . initialDate . getFullYear ( ) , isLoading : false } ) ; } onKeyDown = e => { const { onOK , onCancel } = this . props ; switch ( e . key ) { case 'SoftLeft' : if ( onCancel ) { onCancel ( ) ; } this . closeWindow ( ) ; break ; case 'Enter' : if ( onOK ) { onOK ( this . calcSelectedDate ( ) ) ; } this . closeWindow ( ) ; break ; case 'Backspace' : this . closeWindow ( ) ; e . preventDefault ( ) ; break ; default : break ; } } ; closeWindow ( ) { this . props . close ( ) ; } render ( ) { if ( this . state . isLoading ) { return ( < div > Loading ... < /div>); } const { header , onOK } = this . props ; return ( < div className = "systemContent" > < div className = "kai-datesel-wrapper" tabIndex = { - 1 } onKeyDown = { this . onKeyDown } > { header ? < div className = "kai-datesel-header h1" > { header } < /div> : null} < div className = { `kai-datesel-container` } > < div className = "kai-datesel-content" > < TriColListView col1Children = { this . state . years . map ( ( item ) => ( < BodyTextListItem header = { item . toString ( ) } / > ) ) } col2Children = { this . state . months . map ( ( item ) => ( < BodyTextListItem header = { item . toString ( ) } / > ) ) } col3Children = { this . state . days . map ( ( item ) => ( < BodyTextListItem header = { item . toString ( ) } / > ) ) } onCol1ChangeIndex = { ( index ) => this . setYear ( index ) } onCol2ChangeIndex = { ( index ) => this . setMonth ( index ) } onCol3ChangeIndex = { ( index ) => this . setDay ( index ) } selectedCol1Index = { this . state . years . indexOf ( this . props . initialDate . getFullYear ( ) ) } selectedCol2Index = { this . props . initialDate . getMonth ( ) } selectedCol3Index = { this . state . days . indexOf ( this . props . initialDate . getDate ( ) ) } / > < /div> < /div> < /div> < SoftKey leftText = { "Cancel" } leftCallback = { ( ) => { this . closeWindow ( ) ; } } rightText = { "Select" } rightCallback = { ( ) => { onOK ( this . calcSelectedDate ( ) ) ; this . closeWindow ( ) ; } } /> < /div>); } calcSelectedDate ( ) { return new Date ( this . state . selectedYear , this . state . selectedMonth , this . state . selectedDay ) ; } setYear ( index ) { this . setState ( { selectedYear : this . state . years [ index ] } ) ; this . resetDaysForNewMonthYear ( ) ; } setMonth ( index ) { this . setState ( { selectedMonth : index + 1 } ) ; this . resetDaysForNewMonthYear ( ) ; } setDay ( index ) { this . setState ( { selectedDay : this . state . days [ index ] } ) ; } resetDaysForNewMonthYear ( ) { const minDay = 1 ; const maxDay = getDaysInMonth ( this . state . selectedMonth , this . state . selectedYear ) ; const days = [ ] ; for ( let i = minDay ; i <= maxDay ; i ++ ) { days . push ( i ) ; } this . setState ( { days } ) ; } } function showDateSelctor ( config ) { const div = document . createElement ( 'div' ) ; div . className = 'kai-datesel' ; document . body . appendChild ( div ) ; function render ( props ) { ReactDOM . render ( < DateSelector { ... props } / > , div ) ; } function closeWindow ( ) { ReactDOM . unmountComponentAtNode ( div ) ; document . body . removeChild ( div ) ; } render ( { ... config , close : closeWindow } ) ; } export { showDateSelctor } ; export default DateSelector ;