bug
This took me quite some time to simulate, so bear with my explanation.
Problem is, that DnD at some cases seems to be not fully initialized and then is not working on each odd attempt.
Problem can be easily seen here: https://codesandbox.io/s/640nmy650r
In depth in first attempt I saw that drag is not started due to beforeSelect check, where state accessible via dragAndDropAction is not yet filled. Maybe issue with event listeners?
I had this problem starting in WEEK and DAY view (maybe it's also issue with MONTH).
!Beware: hot reload causes correct re-initialization, so you need to refresh whole page before each try.
Problem is not connected to OS or browser.
DnD works no matter what defaultDate and view is used.
I seem to be able to confirm this bug. Here's how:
onSelectSlot to create a new event and update the events stateevents does not contain events that will render on initial loadIf the events array has one or more items in it that will be rendered, everything works fine; otherwise, the move/resize events only work every other time, and other strange behavior occurs also.
Consider the following code:
import React, { Component } from "react";
import Calendar from "react-big-calendar";
import moment from "moment";
import withDragAndDrop from "react-big-calendar/lib/addons/dragAndDrop";
import "react-big-calendar/lib/addons/dragAndDrop/styles.css";
import "react-big-calendar/lib/css/react-big-calendar.css";
const localizer = Calendar.momentLocalizer(moment);
const DnDCalendar = withDragAndDrop(Calendar);
class App extends Component {
state = {
events: [
{
start: new Date("1970-01-01"),
end: new Date("1970-01-01 2:00 PM"),
title: "Some title"
}
]
};
onSelectSlot = ({action, start, end }) => {
this.setState(state => {
const events = [...state.events, {
start, end,
title: "New Event"
}]
return { events };
});
}
onEventResize = ({ event, start, end, allDay }) => {
this.setState(state => {
const events = [...state.events]
const i = events.indexOf(event)
events[i] = Object.assign({}, state.events[i], {start, end})
return { events };
});
};
onEventDrop = ({ event, start, end, allDay }) => {
this.setState(state => {
const events = [...state.events]
const i = events.indexOf(event)
events[i] = Object.assign({}, state.events[i], {start, end})
return { events };
});
};
render() {
return (
<div className="App">
<DnDCalendar
localizer={localizer}
defaultDate={new Date()}
defaultView="week"
events={this.state.events}
onSelectSlot={this.onSelectSlot}
onEventDrop={this.onEventDrop}
onEventResize={this.onEventResize}
selectable
resizable
style={{ height: "100vh" }}
/>
</div>
);
}
}
export default App;
In the above example, the drag and drop functionality will not work properly for newly created events. However, if I simply change the initial state of events to a Date range that will be rendered initially, everything works fine:
state = {
events: [
{
start: new Date(),
end: new Date(),
title: "Some title"
}
]
};
So, with the above change, everything works normally again.
Here is a smaller repro with a draggableAccessor returning a dynamic value:
To reproduce, click on the button at the top to enable dragging, then try to drag. The first drag fails, and then works as expected. Clicking the On/Off button twice causes the bug again on the first drag.
import React, { Component } from 'react';
import moment from 'moment';
import BigCalendar from 'react-big-calendar';
import withDragAndDrop from 'react-big-calendar/lib/addons/dragAndDrop';
import 'react-big-calendar/lib/css/react-big-calendar.css';
import 'react-big-calendar/lib/addons/dragAndDrop/styles.css';
const localizer = BigCalendar.momentLocalizer(moment);
const DragAndDropCalendar = withDragAndDrop(BigCalendar);
export default class App extends Component {
state = {
enableDrag: false,
}
toggleDrag = () => this.setState((prevState) => ({ enableDrag: !prevState.enableDrag }))
render() {
const { enableDrag } = this.state;
const start = new Date();
const end = new Date();
end.setHours(end.getHours() + 1);
return (
<React.Fragment>
<button type='button' onClick={this.toggleDrag}>
{ enableDrag ? 'On' : 'Off' }
</button>
<DragAndDropCalendar
view='day'
localizer={localizer}
events={[{
title: 'Buggy',
start,
end,
}]}
draggableAccessor={() => enableDrag}
/>
</React.Fragment>
);
}
}
@jquense, @arecvlohe sry for bothering guys, but this issue makes Dnd not working at all for me. I already spent some time to figure out how to fix this, but nothing worked (no delay, check...).
Do you have any idea, or can you point me to somebody who can help with this?
I also confirm this behavior.
Argh, please ignore the reference to # 1024
until the official fix is coming, I'm using this workaround
eventPropGetter={event => {
if (event.hide) {
return { style: { display: "none" } };
}
}}
events={[
{ start: new Date(), end: new Date(), title: "", hide: true },
...events
]}
Do you guys have any feedback? Can I use this right now?
@kkesley thanks for workaround, already applied that and it's working ok.
Just found out, that even for this hidden event draggableAccessor / resizableAccessor has to return true.
I also confirm this behaviour
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
I don't believe that the PR #1342 solved this issue. I think the author of the PR referenced the wrong issue. It should not be stale.
This is happening for me on IE11. Having events before/after initialization do not have an effect on the outcome. First attempt at dragging does not work.
Yes I wrongly referenced this issue while fixing something else.
@sgraham3311 have you tried above workaround. Catch is, that this fake event has to be rendered in current view, but you can hide it with css property. This workaround works for me in all browsers.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Most helpful comment
I seem to be able to confirm this bug. Here's how:
onSelectSlotto create a new event and update theeventsstateeventsdoes not contain events that will render on initial loadIf the
eventsarray has one or more items in it that will be rendered, everything works fine; otherwise, the move/resize events only work every other time, and other strange behavior occurs also.Consider the following code:
In the above example, the drag and drop functionality will not work properly for newly created events. However, if I simply change the initial state of
eventsto a Date range that will be rendered initially, everything works fine:So, with the above change, everything works normally again.