richardtallent / vue-simple-calendar Goto Github PK
View Code? Open in Web Editor NEWSimple Vue component to show a month-grid calendar with events
License: MIT License
Simple Vue component to show a month-grid calendar with events
License: MIT License
Here's a possible layout for a week view in flexbox.
I'm embarrassed to say that way multi-day events are rendered doesn't work with days that have a defined background color due to my completely forgetting about the z-index stacking context (which is different for each day since the events are grandchildren of the day they start).
There seem to be only two solutions:
Draw the calendar grid twice, once for borders and background colors and again for days and events, using the same metrics for both. This would put the events on a plane that is transparent, allowing them to "spill over" on top of siblings of their grandparent element. We can still use z-index to avoid vertical spilling.
Position each event relative to the grid upper-left corner, separately from rendering the grid. This can still be done with classes indicating the week number, day of week, and event number on that day. This would require having a hard-set day and event height, providing the end developer no flexibility in margins, padding, font size, or border size unless they override a significant number of classes.
The final solution is to simply not support background colors by the day. It would still be safe to do so to the day number row, but not the area where the events live. This may be the best short-term solution.
The other open issue is how to handle staggering of the "slots" for each day. The current approach minimizes overlap, but doesn't completely avoid it. To avoid overlap, each day must be rendered with knowledge of which "slots" are already spilling over from previous days of that week, and thus not reuse them. This is making me lean toward solution (2).
Not sure when I'll have time to work on this.
Chrome 61 on Mac OS X (Yosemite) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Depending on the viewport, the left border will not show up. This is an artifact of using percentages. I was able to fix this buy calculating the percentages rather than having them hard coded.
.calendar-month .event.offset0 { left: calc(.05em); }
.calendar-month .event.offset1 { left: calc(calc(100% / 7) + .05em); }
.calendar-month .event.offset2 { left: calc(calc(100% / 7) * 2 + .05em); }
.calendar-month .event.offset3 { left: calc(calc(100% / 7) * 3 + .05em); }
.calendar-month .event.offset4 { left: calc(calc(100% / 7) * 4 + .05em); }
.calendar-month .event.offset5 { left: calc(calc(100% / 7) * 5 + .05em); }
.calendar-month .event.offset6 { left: calc(calc(100% / 7) * 6 + .05em); }
.calendar-month .event.span1 { width: calc(calc(100% / 7) - .05em); }
.calendar-month .event.span2 { width: calc(calc(100% / 7) * 2 - .05em); }
.calendar-month .event.span3 { width: calc(calc(100% / 7) * 3 - .05em); text-align: center;}
.calendar-month .event.span4 { width: calc(calc(100% / 7) * 4 - .05em); text-align: center;}
.calendar-month .event.span5 { width: calc(calc(100% / 7) * 5 - .05em); text-align: center;}
.calendar-month .event.span6 { width: calc(calc(100% / 7) * 6 - .05em); text-align: center;}
.calendar-month .event.span7 { width: calc(calc(100% / 7) * 7 - .05em); text-align: center;}
Hello,
I would like to know if there is already a function that can display the calendar by years.
Thank's for your reply.
Not sure of the code issues, but March 2018 is getting off weeks. Not sure if this repeats throughout the different years.
Thanks.
Hello,
I try to use your calendar but I get:
ERROR in ./node_modules/babel-loader/lib?{"cacheDirectory":true,"presets":[["env",{"modules":false,"targets":{"browsers":["> 2%"],"uglify":true}}]],"plugins":["transform-object-rest-spread",["transform-runtime",{"polyfill":false,"helpers":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!./node_modules/vue-simple-calendar/src/components/calendar-month.vue Module build failed: Error: Couldn't find preset "stage-2" relative to directory "C:\\Users\\umignon\\projects\\capability\\node_modules\\vue-simple-calendar" at C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\options\option-manager.js:293:19 at Array.map (<anonymous>) at OptionManager.resolvePresets (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\options\option-manager.js:275:20) at OptionManager.mergePresets (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\options\option-manager.js:264:10) at OptionManager.mergeOptions (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\options\option-manager.js:249:14) at OptionManager.init (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\options\option-manager.js:368:12) at File.initOptions (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\index.js:212:65) at new File (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\file\index.js:135:24) at Pipeline.transform (C:\Users\umignon\projects\capability\node_modules\babel-core\lib\transformation\pipeline.js:46:16) at transpile (C:\Users\umignon\projects\capability\node_modules\babel-loader\lib\index.js:50:20) at C:\Users\umignon\projects\capability\node_modules\babel-loader\lib\fs-cache.js:118:18 at ReadFileContext.callback (C:\Users\umignon\projects\capability\node_modules\babel-loader\lib\fs-cache.js:31:21) at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:421:13) @ ./node_modules/vue-simple-calendar/src/components/calendar-month.vue 8:21-364 @ ./node_modules/babel-loader/lib?{"cacheDirectory":true,"presets":[["env",{"modules":false,"targets":{"browsers":["> 2%"],"uglify":true}}]],"plugins":["transform-object-rest-spread",["transform-runtime",{"polyfill":false,"helpers":false}]]}!./node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!./resources/assets/js/components/fullCalendar.vue @ ./resources/assets/js/components/fullCalendar.vue @ ./resources/assets/js/vue.js @ ./resources/assets/js/app.js @ multi ./resources/assets/js/app.js ./resources/assets/sass/app.scss npm ERR! code ELIFECYCLE npm ERR! errno 2 npm ERR! @ development:
cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the @ development script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\umignon\AppData\Roaming\npm-cache_logs\2017-12-15T14_48_05_818Z-debug.log
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.`
here is my app.vue:
<template>
<calendar-month
:show-date="showDate"
@setShowDate="setShowDate"
class="holiday-us-traditional holiday-us-official"
/>
</template>
<script>
import CalendarMonth from 'vue-simple-calendar/src/components/calendar-month'
require("vue-simple-calendar/static/css/default.css")
require("vue-simple-calendar/static/css/holidays-us.css")
export default {
data: function() {
return { showDate: new Date() }
},
components: {
CalendarMonth
},
methods: {
setShowDate(d) {
this.showDate = d;
},
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
color: #2c3e50;
height: 67vh;
width: 90vw;
margin-left: auto;
margin-right: auto;
}
</style>
here is my app.js:
import Vue from 'vue';
import app from './components/app.vue';
new Vue({
el: '#app',
components: {
app
}
});
Thanks for your replys !
Hi,
Is there a way to change the calendar day cell's class based on an event click? A simple use case will mark the cell as selected if an event of that specific day is clicked.
At this moment, I am making the event take all available space on the calendar day cell and change its class. But the issue is I lose the current day. I think to add it manually
Something like this:
I will appreciate any hint. Thanks in advance.
Hello, I am trying to use the component however after following the steps of Installation and use I came across this error.
Any idea what might be happening?
Error in ./~/vue-simple-calendar/src/components/calenda-month.vue
Module build failed: Error: Couldn't find preset "env" relative to directory "c:\Users\allan_vieira\front\sicred-front\node_modules\vue-simple-calendar"
Hey Rich,
Regarding getting this on NPM I'd love to see this! Currently manually using this in a new project and just trying to get the next and previous buttons working!
I found this which might be of help: https://docs.npmjs.com/getting-started/publishing-npm-packages. Also we use Yarn a lot, and I know many others do so might be worth looking at getting it up on there too: https://yarnpkg.com/en/docs/creating-a-package
If you want to give it a shot, let me know and I'll try it locally when done :)
Is it possible, using slots, to create events which contain images, buttons and other components?
I'm looking to create something similar to falcon.io
Get the above Vue warning when running calendar (got it before updates as well).
I think the solution is to change line:
<div v-for="day in daysOfWeek(weekStart)" class="day" :key="day" :class="[
to
<div v-for="(day, dayIndex) in daysOfWeek(weekStart)" class="day" :key="dayIndex" :class="[
Seem to be having no issues with making this change (I did locally).
Thanks.
I took the minimal application example for a calendar and added some events.
However it seems like the height of the cells doesn't adjust to the number of events so it only shows one event for each day.
Hi there! When I have 3 events all on the same day in my google calendar, for some reason they are displayed oddly in the table-cell for that date. Each event starts and ends on the same date - but as you'll see in my screenshot,
I changed one of the items to 2017-03-14 (March 14th, 2017) and ended on 2017-03-17 (March 17th, 2017). This particular item did not render into the correct day. Not sure if same thing happens else where.
It's currently November and when clicking back to October it adds the class future
and when clicking forward to December it adds class past
. Seems like it should be the other way around, no?
Just need to swap the comparisons on the isPastMonth() and isFutureMonth() functions.
Theming ideas:
Disable past prop works fine, but you can navigate forward with disabled future using dayClick.
Take a look at the Multi-day event on the demo. The dayDiff() function is calculating 12 - 5 = 7 so it thinks it doesn't spill over to the next week. If times were included it would still break because of the now included round() function. For now it would work to change the condition to >= 7.
Very nice project, congratulations.
I would like to use it for my client's platform, however they support the following browsers:
I found no indication of which browsers are supported in the readme, and found out that the demo page does not work on IE11. I get TypeError: Object doesn't support property or method 'fill', which could be fixed easily by a polyfill. But maybe it's a conscious decision on your part not to go there.
Anyway it would be nice to have the supported/tested browsers in the readme.
Also, the readme contains a lot of information. You could split that into release notes (for breaking changes and such) attached to the release and move some into the Wiki pages. It would make it easier for people to discover your projet and evaluate it, I believe.
Keep up the great work!
Any plans for an agenda in the future? I read in the Features section: "There is no "agenda" view (time-of-day grid). This would require adding too much complexity."
But is there a plan for this? Also, if there is a hint on how to do it, I could help with it.
I would like to display a calendar with 8 days
The demo works great when run using npm run dev
, but serving the files statically on my Apache server breaks them.
The index.html
file is saved in UTF-8 according to Visual Studio Code, Apache is set to default to UTF-8, and the response headers look fine in Chrome, but I'm still seeing garbled characters rather than the emoji.
Not sure what's going on, hoping someone else has a clue.
When I push event to the events array, it is not rendered. When I remove event it works fine.
hi there, drag and drop works fine in chrome and opera, but not in firefox or edge,
is there a fix or a known problem
thanks for info
marc
I have been trying to override event template with my own, however it seems that the event
prop returned is incorrect (data described (here)[https://github.com/richardtallent/vue-simple-calendar#event] is missing).
This template code:
<template slot="event" slot-scope="props">
<div>
@{{ props.event }}
</div>
</template>
Produces this result (event passed into events
list):
{ "startDate": "2018-02-01 09:00:00", "endDate": "2018-02-01 10:30:00", "title": "Event 1" }
Digging into the source code I found that it actually returns originalEvent
itself and not normalized version, which would return something like this:
{ "originalEvent": { "startDate": "2018-02-01 09:00:00", "endDate": "2018-02-01 10:30:00", "title": "Event 1" }, "startDate": "2018-02-01T06:00:00.000Z", "endDate": "2018-02-01T07:30:00.000Z", "classes": [ "offset4", "span1", "eventRow1" ], "title": "Event 1", "id": "eg4fdt523xk", "eventRow": 0 }
I guess it's a bug? If so, I created a pull request fixing this: #41
Otherwise this is a great component, thank you for your hard work!
I have the version 2.1.3
of this package installed. I try to change the event markup a bit:
<div slot="event" slot-scope="e"
class="event"
:class="e.classes"
:key="e.id">
{{ e }}
</div>
If i output {{ e }} it returns me
{ "event": { "startDate": "2018-03-13", "id": 677, "title": "My Series" }, "weekStartDate": "2018-03-10T23:00:00.000Z" }
I also tried it with slot-scope="props"
which you say here #44 but there is an error in your example code (e does not exists), and it does also not work.
Sorry if i missing somethin, but is there a way to change style of clicked day/event?
It will be very nice to have special class added to clicked element.
Thanks for the solid component!
When I click on a date in your demo, it reports that I clicked on a different date. For instance, if i click on 22 June 2017, it reports "You clicked: 2017-06-21".
I haven't looked any deeper, but could it be a locale issue (I'm east coast Australia, GMT +10)?
I'd like to get this plugin working with SSR.
So far I've been using no-ssr to avoid errors on the server, but I'd like this to work on the server too.
This is a feature request, I'll be glad to help if needed.
I think the mixins file and the vue should be in the same base directory, for instance:
/components/calender-month.vue
/components/mixins/mixin-calendarMath.js
Then change the imports
to match. Not a hard change when including the code in your own projects, but allows for self containing if a 3rd party is using a common components directory for multiple 3rd party components (like we are) ๐
I want to change event HTML completely as i did in fullcalendar
library. I used slot for this purpose but all events floated to right side because these classes like event offset2 span1 eventRow1
are not added if i use slot. Is there anything i am missing ?
<calendar-view :events="events"
:startingDayOfWeek="parseInt(changeCalendarStartDay)"
:displayPeriodUom="changeCalendarView"
:show-date="showDate"
@setShowDate="setShowDate"
class="holiday-us-traditional holiday-us-official">
<template slot="event" slot-scope="props" >
<div>
{{ props.event.title }}
</div>
</template>
</calendar-view>
Event array is look like this :
events:[
{
startDate:'2018-02-08',
title:'Event1',
classes:'testing'
},
{
startDate:'2018-02-07',
title:'Event2'
},
{
startDate:'2018-02-09',
title:'Event3'
},
]
I got result like this below :
What i exactly want is to modify event HTML according to my need. Below example image of my current fullcalendar
library preview.
The drag and drop functionality currently does not support touch devices. I haven't looked into whether this is easy enough to do in vanilla JS or if adding a dependency to deal with various platform differences will be more practical.
May want to support "ghost" positioning during the drag event (i.e., being able to see the other events "open up" the place where the current event would be positioned).
Hello! Can you add some basic information like "Getting starting" or simple example?
Well it depends what it's supposed to do. I expect it should be used to decorate days which are not in the month being shown - the max 6 days at the start and the end. If you check the demo, you can see the defect.... click "next month", and pretty much everything is out side that "next" month. Maybe that's by design, but it's not what I'd expect.
Hello Richard, thank you so much for this fine component!
I am trying to figure out how to deal with events overflowing their respective day. As you align them absolutely, scrolling within the day is not really an option. Do you have any suggestions? Would you think attempting to refactor the day + events into a self-sizing, scroll-compatible flexbox would be good? I can likely provide a pull request if you feel this is a good idea, but since I expect you already have some experience / learnings from building the thing in the first place, I'd ask.
Date/time math on any platform is always a minefield, and in JavaScript, even moreso.
To help prevent regressions or new bugs, it would probably be a good idea to set up some unit tests for this mixin's methods.
Possibly using Karma?
This was on the wish-list but not identified as an issue yet. The control should allow for starting on days of the week other than Sunday. I've made the changes for 4.7.0, coming soon.
The main sections that the reamed should start with:
startDate: reservationData.time_raw,
endDate: reservationData.time_raw,
title: '
' + reservationData.name + '
',All working good, but not url, any suggestion?
In 3.0, I'd like to revamp the current primary class names to be flatter (more unique, with no cascaded selectors needed to target most elements), which will simplify both the core and default CSS as well as custom themes. Here are my thoughts so far:
Element | Current Class | New Class |
---|---|---|
Root | calendar-view | cv-wrapper |
Header | header | cv-header |
Period | periodLabel | cv-header-period |
Button area | nav | cv-header-nav |
DOW header | dayList | cv-header-days |
DOW name | day | cv-header-day |
Weeks | weeks | cv-weeks |
Week | week | cv-week |
Day | day | cv-day |
Day content | content | cv-day-content (may look into removing this, can't recall if it's needed anymore) |
Day number | date | cv-day-number |
Event | event | cv-event |
Note that while the list of day names is a "header" of sorts, it lives below the div.header
element, not as a child of it (no change there).
No changes are proposed currently for the "modifier" classes (such as dMM-DD
, instanceX
, and singleMonth
).
However, I am considering dropping the complex periodLabel
child elements and just using a function (and like everything in the header, adding a slot to override it) to format the date period. The CSS-only thing was a cool use of pseudo-element content, but isn't easy to override and makes localized assumptions about date formatting. CSS content for the header buttons will also be replaced with static text, with slots to allow replacing the buttons.
I also need to test to see if I can remove the z-index calculation for weeks and events. Recent changes to how weeks are rendered may make these computations unnecessary.
Finally, I'll be looking into replacing the eventRowX classes with a calculated
style`. This will remove the artificial limitation of 20 events in a given day (as high a number as that is), and should make it easier to override if your slotted or themed events' padding/border/font metrics don't match the default.
The demo shown here causes the Vue development tools to barf with the message below. The cause is that the event name is emitted as setShowDate instead of set-show-date (line 329 etc).
That works ok if you embed this as a component inside another Vue component, but if (like me) you just want to drop it into a HTML file then... it doesn't work. The work-around is to rename the events in the distribution so the event names have hyphens in them, then it works.
Oh, other events have the same issue.
""Event "setshowdate" is emitted in component at src/CalendarView.vue but the
handler is registered for "setShowDate". Note that HTML attributes are case-insensitive and you cannot use v-on to listen to camelCase events when using in-DOM templates. You should probably use "set-show-date" instead of "setShowDate".
This might sound slightly strange but hear me out. One of vue's weaknesses seems to be the inability to either disable or completely override the style portion of an included vue component such as simple calendar.
The 'base style' serves as a great starting point, and obviously will be very helpful in most situations.
However in those situations where you want to have your own style, the only way to do this is to add your own style, and use a ton of important tags.
My suggestion would be a very minor change to essentially split the 'default' theme to be loaded up by a class instead of applying it out of the box.
E.g instead of this showing the default style:
<calendar-view :show-date="showDate" @setShowDate="setShowDate" />
Have it so that to show the default style you do something like this:
<calendar-view :show-date="showDate" @setShowDate="setShowDate" class="sc-default" />
Happy to send over a pull request should there be any interest in this.
I am in need of this feature. I saw your notes on this issue #23 and see that you are interested in seeing a use case:
Online Time Tracker - Adding time to projects/jobs, then being able to see how/where time was spent, where you were able to multi-task (multiple columns where same day/time), as well as see "dead space" where you don't have any time logged.
I have a few small goals for v.1.5, feedback welcome:
Minimize component-level CSS. Like HTML itself, the best web components are styled primarily by the calling page. Any CSS not needed for the functionality of the calendar itself will be moved to an external spreadsheet so users can more easily theme their own calendar.
Enable drag and drop on mobile. Possibly enable "ghost" positioning during the drag event (i.e., being able to see the other events "open up" the place where the current event would be positioned).
Considering using some style attributes rather than classes for positioning of events. Using classes makes it more complicated than it should be for someone to tweak the style of the events (padding, borders, font size relative to the calendar, etc.). Not decided yet. CSS variables would be better, but the web just isn't there yet.
Fix a few issues I believe could still crop up related to use of date.toIsoString() when I really just want the local date in ISO format.
Clean up and organize the methods. My gut tells me I'm over-using methods and there's a cleaner way to handle all of the miscellaneous date transformation/comparison methods. In general I feel like some of the state management of the dates and events should be less coupled to the specific header and template I'm using, since much of it could be used for date-picking or other calendar-related components.
In planning future revisions, I'm considering dropping official IE11 support for the following reasons:
So, for anyone using this component, what's your situation around the need for IE11 support?
in the README.md file there is this code:
<script>
import CalendarView from "vue-simple-calendar"
require("vue-simple-calendar/dist/static/css/default.css")
require("vue-simple-calendar/dist/static/css/holidays-us.css")
</script>
However, including the two require()
directives results in a parse error for me; the compiler is treating the CSS, well, as CSS.
Am I missing a plugin or is my environment not right? Please and thanks for your help.
Hi,
First of all, great plugin!
Could you please release 2.2.1 on npm to make it easier to install for those of us that need IE 11 support ?
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.