Skip to content

Instantly share code, notes, and snippets.

@arnabdas
Created December 26, 2016 10:43
Show Gist options
  • Save arnabdas/34083b2c78cd17b988ed96a009ce0ad1 to your computer and use it in GitHub Desktop.
Save arnabdas/34083b2c78cd17b988ed96a009ce0ad1 to your computer and use it in GitHub Desktop.
A very simple datepicker with ReactJS
// Variables
$default-font-color: rgb(119, 119, 119);
$rem-cal-background: rgba(232, 232, 232, 1);
.rem-cal {
position: relative;
.rem-cal-wrapper {
position: relative;
display: none;
z-index: 10;
&.open {
display: inline-block;
}
.rem-cal-triangle-up {
position: absolute;
left: -.9em;
width: 0;
height: 0;
left: 2.5em;
top: -15px;
border-left: .9em solid transparent;
border-right: .9em solid transparent;
border-bottom: .9em solid $rem-cal-background;
}
.rem-cal-content {
position: absolute;
min-height: 120px;
min-width: 250px;
left: 0.5em;
top: -3px;
padding: 3px;
border-radius: 4px;
background: $rem-cal-background;
.rem-cal-header {
height: 2em;
.rem-cal-header-nav {
margin: .5em .2em;
cursor: pointer;
color: lighten($default-font-color, 30%);
&:hover {
color: lighten($default-font-color, 20%);
}
}
.rem-cal-header-info {
font-size: 1.4em;
top: 1px;
}
}
.rem-cal-month {
background: lighten($rem-cal-background, 80%);
.rem-cal-cell {
cursor: pointer;
width: 2.5em;
padding: .1em;
font-size: .9em;
text-align: center;
display: inline-block;
&:hover {
color: darken($default-font-color, 20%);
}
}
}
}
}
}
/// <reference path="../../../typings/index.d.ts" />
import * as React from 'react';
import * as ReactDOM from 'react-dom';
export interface DatepickerProps { format?: string, onChange?: () => {}, selectedDate?: string };
export interface DatepickerState {
isOpen?: boolean,
dateToShow?: string,
showingMonth?: number,
showingYear?: number,
selectedDate?: Date,
monthArray?: Array<string>
};
export class Datepicker extends React.Component<DatepickerProps, DatepickerState> {
_mounted: boolean;
constructor() {
super();
}
componentWillMount() {
let selectedDate = new Date();
if (this.props.selectedDate) {
selectedDate = new Date(this.props.selectedDate);
}
this.setState({
isOpen: false,
selectedDate: selectedDate,
dateToShow: `${selectedDate.getDate()}/${selectedDate.getMonth()+1}/${selectedDate.getFullYear()}`
});
this.setMonthArray(selectedDate.getFullYear(), selectedDate.getMonth());
}
navigateMonth(isFwd: boolean) {
let currentYear = this.state.showingYear;
let currentMonth = this.state.showingMonth;
currentMonth = isFwd ? currentMonth + 1 : currentMonth - 1;
if (currentMonth > 11) {
currentMonth = 0;
currentYear += 1;
}
else if (currentMonth < 0) {
currentMonth = 11;
currentYear -= 1;
}
this.setMonthArray(currentYear, currentMonth);
}
setMonthArray(year: number, month: number) {
let firstDay = (new Date(year, month)).getDay();
let daysInMonthExtended = (new Date(year, month, 0)).getDate() + firstDay;
let monthArray = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
for (var i = 0; i <= daysInMonthExtended; i++) {
if (i < firstDay) {
monthArray.push('');
}
else {
monthArray.push((i - firstDay + 1).toString());
}
}
this.setState({
monthArray: monthArray,
showingMonth: month,
showingYear: year
});
}
showCalendar() {
if (this.state.isOpen) {
return;
}
let showingMonth = this.state.selectedDate.getMonth();
let showingYear = this.state.selectedDate.getFullYear();
this.setMonthArray(showingYear, showingMonth);
this.setState({
isOpen: true,
showingMonth: showingMonth,
showingYear: showingYear
});
}
setSelectedDate(d: string) {
let selectedDay = Number(d);
if (isNaN(selectedDay)) {
return;
}
let selectedDate = new Date(this.state.showingYear, this.state.showingMonth, selectedDay);
this.setState({
isOpen: false,
selectedDate: selectedDate,
dateToShow: `${selectedDate.getDate()}/${selectedDate.getMonth() + 1}/${selectedDate.getFullYear()}`
});
}
render() {
return (
<div className="rem-cal">
<input type="text" className="form-control" placeholder={this.props.format} onFocus={() => { this.showCalendar() } } value={this.state.dateToShow} />
<div className={this.state.isOpen ? 'rem-cal-wrapper open' : 'rem-cal-wrapper'}>
<div className="rem-cal-triangle-up" />
<div className="rem-cal-content" >
<div className="rem-cal-header text-center" >
<span className="rem-cal-header-nav glyphicon glyphicon-triangle-left pull-left" onClick={() => { this.navigateMonth(false) } } />
<span className="rem-cal-header-info">{
['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'][this.state.showingMonth] }, {this.state.showingYear }</span>
<span className="rem-cal-header-nav glyphicon glyphicon-triangle-right pull-right" onClick={() => { this.navigateMonth(true) } } />
</div>
<div className="rem-cal-month">
{this.state.monthArray.map(function (d) {
return (
<span className="rem-cal-cell" onClick={() => { this.setSelectedDate(d) } }>{d}</span>
);
}.bind(this)) }
</div>
</div>
</div>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment