fullcalendar / fullcalendar

Full-sized drag & drop event calendar in JavaScript
https://fullcalendar.io
MIT License
18.56k stars 3.61k forks source link

when snapDuration larger than slotDuration, buggy selection/dragging #4865

Open giumax87 opened 7 years ago

giumax87 commented 7 years ago

I have a problem when I try to select. Here there is an example: http://jsbin.com/fofegi/3/edit?js,output If I set slotDuration to a fraction of a day I can't select from the second slot to the last, try it on the second day, click on the second or third slot and the selection jump to the first day. I want to select from the second half of a day to che first half of the next day. Is possible to force the selection of half day on the start end on the end of a selection?

Thanks. PS same problem if I try to drag

arshaw commented 7 years ago

thanks, i can reproduce. event dragging is also buggy in this instance

arshaw commented 7 years ago

this seems to only be happening when the snapDuration is larger than the slotDuration

giumax87 commented 7 years ago

it also happens if the snapDuration is minor than slotDuration, just acts in a different way. Try on select. Also on resizing there is similar problem. Thanks

juan0087 commented 6 years ago

Did you guys find a solution to this problem yet? Having the same problem here. I have the slots set to slotDuration: { hours: 12 }, (2 slots per day) but I want a 24 hour snapDuration. While it does work, it's very buggy.

The reason I'm doing it this way is because this calendar is for Hotels, check-in in done on the second slot of the arrival day and the check-out in the first slot of the departure date.

I'd appreciate any suggestions!

acerix commented 4 years ago

In v4 timegrid, snapDuration does not seem to do anything when longer than slotDuration.

https://codepen.io/acerix/pen/vYYMEoP

Illizian commented 3 years ago

Hey @acerix & @arshaw, thanks for the library!

I'm also having issues where snapDuration > slotDuration and must admit that whilst instances where snapDuration is less it does work, this is an altogether strange UX and I can't think of a use case?

I had a very quick dig around in the code but if you could point us in the direction of likely candidates that'd be really helpful. I am more than happy to attempt a PR; though I must admit my TypeScript is a little rusty.

Illizian commented 3 years ago

Update: I've tracked down the code responsible. It seems to be the processSlotOptions method is returning an altered snapDuration, here's an example in my debugger:

image

tusharnaresh commented 2 years ago

Hey, any update on this?

MitchTalmadge commented 2 years ago

It looks like the slot must be exactly divisible by the snap amount (no remainder) or else it replaces the snap with the slot size as shown by @Illizian. So a 15 minute slot with 10 minute snap would not work (15/10 = 1.5 -- must be an integer, so this fails), but a 15 minute slot with 5 minute snap would (15/5 = 3 -- an integer!)

I understand this issue is about the snap being larger than the slot, but I think this logic still applies.

iluffka999 commented 7 months ago

I solved this problem by adding a custom function wholeDivideDurationsCustom instead of wholeDivideDurations, which even returns a non-integer number when calculating the slot height.

in fullcalendar.js

function processSlotOptions(slotDuration, snapDurationOverride) { // let snapDuration = snapDurationOverride || slotDuration; let snapDuration = snapDurationOverride; // let snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); let snapsPerSlot = wholeDivideDurationsCustom(slotDuration, snapDuration); if (snapsPerSlot === null) { snapDuration = slotDuration; snapsPerSlot = 1; // TODO: say warning? } return { snapDuration, snapsPerSlot }; }

And add next new function wholeDivideDurationsCustom function wholeDivideDurationsCustom(numerator, denominator) { let res = null; for (let i = 0; i < INTERNAL_UNITS.length; i += 1) { let unit = INTERNAL_UNITS[i]; if (denominator[unit] !== undefined && denominator[unit] !== 0) { let localRes = numerator[unit] / denominator[unit]; if (isNaN(localRes) || !isFinite(localRes) || (res !== null && res !== localRes)) { return null; } res = localRes; } else if (numerator[unit]) { return null; } } return res; }

Also keep in mind that it is better to make your free time 1-2 minutes longer to accommodate the snapDuration.``