Simple JQuery Calendar Widget using moment.js
A Pen by James Barnett on CodePen.
| <h1>Simple Calendar Widget</h1> | |
| <div class = "wrapper"> | |
| <label for = "date">Date:</label> | |
| <input id = "date"/> | |
| <span class = "calendar-icon"></span> | |
| <div class = "calendar"> | |
| <span class = "month-prev"></span> | |
| <h2 id = "month" class = "month"></h2> | |
| <span class = "month-next"></span> | |
| <ol class = "weekdays"> | |
| <li>Sun</li> | |
| <li>Mon</li> | |
| <li>Tue</li> | |
| <li>Wed</li> | |
| <li>Thu</li> | |
| <li>Fri</li> | |
| <li>Sat</li> | |
| </ol> | |
| <div id = "days" class = "days"></div> | |
| </div> |
Simple JQuery Calendar Widget using moment.js
A Pen by James Barnett on CodePen.
| $(document).ready(function() { | |
| var timeframe = moment(); | |
| var dayOfWeekOffset = 0; | |
| var date = moment(); | |
| drawCalendar(); | |
| function drawCalendar(){ | |
| var output = "<ol>"; | |
| var days = moment(timeframe).daysInMonth(); | |
| var monthName = moment(timeframe).format("MMMM"); | |
| var startOfMonth = moment(timeframe).startOf('month'); | |
| /* Find the day of the week the month starting on | |
| so we can calculate the offset for days of the week to line up correctly */ | |
| dayOfWeekOffset = parseInt(moment(startOfMonth).format("d"),10); | |
| /* draw offset */ | |
| for (i = 0; i < dayOfWeekOffset; i++) { | |
| output += "<li>"; | |
| output += "</li>"; | |
| } | |
| /*** draw days ***/ | |
| for (i = 1; i <= days; i++) { | |
| output += "<li>"; | |
| output += i; | |
| output += "</li>"; | |
| } | |
| output += "</ol>"; | |
| document.getElementById("days").innerHTML = output; | |
| monthName = moment(timeframe).format("MMMM YYYY"); | |
| document.getElementById("month").innerHTML = monthName; | |
| markToday(); | |
| getSelectedDay(); | |
| } | |
| function getSelectedDay(){ | |
| $(".days li").click(function() { | |
| var myDay = $(this).text(); | |
| /* make sure user clicked on an actual day not one of the offset boxes */ | |
| if (!isNaN(parseInt(myDay, 10))){ | |
| var myMonth = moment(timeframe).format("M"); | |
| var myYear = moment(timeframe).format("YY"); | |
| $("input").val(myMonth + "/" + myDay + "/" + myYear); | |
| styleDateValidation(); | |
| styleSelectedDay(); | |
| } | |
| }); | |
| } | |
| function markToday(){ | |
| var dayOfMonth = moment().format("D"); | |
| var today = dayOfWeekOffset + parseInt(dayOfMonth, 10); | |
| /* because today is calculated using the day of month, double check it's the current month */ | |
| if (moment(timeframe).isSame(moment(), 'month')){ | |
| $( ".days li:nth-Child(" + today + ")" ).addClass( "today" ); | |
| } | |
| } | |
| /* parse date from input field & re-draw calendar*/ | |
| function parseDate(){ | |
| var dateRaw = $("input").val(); | |
| date = moment(dateRaw).format("YYYY-MM-DD"); | |
| if(date !== "Invalid date"){ | |
| timeframe = moment(date); | |
| drawCalendar(); | |
| styleSelectedDay(); | |
| return true; | |
| } else { return false; } | |
| } | |
| /* style input box to indicate a valid/invalid date */ | |
| function styleDateValidation(){ | |
| if (parseDate() === true) { | |
| if ($("input").hasClass( "valid-date" ) !== true) { | |
| $("input").addClass("valid-date"); | |
| } | |
| if ($("input").hasClass( "invalid-date" ) === true) { | |
| $("input").removeClass("invalid-date"); | |
| } | |
| } else { | |
| if ($("input").hasClass( "invalid-date" ) !== true) { | |
| $("input").addClass("invalid-date"); | |
| } | |
| if ($("input").hasClass( "valid-date" ) === true) { | |
| $("input").removeClass("valid-date"); | |
| } | |
| } | |
| } | |
| function styleSelectedDay(){ | |
| var selectedDayRaw = moment(date).format("D"); | |
| if (!isNaN(parseInt(selectedDayRaw, 10))){ | |
| var selectedDay = dayOfWeekOffset + parseInt(selectedDayRaw, 10); | |
| $( ".days li:nth-Child(" + selectedDay + ")" ).addClass( "selected-day" ); | |
| } | |
| } | |
| $(".calendar-icon").click(function() { | |
| $(".calendar").toggle(); | |
| }); | |
| $("input").click(function() { | |
| $(".calendar").show(); | |
| }); | |
| $("input").keyup(function() { | |
| styleSelectedDay(); | |
| styleDateValidation(); | |
| }); | |
| /*** change month on calendar ***/ | |
| $(".month-next").click(function() { | |
| timeframe = moment(timeframe).add('M', 1).format("YYYY-MM-DD"); | |
| drawCalendar(); | |
| }); | |
| $(".month-prev").click(function() { | |
| timeframe = moment(timeframe).subtract('M', 1).format("YYYY-MM-DD"); | |
| drawCalendar(); | |
| }); | |
| }); |
| @import url(http://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css); | |
| ol, li { margin: 0; padding: 0; list-style: none; } | |
| .wrapper { | |
| width: 330px; | |
| margin: 10px 40px; | |
| } | |
| h1 { | |
| font-size: 1.5em; | |
| margin-left: 20px; | |
| } | |
| label { margin: auto; } | |
| input { margin: 0 0 10px 10px;} | |
| .calendar { | |
| display: none; | |
| margin-left: 5px; | |
| width: 255px; | |
| color: #525252; | |
| } | |
| .days li:hover, .month-prev:hover, .month-next:hover, .calendar-icon { cursor: pointer; } | |
| .month, .month-prev, .month-next, .calendar-icon { font-size: 1.125em; } | |
| .month { | |
| width: 185px; | |
| display: inline-block; | |
| margin: 0; | |
| text-align: center; | |
| } | |
| .month-prev, .month-next, .calendar-icon { | |
| font-family: FontAwesome; | |
| padding: 3px; | |
| display: inline-block; | |
| } | |
| .calendar-icon:before { | |
| content: "\f073"; | |
| margin-left: 5px; | |
| } | |
| .month-prev:before { | |
| content: "\f0a8"; | |
| margin-left: 5px; | |
| } | |
| .month-next:before { | |
| content: "\f0a9"; | |
| margin-right: 5px; | |
| } | |
| .weekdays li, .days li { | |
| font-size: 13px; | |
| text-align: center; | |
| } | |
| .weekdays li { | |
| width: 20px; | |
| padding: 0 6px 5px 3px; | |
| margin-left: 2px; | |
| display: inline-block; | |
| } | |
| .days li { | |
| width: 20px; | |
| height: 20px; | |
| float: left; | |
| padding: 5px 5px 5px 10px; | |
| font-size: 13px; | |
| font-family: Tahoma, Verdana, sans-serif; | |
| font-weight: bold; | |
| } | |
| .days li:hover { | |
| color: royalblue; | |
| background: whitesmoke; | |
| } | |
| .today { | |
| color: indianred; | |
| background: whitesmoke; | |
| } | |
| /*** draw borders ***/ | |
| .days li { | |
| border-bottom: 1px solid darkgrey; | |
| border-right: 1px solid darkgrey; | |
| } | |
| .days li:nth-child(-n+7) { border-top: 1px solid darkgrey; } | |
| .days li:nth-child(7n+1) { border-left: 1px solid darkgrey; } | |
| /*** valid/invalid date field ***/ | |
| .valid-date { | |
| outline: none; | |
| border: 2px solid green; | |
| } | |
| .invalid-date { | |
| outline: none; | |
| border: 2px solid red; | |
| } | |
| .selected-day { | |
| background: whitesmoke; | |
| color: green; | |
| } |