Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DnD: dragging won't start on first attempt (when no events are visible when initialized?) #1105

Closed
xtursky opened this issue Nov 12, 2018 · 13 comments
Labels

Comments

@xtursky
Copy link
Contributor

xtursky commented Nov 12, 2018

Do you want to request a feature or report a bug?

bug

What's the current behavior?

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

  • If I set defaultDate to be at the same week as events, DnD is working.
  • If I set defaultDate to start at some other week without events, then after navigation via Previous/Next controls to events, DnD won't start on each odd attempt. Every second attempt works.

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.

What's the expected behavior?

DnD works no matter what defaultDate and view is used.

@bminer
Copy link

bminer commented Nov 15, 2018

I seem to be able to confirm this bug. Here's how:

  • Use onSelectSlot to create a new event and update the events state
  • Ensure that events does not contain events that will render on initial load

If 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.

@bs85
Copy link
Collaborator

bs85 commented Nov 16, 2018

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>
        );
    }
}

@xtursky
Copy link
Contributor Author

xtursky commented Jan 3, 2019

@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?

@xtursky xtursky changed the title DnD: dragging won't start on first attempt sometimes (when no events are visible when initialized?) DnD: dragging won't start on first attempt (when no events are visible when initialized?) Jan 3, 2019
@sbusch
Copy link
Contributor

sbusch commented Jan 8, 2019

I also confirm this behavior.

@sbusch
Copy link
Contributor

sbusch commented Jan 9, 2019

Argh, please ignore the reference to # 1024

@kkesley
Copy link

kkesley commented Feb 1, 2019

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?

@xtursky
Copy link
Contributor Author

xtursky commented Feb 7, 2019

@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.

@tuancaraballo
Copy link

I also confirm this behaviour

@stale
Copy link

stale bot commented Jul 21, 2019

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.

@stale stale bot added the wontfix label Jul 21, 2019
@bminer
Copy link

bminer commented Jul 21, 2019

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.

@stale stale bot removed the wontfix label Jul 21, 2019
@sgraham3311
Copy link

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.

@xtursky
Copy link
Contributor Author

xtursky commented Aug 27, 2019

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.

@stale
Copy link

stale bot commented Oct 26, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants