Skip to content

Instantly share code, notes, and snippets.

@hmmhmmhm
Created October 30, 2018 06:11
Show Gist options
  • Save hmmhmmhm/8283f4bff837c9733324ac896089b4f3 to your computer and use it in GitHub Desktop.
Save hmmhmmhm/8283f4bff837c9733324ac896089b4f3 to your computer and use it in GitHub Desktop.
moment.js based calendar
import moment from 'moment'
class Calendar{
constructor(paramCalendarDiv, updateCallback) {
this.calendarDiv = paramCalendarDiv
this.monthPage = 0
this.activatedDay = null
this.callbacks = []
this.todayCallbacks = []
this.preCallbacks = []
this.data = {}
this.update = updateCallback
}
change(updateCallback){
this.update = updateCallback
}
// 계산된 현재 달력정보에 최초로 접근하는 콜백들
preRegister(paramPreCallback){
this.preCallbacks.push(paramPreCallback)
}
register(paramCallback, isOnlyWorkOnInToday){
if(isOnlyWorkOnInToday)
this.todayCallbacks.push(paramCallback)
else
this.callbacks.push(paramCallback)
}
prevMonthPage() {
--this.monthPage
this.update()
}
nextMonthPage() {
++this.monthPage
this.update()
}
static get(addMonth, date) {
let innerDate = date
if(innerDate == undefined) innerDate = moment()
if(addMonth == undefined) addMonth = 0
innerDate.month(innerDate.month() + addMonth)
let calendarFirstDay = Calendar.getWeeksFirstDay(Calendar.getCalendarFirstDay(innerDate))
return {
data: Calendar.buildMonth( calendarFirstDay, innerDate),
date: innerDate
}
}
static getCalendarFirstDay (date) {
let innerDate = date.clone()
return innerDate.date(1).day(0)
}
static getWeeksFirstDay (date) {
let innerDate = date.clone()
return innerDate.day(0).hour(0).minute(0).second(0).millisecond(0)
}
static buildMonth (currentTime, currentMonth) {
let weeks = []
let done = false
let date = currentTime.clone()
let monthIndex = date.month()
let count = 0
while (!done) {
weeks.push( this.buildWeek(date.clone(), currentMonth) )
date.add(1, 'w') // 다음 주로 이동
done = count++ > 2 && monthIndex !== date.month() // 달이 넘어 가면 멈춤
monthIndex = date.month()
}
return weeks
}
// 한주의 첫번째 날과 달의 정보를 받음
static buildWeek (date, currentMonth) {
let days = [] // 총 7일의 정보가 들어감
for (let i = 0; i < 7; i++) {
days.push({
// 요일[S-M-T-W]정보
name: date.format('dd').substring(0, 1),
// 일[0-1-2-3]정보
number: date.date(),
// 월 정보[1~12]
month: date.month()+1,
// 년 정보
year: date.year(),
// 현재 월인지
isCurrentMonth: date.month() === currentMonth.month(),
// 오늘인지
isToday: date.isSame(new Date(), 'day'),
// 실제 모멘트 오브젝트
date: date
})
date = date.clone()
date.add(1, 'd')
}
return days
}
}
export default Calendar
@hmmhmmhm
Copy link
Author

Calendar 클래스 사용 예제

import Calendar from '../../math/calendar.js'

// 달력 인스턴스 생성
let calendarInstance = new Calendar(targetCalendar, function (){
	let updatedCalendar = Calendar.get(this.monthPage)
	for(let loopPreCallback of this.preCallbacks)
		loopPreCallback(updatedCalendar)

	this.data = {}
	this.calendarDiv.innerHTML = ''

	for(let weekData of updatedCalendar.data){
		for(let dayData of weekData){
			let classData = ''

			if(!dayData.isCurrentMonth) classData += 'overday '

			// 술 먹었는지 여부
			let isRunnedDay = false

			// 디자인 테스트용 코드
			// if(dayData.number < 6 ) isRunnedDay = true

			// 이용자의 개인정보 반영
			let drinkMG = 0
			let moneyCount = 0
			let peopleCount = 1

			// drinkCount 는 mg 단위로 받아온 후
			// 현재 설정의 한 잔 mg로 나눠서 잔수로 변환합니다.
			let drinkCount = 0

			// 마신 횟수가 0보다 클때만 마신 날로 간주
			if(drinkCount > 0) isRunnedDay = true

			let targetDate = new Date(dayData.date)
			targetDate = targetDate.setDate(targetDate.getDate() + 1)
			let currentDateObj = new Date(targetDate)
			let lightData = getLightData(currentDateObj)
			let BMNT = `${lightData.dawn}`
			let EENT = `${lightData.dusk}`

			// 오늘 또는 안 먹은 날 또는 마신 날
			classData += (dayData.isToday) ? 'today ' : 'notrunnedday '

			// 일요일 색칠
			if(dayData.date.format('ddd') == 'Sun')
				classData += 'sunday '
			if(dayData.date.format('ddd') == 'Sat')
				classData += 'sat '

			let tempDiv = document.createElement('div')
			let dayNumber = String(dayData.number)
			if (dayNumber.length == 1) dayNumber = `0${dayNumber}`
			tempDiv.insertAdjacentHTML('beforeend',
				'<span class="' + classData + '">'
					+'<a class="day-present">' + dayNumber
					+	'<a class="day-info-1">' + BMNT + '</a>'
					+	'<a class="day-used-money">' + EENT + '</a>'
				+ '</a></span>')

			// {"name":"T","number":1,"month":5,
			// "isCurrentMonth":true,"isToday":false,
			// "date":"2018-04-30T15:00:00.000Z"}

			// 오늘 날짜 미리 선택시켜놓기
			if(dayData.isToday)
				for(let loopTodayCallback of this.todayCallbacks)
					loopTodayCallback(dayData, tempDiv)

			for(let loopCallback of this.callbacks)
				loopCallback(dayData, tempDiv)

			this.data[`${dayData.year}/${dayData.month}/${dayData.number}`] = tempDiv
			this.calendarDiv.insertAdjacentElement('beforeend', tempDiv)
		}
	}
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment