VueJS Calendar Component
How do I make an vuejs calendar component?
A responsive calendar component written with the awesome VueJS. Should meet accessibility requirements and very easily adapt to different screen sizes.. What is a vuejs calendar component? How do you make a vuejs calendar component? This script and codes were developed by Altitude on 05 September 2022, Monday.
VueJS Calendar Component - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>VueJS Calendar Component</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <style> /* NOTE: The styles were added inline because Prefixfree needs access to your styles and they must be inlined if they are on local disk! */ @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,100);
html { min-height: 100%;
}
body { min-height: 100%; font-family: "Open Sans"; font-size: 16px; font-weight: 300; line-height: 1.5; color: #555; background: linear-gradient(45deg, #B62B10 30%, #222); background: #e0e0e0; padding: 4rem;
}
#app { background: rgba(255, 255, 255, 0.9); padding: 4rem;
}
.calendar > .title { font-size: 2.5rem; font-weight: 100; margin-bottom: 2rem; color: #222;
}
.calendar > .title > * { display: inline;
}
.calendar .days { list-style: none; margin: 0 0 0 0; padding: 0;
}
.calendar .days > .day.outside { display: none;
}
.calendar .days > .day.empty { display: none;
}
.calendar .days .events { margin-bottom: 1rem;
}
.calendar .days .events .event { box-sizing: border-box; line-height: 1; font-size: .75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: rgba(182, 43, 16, 0.05); color: #B62B10; padding: .25rem .5rem; margin-bottom: 2px; cursor: pointer; transition: all .1s ease-in-out;
}
.calendar .days .events .event:hover, .calendar .days .events .event:focus { background: rgba(182, 43, 16, 0.1);
}
.calendar .days .events .event:active { color: white; background: #b62b10;
}
.calendar .days .date { position: relative; font-size: 1.25rem; margin-bottom: 1rem; padding-bottom: .5rem;
}
.calendar .days .date:after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor; opacity: .5;
}
.calendar .days .date > * { display: inline-block;
}
.calendar .days .date .weekday { font-weight: 400; color: #B62B10; text-transform: uppercase;
}
.calendar .days .date .weekday:after, .calendar .days .date .day:after { content: ',';
}
@media (min-width: 1024px) { .calendar { border-bottom: 2px solid #B62B10; } .calendar .days { position: relative; display: flex; justify-content: flex-start; align-items: stretch; flex-wrap: wrap; } .calendar .days > .day { position: relative; font-size: .75rem; margin-bottom: 0; padding: 0 0 15% 0; width: 14.28571%; flex-shrink: 0; } .calendar .days > .day:before { content: ''; position: absolute; left: 0; right: .5rem; top: 0; height: 1px; background: currentColor; opacity: .5; } .calendar .days > .day .date { position: absolute; top: 1rem; font-size: 1rem; line-height: 1rem; } .calendar .days > .day .date:after { display: none; } .calendar .days > .day .date .weekday, .calendar .days > .day .date .month, .calendar .days > .day .date .year { display: none; } .calendar .days > .day .date .day:after { content: ""; } .calendar .days > .day.outside { display: inline-block; } .calendar .days > .day.outside:before { opacity: .125; } .calendar .days > .day.outside .date .day { opacity: 0.5; } .calendar .days > .day.empty { display: inline-block; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) { margin-top: 2rem; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7):before { opacity: 1; height: 2px; background: #B62B10; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) .date { width: 100%; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) .date .weekday { display: block; position: absolute; top: -3rem; width: 100%; overflow: hidden; text-transform: uppercase; font-weight: 300; color: #B62B10; text-overflow: ellipsis; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) .date .weekday:after { content: ""; } .calendar .days > .day .events { box-sizing: border-box; position: absolute; height: 100%; width: 100%; padding-top: 2.5rem; padding-right: .5rem; overflow: auto; } .calendar .days > .day .events .event { box-sizing: border-box; line-height: 1; font-size: .75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: rgba(182, 43, 16, 0.05); color: #B62B10; padding: .25rem .5rem; margin-bottom: 2px; cursor: pointer; transition: all .1s ease-in-out; } .calendar .days > .day .events .event:hover, .calendar .days > .day .events .event:focus { background: rgba(182, 43, 16, 0.1); } .calendar .days > .day .events .event:active { color: white; background: #b62b10; }
} </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
<body> <div id="app"> <calendar></calendar>
</div>
<template id="calendar-template"> <div class="calendar"> <div class="title"> <div class="month"> {{monthName}} </div> <div class="year"> {{year}} </div> </div> <ol class="days"> <li class="day" v-for="day in days | orderBy 'unix' 1" v-bind:class="{ 'outside': day.outsideOfCurrentMonth, 'empty': day.events.length === 0 }"> <div class="date"> <span class="weekday">{{day.weekday}}</span> <span class="month">{{day.month}}</span> <span class="day">{{day.number}}</span> <span class="year">{{day.year}}</span> </div> <div class="events"> <div v-for="event in day.events" class="event" v-bind:class="{'first': event.firstInRange, 'last': event.lastInRange }">{{event.title}} </div> </div> </li> </ol> </div>
</template> <script src='https://cdn.jsdelivr.net/vue/1.0.15/vue.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.1/moment.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
VueJS Calendar Component - Script Codes CSS Codes
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,100);
html { min-height: 100%;
}
body { min-height: 100%; font-family: "Open Sans"; font-size: 16px; font-weight: 300; line-height: 1.5; color: #555; background: linear-gradient(45deg, #B62B10 30%, #222); background: #e0e0e0; padding: 4rem;
}
#app { background: rgba(255, 255, 255, 0.9); padding: 4rem;
}
.calendar > .title { font-size: 2.5rem; font-weight: 100; margin-bottom: 2rem; color: #222;
}
.calendar > .title > * { display: inline;
}
.calendar .days { list-style: none; margin: 0 0 0 0; padding: 0;
}
.calendar .days > .day.outside { display: none;
}
.calendar .days > .day.empty { display: none;
}
.calendar .days .events { margin-bottom: 1rem;
}
.calendar .days .events .event { box-sizing: border-box; line-height: 1; font-size: .75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: rgba(182, 43, 16, 0.05); color: #B62B10; padding: .25rem .5rem; margin-bottom: 2px; cursor: pointer; transition: all .1s ease-in-out;
}
.calendar .days .events .event:hover, .calendar .days .events .event:focus { background: rgba(182, 43, 16, 0.1);
}
.calendar .days .events .event:active { color: white; background: #b62b10;
}
.calendar .days .date { position: relative; font-size: 1.25rem; margin-bottom: 1rem; padding-bottom: .5rem;
}
.calendar .days .date:after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: currentColor; opacity: .5;
}
.calendar .days .date > * { display: inline-block;
}
.calendar .days .date .weekday { font-weight: 400; color: #B62B10; text-transform: uppercase;
}
.calendar .days .date .weekday:after, .calendar .days .date .day:after { content: ',';
}
@media (min-width: 1024px) { .calendar { border-bottom: 2px solid #B62B10; } .calendar .days { position: relative; display: flex; justify-content: flex-start; align-items: stretch; flex-wrap: wrap; } .calendar .days > .day { position: relative; font-size: .75rem; margin-bottom: 0; padding: 0 0 15% 0; width: 14.28571%; flex-shrink: 0; } .calendar .days > .day:before { content: ''; position: absolute; left: 0; right: .5rem; top: 0; height: 1px; background: currentColor; opacity: .5; } .calendar .days > .day .date { position: absolute; top: 1rem; font-size: 1rem; line-height: 1rem; } .calendar .days > .day .date:after { display: none; } .calendar .days > .day .date .weekday, .calendar .days > .day .date .month, .calendar .days > .day .date .year { display: none; } .calendar .days > .day .date .day:after { content: ""; } .calendar .days > .day.outside { display: inline-block; } .calendar .days > .day.outside:before { opacity: .125; } .calendar .days > .day.outside .date .day { opacity: 0.5; } .calendar .days > .day.empty { display: inline-block; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) { margin-top: 2rem; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7):before { opacity: 1; height: 2px; background: #B62B10; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) .date { width: 100%; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) .date .weekday { display: block; position: absolute; top: -3rem; width: 100%; overflow: hidden; text-transform: uppercase; font-weight: 300; color: #B62B10; text-overflow: ellipsis; } .calendar .days > .day:nth-child(n+1):nth-child(-n+7) .date .weekday:after { content: ""; } .calendar .days > .day .events { box-sizing: border-box; position: absolute; height: 100%; width: 100%; padding-top: 2.5rem; padding-right: .5rem; overflow: auto; } .calendar .days > .day .events .event { box-sizing: border-box; line-height: 1; font-size: .75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: rgba(182, 43, 16, 0.05); color: #B62B10; padding: .25rem .5rem; margin-bottom: 2px; cursor: pointer; transition: all .1s ease-in-out; } .calendar .days > .day .events .event:hover, .calendar .days > .day .events .event:focus { background: rgba(182, 43, 16, 0.1); } .calendar .days > .day .events .event:active { color: white; background: #b62b10; }
}
VueJS Calendar Component - Script Codes JS Codes
'use strict';
Vue.config.debug = true;
var randomIntRange = function randomIntRange(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min;
};
var Events = { get: function get(startDate, endDate) { return new Promise(function (resolve, reject) { // TODO: Replace with actual API request // Generate some dummy events var events = []; var start = moment(startDate); var end = moment(endDate); var days = end.diff(start, 'days'); for (var i = 0; i < days / 4; i++) { var m = start.clone().add(randomIntRange(0, days), 'days'); events.push({ "id": i, "title": "Event " + i, "startDateTime": m.add(randomIntRange(0, 24), 'hours').toISOString(), "endDateTime": m.add(randomIntRange(1, 3 * 24), 'hours').toISOString() }); } resolve(events); }); }
};
var Calendar = Vue.extend({ template: '#calendar-template', props: { 'month': { default: moment().month() + 1 }, 'year': { default: moment().year() } }, data: function data() { return { loading: true, days: [] }; }, ready: function ready() { this.getEvents(); }, computed: { startDate: function startDate() { return moment().year(this.year).month(this.month - 1).startOf('month'); }, endDate: function endDate() { return this.startDate.clone().add(this.startDate.daysInMonth() - 1, 'days'); }, monthName: function monthName() { return moment().month(parseInt(this.month) - 1).format('MMMM'); } }, methods: { getEvents: function getEvents() { var self = this; Events.get(self.startDate.toISOString(), self.endDate.toISOString()).then(function (events) { // We have our events but we need to split up multi-day events into individual occurances var start = null; var end = null; var span = 1; var seriesEvents = []; for (var _iterator = events, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { if (_isArray) { if (_i >= _iterator.length) break; event = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; event = _i.value; } start = moment(event.startDateTime); end = moment(event.endDateTime); span = end.diff(start, 'days') + 1; event.parentId = event.id; if (span > 1) { event.firstInRange = true; event.lastInRange = false; for (var s = 1; s < span; s++) { seriesEvents.push({ "id": 0, "parentId": event.parentId, "firstInRange": false, "lastInRange": s === span - 1, "title": event.title, "startDateTime": start.clone().add(s, 'days').toISOString(), "endDateTime": end.toISOString() }); } } else { event.firstInRange = true; event.lastInRange = true; } } // Attempt to sort by time and event group bias // TODO: Remove or find a better solution events = events.concat(seriesEvents).sort(function (a, b) { var keyA = new Date(a.unix), keyB = new Date(b.unix); var bias = a.id === 0 ? 1 : 0; if (keyA < keyB) return -1 + bias; if (keyA > keyB) return 1 + bias; return 0 + bias; }); self.updateDays(events); self.loading = false; }); }, updateDays: function updateDays(events) { var _this = this; var m = function m() { return moment().year(_this.year).month(_this.month - 1).startOf('month'); }; var daysInMonth = m().daysInMonth(); var previousMonthDays = m().date(1).day(); var offset = 0 - previousMonthDays; var nextMonthDays = offset + (6 - m().date(daysInMonth).day()); var total = daysInMonth + previousMonthDays + nextMonthDays; var days = []; for (var i = offset; i < total; i++) { var current = m().add(i, 'd'); days.push({ outsideOfCurrentMonth: i < 0 || i > daysInMonth - 1 ? true : false, date: current, unix: current.valueOf(), weekday: current.format('dddd'), day: current.format('Do'), number: current.format('D'), month: current.format('MMMM'), year: current.format('YYYY'), events: events.filter(function (event) { return current.isSame(event.startDateTime, 'day'); }) }); } this.days = days; } }
});
new Vue({ el: '#app', components: { Calendar: Calendar }
});
Developer | Altitude |
Username | altitudems |
Uploaded | September 05, 2022 |
Rating | 3.5 |
Size | 8,913 Kb |
Views | 60,720 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
CSS3 Buttons | 5,428 Kb |
Jquery Tab Plugin | 5,471 Kb |
Simple Grid System | 6,136 Kb |
Semantic Tableless Calendar and Agenda | 6,099 Kb |
Simple Tile Map with easel.js | 2,895 Kb |
Responsive, Fullscreen Slider | 5,472 Kb |
VueJS Audio Mixer | 10,100 Kb |
Simple CSS Ribbon and Banner | 3,871 Kb |
Semantic Tableless Calendar | 4,528 Kb |
Custom Social Feeds | 3,750 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
A Pen by MurabitoB | MurabitoB | 4,421 Kb |
Bootstrap example | Ssaakkaa | 2,716 Kb |
Simple content swap | Snografx | 1,859 Kb |
Shape Outside - Polygon | Stacy | 3,954 Kb |
My Starter Kit For Codepen | Dkdesign | 2,012 Kb |
RequestAnimationFrame | Martin-banks | 2,541 Kb |
Text Blocks Over Image, Updated | KatieK2 | 3,122 Kb |
Twitch.tv API | Ryzokuken | 2,618 Kb |
Project_one | MOHIM | 9,592 Kb |
Countdown Timer | Massiebn | 3,001 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!