React-big-calendar: Mobile view plans

Created on 25 Sep 2018  路  13Comments  路  Source: jquense/react-big-calendar

Are there any plans on making the mobile experience of react-big-calandar equivalent to the experience on desktop?

Missing feature which is kind of deal breaker is onSelectSlot not working at all on mobile

Most helpful comment

I've been running into the same problem with my application. I was able to hack a solution by adding an onTouchEnd handler to a custom dateCellWrapper I was using.

Something like:

const DateCellWrapper = ({ value, onSelect, children }) => (
  React.Children.map(children, child => 
    React.cloneElement(child, { 
      onTouchEnd: event => {
        event.preventDefault();
        onSelect(value);
      }
    })
  )
);

<BigCalendar
  components={{
    dateCellWrapper: props => <DateCellWrapper onSelect={onSelectDate} {...props} />,
  }}
/>

I think this only works if you are using react-big-calendar in a controlled mode.

For my application, I wrap react-big-calendar into a Calendar component that has an onSelectDate event handler so I can abstract away all the different ways the date could be changed. Something like:

class Calendar extends Component {
  static defaultProps = {
    defaultDate: new Date(),
    onSelectDate: () => {},
  };

  selectDate = date => this.props.onSelectDate(date);

  onSelectSlot = event => this.selectDate(event.start);
  onDrillDown = date => this.selectDate(date);
  onNavigate = date => this.selectDate(date);

  render() {
    const { components, ...props } = this.props;
    const date = props.date || props.defaultDate;

    return (
      <BigCalendar 
        {...props}
        selectable
        date={date}
        defaultDate={date}
        onDrillDown={this.onDrillDown}
        onSelectSlot={this.onSelectSlot}
        onNavigate={this.onNavigate}
        components={{
          ...components
        }} 
      />
    );
  }
}

@fastfedora what do you mean by saying controlled mode?
I've tried to implement as you wrote, didn't work.

thanks,

All 13 comments

selecting should already work, at least we listen for touch events and respond to them. check out the Selction.js file. I don't use this on mobile tho so it's not super hi priority for me, but happy to take improvements

Thx for answering

True that selecting works however touching does not trigger the onSelectSlot similar to how it works with clicking on desktop or am i missing something?

@jhammersholt I see a similar thing.

Actual behaviour
On 'click & hold' nothing happens
On 'click & hold with a slight drag' the onSelectSlot is triggered

Expected behaviour
On 'click & hold', after the longPressThreshold has passed onSelectSlot should triggered

@jquense Can you confirm the expected behaviour? then I'll do some further investigation and see if I can raise a PR.

I think this is a duplicate of #972

@jquense and @bgelineau does this has been fixed on #1066 ?

I've been running into the same problem with my application. I was able to hack a solution by adding an onTouchEnd handler to a custom dateCellWrapper I was using.

Something like:

const DateCellWrapper = ({ value, onSelect, children }) => (
  React.Children.map(children, child => 
    React.cloneElement(child, { 
      onTouchEnd: event => {
        event.preventDefault();
        onSelect(value);
      }
    })
  )
);

<BigCalendar
  components={{
    dateCellWrapper: props => <DateCellWrapper onSelect={onSelectDate} {...props} />,
  }}
/>

I think this only works if you are using react-big-calendar in a controlled mode.

For my application, I wrap react-big-calendar into a Calendar component that has an onSelectDate event handler so I can abstract away all the different ways the date could be changed. Something like:

class Calendar extends Component {
  static defaultProps = {
    defaultDate: new Date(),
    onSelectDate: () => {},
  };

  selectDate = date => this.props.onSelectDate(date);

  onSelectSlot = event => this.selectDate(event.start);
  onDrillDown = date => this.selectDate(date);
  onNavigate = date => this.selectDate(date);

  render() {
    const { components, ...props } = this.props;
    const date = props.date || props.defaultDate;

    return (
      <BigCalendar 
        {...props}
        selectable
        date={date}
        defaultDate={date}
        onDrillDown={this.onDrillDown}
        onSelectSlot={this.onSelectSlot}
        onNavigate={this.onNavigate}
        components={{
          ...components
        }} 
      />
    );
  }
}

I've been running into the same problem with my application. I was able to hack a solution by adding an onTouchEnd handler to a custom dateCellWrapper I was using.

Something like:

const DateCellWrapper = ({ value, onSelect, children }) => (
  React.Children.map(children, child => 
    React.cloneElement(child, { 
      onTouchEnd: event => {
        event.preventDefault();
        onSelect(value);
      }
    })
  )
);

<BigCalendar
  components={{
    dateCellWrapper: props => <DateCellWrapper onSelect={onSelectDate} {...props} />,
  }}
/>

I think this only works if you are using react-big-calendar in a controlled mode.

For my application, I wrap react-big-calendar into a Calendar component that has an onSelectDate event handler so I can abstract away all the different ways the date could be changed. Something like:

class Calendar extends Component {
  static defaultProps = {
    defaultDate: new Date(),
    onSelectDate: () => {},
  };

  selectDate = date => this.props.onSelectDate(date);

  onSelectSlot = event => this.selectDate(event.start);
  onDrillDown = date => this.selectDate(date);
  onNavigate = date => this.selectDate(date);

  render() {
    const { components, ...props } = this.props;
    const date = props.date || props.defaultDate;

    return (
      <BigCalendar 
        {...props}
        selectable
        date={date}
        defaultDate={date}
        onDrillDown={this.onDrillDown}
        onSelectSlot={this.onSelectSlot}
        onNavigate={this.onNavigate}
        components={{
          ...components
        }} 
      />
    );
  }
}

@fastfedora what do you mean by saying controlled mode?
I've tried to implement as you wrote, didn't work.

thanks,

@sahar922 Controlled mode is when the parent component passes the state for a component into it, rather than letting the component itself manage it.

To make a component controlled, you usually pass in the value via a prop, then receive any changes to that value via an event handler. The component itself never updates the value itself, it relies on the parent component updating the state after receiving a change event.

You can read more about controlled input controls here.

For my Calendar component, you'll notice it has two props:

date
: The selected date that is passed into BigCalendar

onSelectDate
: A callback function that is called whenever the user attempts to change the date via BigCalendar (in this case, via a drill down, select slot or navigate event).

It's the parent's component's responsibility to update the date prop whenever the onSelectDate function is called. In my case, I'm storing the date in the route, so the date is just the parsed value from the route and the onSelectDate just updates the route.

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.

Activity!

Activity

I've no plans to add this as i don't use the component. If someone wants to implement this happy to take a PR!

@jquense does this PR resolve this issue? https://github.com/intljusticemission/react-big-calendar/pull/1066 Do you remember what the blocker for merging is?

Happy to help push this over the finish line since we use this component for mobile in production.

My solution to make touch works like "click" (inspired by @fastfedora)

` const TouchCellWrapper = ({ children, value, onSelectSlot }) => ( React.cloneElement(Children.only(children), { onTouchEnd: () => onSelectSlot({ action: 'click', slots: [value] }), }) ); // ... <Calendar components={{ dateCellWrapper: (props) => ( <TouchCellWrapper {...props} onSelectSlot={onSelectSlot} /> ), }} />

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jgautsch picture jgautsch  路  3Comments

tiaaaa123 picture tiaaaa123  路  4Comments

nicolasriccardi picture nicolasriccardi  路  3Comments

connercms picture connercms  路  3Comments

KatiaPosPago picture KatiaPosPago  路  3Comments