I'm trying to change the first day of the work_week view with react big calendar but I didn't found a way to do it... I was able to change the first day of the week view but nothing helped with work week... any ideas?
This is how I changed the first day of the week view:
import "moment/locale/en-gb";
moment.locale("en-gb", {
week: {
dow: 0,
},
});
const localizer = momentLocalizer(moment);
Unfortunately, the only way to do this is by defining a custom 'View', rather than using the 'work_week' view. First you can create the 'View', using the 'work_week' view as a template.
import PropTypes from "prop-types";
import React from "react";
import Week from "react-big-calendar/lib/Week";
import TimeGrid from "react-big-calendar/lib/TimeGrid";
function workWeekRange(date, options) {
return Week.range(date, options).filter(
(d) => [0, 1, 6].indexOf(d.getDay()) === -1
);
}
class MyWorkWeek extends React.Component {
render() {
let { date, ...props } = this.props;
let range = workWeekRange(date, this.props);
return <TimeGrid {...props} range={range} eventOffset={15} />;
}
}
MyWorkWeek.propTypes = {
date: PropTypes.instanceOf(Date).isRequired
};
MyWorkWeek.defaultProps = TimeGrid.defaultProps;
MyWorkWeek.range = workWeekRange;
MyWorkWeek.navigate = Week.navigate;
MyWorkWeek.title = (date, { localizer }) => {
let [start, ...rest] = workWeekRange(date, { localizer });
return localizer.format({ start, end: rest.pop() }, "dayRangeHeaderFormat");
};
export default MyWorkWeek;
The magic there is in the workWeekRange method, where I defined the days (zero index) to hide from the week. In this example I'm hiding Sunday, Monday and Saturday.
Also notice that I had to change my import statements for the Week and TimeGrid components.
The last thing I had to do was provide the custom 'View', as well as a title for the button in the Toolbar. You do this in your calendar props. The views prop changes from the standard array to an object.
return (
<Calendar
// other props
views={{
day: true,
month: true,
myweek: MyWorkWeek
}}
messages={{
myweek: 'Work Week'
}}
/>
You can see a working example in CodeSandbox.
Related
I was trying to create Lightweight Charts in Next.js. Firstly, I created chart component which accepts chart data as props.
import { createChart, CrosshairMode } from 'lightweight-charts';
import { useEffect, useRef } from 'react';
const CandleStickChart = ({ OHLC_Data }) => {
const chartContainerRef = useRef(null);
useEffect(() => {
const chart = createChart(chartContainerRef.current, {
width: 700,
height: 400,
timeScale: {
timeVisible: true,
secondsVisible: false,
fixLeftEdge: true,
fixRightEdge: true,
},
crosshair: {
mode: CrosshairMode.Normal,
},
});
const candleSeries = chart.addCandlestickSeries({
priceFormat: {
type: 'price',
minMove: 0.00001,
precision: 5,
},
});
candleSeries.setData(OHLC_Data);
}, [OHLC_Data]);
return <div ref={chartContainerRef} />;
};
export default CandleStickChart;
In page component, I used getServerSideProps to fetch the data required for chart.
import { useCallback, useEffect, useState } from 'react';
import dynamic from 'next/dynamic';
import Image from 'next/image';
const CandleStickChart = dynamic(
() => import('../../components/CandleStickChart'),
{ ssr: false }
);
import { fetchTimeSeries } from '../../utils/fetchData';
const ForexPair = ({ meta, hour, day, week }) => {
const { currency_base, currency_quote, symbol, type } = meta;
const [logos, setLogos] = useState(null);
return (
<>
<CandleStickChart OHLC_Data={hour.values} />
<CandleStickChart OHLC_Data={day.values} />
<CandleStickChart OHLC_Data={week.values} />
</>
);
};
export default ForexPair;
export async function getServerSideProps(context) {
const { params, res } = context;
const { pairSymbol } = params;
res.setHeader(
'Cache-Control',
'public, s-maxage=300, stale-while-revalidate=3600'
);
const { meta, hour, day, week } = await fetchTimeSeries(
pairSymbol.replace('-', '/')
);
return {
props: {
meta,
hour,
day,
week,
},
};
}
I excluded some unnecessary codes. fetchTimeSeries function is just asynchronous function to fetch data for third party api. getServerSideProps is returning data format required in <CandleStickChart /> component.
What I expect to see is total 3 charts since I only included 3 components. but I am seeing two of each charts, total of 6 charts.
Please dont yell at me if my code looks terrible, I am new to Next.js :D. I really have no idea what is happening in my app.
p.s Charts are displaying correctly, just seeing duplicate charts for each. Thanks in advance. :D
It has to do with the way React & useEffect works under the hood.
Just add
return () => {
chart.remove();
};
after candleSeries.setData(OHLC_Data); and you won't see duplications :)
I'm using vuejs 3 with the composition API.
One component with params looks like this: https://webiste/accounts/1/4/2022, where 1 = id, 4 = month.
In that component, I have 2 links to go to the next month or previous month:
<router-link
:to="{ name: 'comptes', params: {id: 1, month: nextmonth, year: nextyear } }"
class="text-sky-600">next month</router-link>
nexmonth and nextyear are computed properties that go ... to the next month (and year if need be).
I run the axios call each time the route params change:
<script setup>
import { ref, onMounted, computed, watchEffect } from "vue"
const getaccounts = async () => {
// axios get results and put into ref ; cut for clarity
}
onMounted(() => {
getaccounts()
watchEffect(() => getaccounts() )
});
Obviously, the first time the page is loaded, the getAccounts() method gets called twice. How can I change that?
I have created a simple datepicker component based on react-dates and implemented as per documentation at https://github.com/airbnb/react-dates
The datepicker seems to be working however the calendar styling is completely broken when clicking on the datepicker field
The datepicker code:
import React, { Component } from 'react';
import moment from 'moment';
import 'react-dates/initialize';
import { SingleDatePicker } from 'react-dates';
import 'react-dates/lib/css/_datepicker.css';
export default class DatePicker extends Component {
constructor(props) {
super(props);
this.state = {
selectedStartDate: moment(),
calendarSelectedStartDate: false
}
}
onDateChange = (selectedStartDate) => {
this.setState(() => ({ selectedStartDate }));
};
onFocusChange = ({ focused }) => {
this.setState(() => ({ calendarSelectedStartDate: focused }));
};
render() {
return (
<SingleDatePicker
date={this.state.selectedStartDate}
onDateChange={this.onDateChange}
focused={this.state.calendarSelectedStartDate}
onFocusChange={this.onFocusChange}
numberOfMonths={1}
isOutsideRange={() => false}
/>
)
}
}
Implementation is just call to :
<DatePicker />
outside of any parent html tags that could affect it.
The styling looks like this:
Ok i found an answer for this problem, so:
Are you trying to render the calendar inside another element that is not always visible, right?
Well, if you are doing that, in the parent component you must have an state like "isOpen" or something like that. Then, when you call the Picker component, must be like:
{isOpen && <DatePicker />}
I spent like two hours searching this solution. I hope that make sense for you.
I use Full Calendar in my React project. I can not refresh the calendar although I make an update on the state.
Here is my sample code: https://codesandbox.io/embed/fullcalendar-react-jp7n1
In this sample, I change the title of events when user clicks on the Change title button, but nothing changes. I there anything that I miss?
Thanks for your help.
import React from "react";
import FullCalendar from "#fullcalendar/react";
import dayGridPlugin from "#fullcalendar/daygrid";
import timeGridPlugin from "#fullcalendar/timegrid";
import interactionPlugin from "#fullcalendar/interaction";
import "./styles.css";
import "#fullcalendar/core/main.css";
import "#fullcalendar/daygrid/main.css";
import "#fullcalendar/timegrid/main.css";
export default class DemoApp extends React.Component {
calendarComponentRef = React.createRef();
state = {
calendarWeekends: true,
calendarEvents: [
// initial event data
{ title: "Event 1", start: new Date() },
{ title: "Event 2", start: new Date() },
{ title: "Event 3", start: new Date() }
]
};
render() {
return (
<div className="demo-app">
<div className="demo-app-top">
<button onClick={this.changeTitle}>Change title</button>
</div>
<div className="demo-app-calendar">
<FullCalendar
defaultView="dayGridMonth"
header={{
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek"
}}
plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
ref={this.calendarComponentRef}
weekends={this.state.calendarWeekends}
events={this.state.calendarEvents}
/>
</div>
</div>
);
}
changeTitle = () => {
let events = [...this.state.calendarEvents];
events[0].title = new Date().toTimeString();
events[1].title = new Date().toTimeString();
this.setState({ calendarEvents: events });
};
}
Full calendar uses deep equality check to test for changes and since the object of the event inside the array is not changed (it's the same object by reference) it doesn't detect the change. You need to create a new event object to update it.
let events = [ ...this.state.calendarEvents];
events[0] = {
title: new Date().toTimeString(),
start: events[0] .start
}
events[1] = {
title: new Date().toTimeString(),
start: events[1].start
}
this.setState({ calendarEvents: events});
Im using React date picker http://react-day-picker.js.org/
Im using the today button:
http://react-day-picker.js.org/examples/customization-today-button/
The default behaviour for the today button is to navigate to the current month but not select the actual day. How can I make it select the actual day? This is updating the selectedDay state in this code example
import React from 'react';
import DayPicker from 'react-day-picker';
import 'react-day-picker/lib/style.css';
export default class BasicConcepts extends React.Component {
constructor(props) {
super(props);
this.handleDayClick = this.handleDayClick.bind(this);
this.state = {
selectedDay: undefined,
};
}
handleDayClick(day) {
this.setState({ selectedDay: day });
}
render() {
return (
<div>
<DayPicker onDayClick={this.handleDayClick} />
{this.state.selectedDay ? (
<p>You clicked {this.state.selectedDay.toLocaleDateString()}</p>
) : (
<p>Please select a day.</p>
)}
</div>
);
}
}
You can use onTodayButtonClick and set the day as selected:
<DayPicker
selectedDays={this.state.selectedDay}
todayButton="Select today"
onTodayButtonClick={day=>this.setState({selectedDay: day})
/>