show react-dates airbnb daterangepicker in mobile screen vertically fullscreen - javascript

I am using react-dates package from airbnb, and I am using DateRangePicker component of this library. I want to show datepicker verically fullscreen as shown in below image
Now, My question is how can we show this dateRangePicker component in mobile screen with vertically fullscreen.
import React, { useState } from "react";
import { DateRangePicker } from "react-dates";
export const Datepicker = () => {
const [startDate, setStartDate] = useState();
const [endDate, setEndDate] = useState();
const [focusedInput, setFocusedInput] = useState();
return (
<div>
<h1> Date </h1>{" "}
<p> selected start Date is : {JSON.stringify(startDate)} </p>
<p> selected end Date is : {JSON.stringify(endDate)} </p>
{window.matchMedia("(max-width: 700px)").matches && (
<DateRangePicker
orientation="vertical"
numberOfMonths={1}
verticalHeight={800}
startDate={startDate}
startDateId="start-date"
endDate={endDate}
endDateId="end-date"
onDatesChange={({ startDate, endDate }) => {
setStartDate(startDate);
setEndDate(endDate);
}}
focusedInput={focusedInput}
onFocusChange={(focusedInput) => setFocusedInput(focusedInput)}
/>
)}
</div>
)
Demo code sandbox is Codesandbox

Related

How to add Custom Buttons in React Datepicker Model

I want to create a calendar like this.
The Issue is I don't know how to add Apply and Cancel button in It. I have tried multiple solutions, But failed to get desired solution.
Through this block of code of I got this.
Kindly help me to add Button in react-datepicker.
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
const [startDate, setStartDate] = useState(new Date())
<DatePicker
selected={startDate}
className='w-[210px] p-3 text-sm font-[Inter-Regular] outline-none text-black-100 '
onChange={(date) => {
setStartDate(date as SetStateAction<Date>)
}}
showYearPicker
dateFormat='yyyy'
yearItemNumber={20}
/>
You can pass the buttons to the datepicker widget as children.
Both are closing the modal using the datepicker widget's api.
We have access to the api through a ref we assign to the widget.
The cancel button just set the date to the original[1] date.
const originalDate = new Date(); // or get it as prop
const [startDate, setStartDate] = React.useState(originalDate);
const calRef = React.useRef();
return (
<DatePicker
ref={calRef}
selected={startDate}
shouldCloseOnSelect={false}
onChange={(date) => setStartDate(date)}
showYearPicker
dateFormat="yyyy"
yearItemNumber={20}
>
<div>
<button
onClick={() => {
setStartDate(originalDate);
calRef.current.setOpen(false);
}}
>
Cancel
</button>
<button
onClick={() => {
calRef.current.setOpen(false);
}}
>
Apply
</button>
</div>
</DatePicker>
);
https://stackblitz.com/edit/react-datepicker-footer-buttons?file=App.tsx
[1] original - in your example it would be today but if the component receives it as prop, it can be it too

How to toggle class in react, but one component at once(all with the same classes)

let me explain my situation.
I am building a MERN project to my portfolio and I am trying to make a button toggle between the name of an item and a inputfield. So when the user click the pen (edit), it will add a class with the displain:none; in the div with the text coming from the MongoDB data base to hide it and will remove it from the div with the input. I could manage to do it. BUT since the amount of items can inscrease, clicking in one of them cause the toggle in all of them.
It was ok until I send some useState as props to the component.
This is my code from the App.jsx
import React, {useState, useEffect} from "react";
import Axios from "axios";
import "./App.css";
import ListItem from "./components/ListItem";
function App() {
//here are the use states
const [foodName, setFoodName] = useState("");
const [days, setDays] = useState(0);
const [newFoodName, setNewFoodName] = useState("");
const [foodList, setFoodList] = useState([]);
//here is just the compunication with the DB of a form that I have above those components
useEffect(() => {
Axios.get("http://localhost:3001/read").then((response) => {
setFoodList(response.data);
});
}, []);
const addToList = () => {
Axios.post("http://localhost:3001/insert", {
foodName: foodName,
days: days,
});
};
const updateFood = (id) => {
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
});
};
return (
<div className="App">
//Here it starts the app with the form and everything
<h1>CRUD app with MERN</h1>
<div className="container">
<h3 className="container__title">Favorite Food Database</h3>
<label>Food name:</label>
<input
type="text"
onChange={(event) => {
setFoodName(event.target.value);
}}
/>
<label>Days since you ate it:</label>
<input
type="number"
onChange={(event) => {
setDays(event.target.value);
}}
/>
<button onClick={addToList}>Add to list</button>
</div>
//Here the form finishes and now it starts the components I showed in the images.
<div className="listContainer">
<hr />
<h3 className="listContainer__title">Food List</h3>
{foodList.map((val, key) => {
return (
//This is the component and its props
<ListItem
val={val}
key={key}
functionUpdateFood={updateFood(val._id)}
newFoodName={newFoodName}
setNewFoodName={setNewFoodName}
/>
);
})}
</div>
</div>
);
}
export default App;
Now the component code:
import React from "react";
//Material UI Icon imports
import CancelIcon from "#mui/icons-material/Cancel";
import EditIcon from "#mui/icons-material/Edit";
//import CheckIcon from "#mui/icons-material/Check";
import CheckCircleIcon from "#mui/icons-material/CheckCircle";
//App starts here, I destructured the props
function ListItem({val, key, functionUpdateFood, newFoodName, setNewFoodName}) {
//const [foodList, setFoodList] = useState([]);
//Here I have the handleToggle function that will be used ahead.
const handleToggle = () => {
setNewFoodName(!newFoodName);
};
return (
<div
className="foodList__item"
key={key}>
<div className="foodList__item-group">
<h3
//As you can see, I toggle the classes with this conditional statement
//I use the same classes for all items I want to toggle with one click
//Here it will toggle the Food Name
className={
newFoodName
? "foodList__item-newName-delete"
: "foodList__name"
}>
{val.foodName}
</h3>
<div
className={
newFoodName
? "foodList__item-newName-group"
: "foodList__item-newName-delete"
}>
//Here is the input that will replace the FoodName
<input
type="text"
placeholder="The new food name..."
className="foodList__item-newName"
onChange={(event) => {
setNewFoodName(event.target.value);
}}
/>
//Here it will confirm the update and toggle back
//Didn't implement this yet
<div className="foodList__icons-confirm-group">
<CheckCircleIcon
className="foodList__icons-confirm"
onClick={functionUpdateFood}
/>
<small>Update?</small>
</div>
</div>
</div>
//here it will also desappear on the same toggle
<p
className={
newFoodName
? "foodList__item-newName-delete"
: "foodList__day"
}>
{val.daysSinceIAte} day(s) ago
</p>
<div
className={
newFoodName
? "foodList__item-newName-delete"
: "foodList__icons"
}>
//Here it will update, and it's the button that toggles
<EditIcon
className="foodList__icons-edit"
onClick={handleToggle}
/>
<CancelIcon className="foodList__icons-delete" />
</div>
</div>
);
}
export default ListItem;
I saw a solution that used different id's for each component. But this is dynamic, so if I have 1000 items on the data base, it would display all of them, so I can't add all this id's.
I am sorry for the very long explanation. It seems simple, but since I am starting, I spent the day on it + searched and tested several ways.
:|

Unable to hide and show react-date-range picker package on date selection

I am stuck with an issue. I am not able to hide and show the react-date-range picker on date selection. Actually, I am using a package for date range selection, Here's the package link - https://www.npmjs.com/package/react-date-range.
This package does not support hiding the date picker once the date range picker is selected. But according to my requirement, the date picker should be visible once the user clicks on the start date or selected date input and should close once the end date is selected.
I have used a state to toggle the view of the date range picker to show it once the user clicks on the input field and closes it on the onChange event. But when ver the user clicks on the date picker it closes since the onChange event is triggered.
Here's my code for a better understanding
import React from 'react'
// import date-range-picker css
import 'react-date-range/dist/styles.css'; // main style file
import 'react-date-range/dist/theme/default.css'; // theme css file
import { DateRangePicker } from 'react-date-range';
export interface IDateRangePickerProps {
range: any[],
onChange: (range: any) => void
}
const CustomDateRangePicker: React.FC<IDateRangePickerProps> = ({ range, onChange }) => {
const TODAY = new Date();
return (
<DateRangePicker
months={2}
minDate={TODAY}
direction="horizontal"
ranges={range}
onChange={onChange}
/>
)
}
export default CustomDateRangePicker;
In the above code, we have created a component to make the react-date-range picker easier to reuse throughout the application.
Here's the implementation of the react-date-range picker
import React, { useEffect, useState } from "react";
import CustomDateRangePicker from "../../components/daterangepicker/DateRangePicker";
import { format } from "date-fns";
const PropertyRoomTypes = () => {
const [showDateRangePicker, setShowDateRangePicker] = useState(false);
const [selectionRange, setSelectionRange] = useState<any[]>([{
startDate: null,
endDate: null,
key: 'selection',
}]);
const onDateRangeChange = (range: any) => {
setSelectionRange([range.selection])
if (selectionRange[0].startDate && selectionRange[0].endDate) {
setShowDateRangePicker(false);
}
}
const formatDate = (date: any) => {
if (date) {
let res = format(new Date(date), "dd MMM yyyy");
return res;
} else {
return;
}
}
return (
<>
<div className="add__room__type__meal__plan__wrapper px-0 mx-0">
<div className="room__rates__edit__date__range__picker" onClick={() => setShowDateRangePicker(!showDateRangePicker)}>
<div className="date__range__picker__icon"><i className="bi bi-calendar"></i></div>
<div className="date__range__label">{`${selectionRange[0].startDate && selectionRange[0].endDate ? formatDate(selectionRange[0].startDate) + " | " + formatDate(selectionRange[0].endDate) : "Select Dates"}`}</div>
{/* <div className="date__range__label">Select Dates</div> */}
</div>
{showDateRangePicker &&
<CustomDateRangePicker
range={selectionRange}
onChange={onDateRangeChange}
/>
}
</div>
</>
);
};
export default PropertyRoomTypes;
Any help would be much appreciated.
When user do first selection, both dates are the same...
So, you should compare it... something like that:
useEffect(() => {
if (selectionRange.startDate !== selectionRange.endDate) {
showDateRangePicker(false);
}
}, [selectionRange]);

Two onPointerOver events conflict in React

My screen is divided in two zones: left zone and right zone.
The left zone appears always. When you point over the left zone, it should make appear the right zone.
Once the right zone is displayed, both zones should make the right zone display.
But its not working as expected, the right zone disappear when "trying" to point over it.
Check the demo HERE
export default function App() {
const [pointOverLeftZone, setPointOverLeftZone] = useState(false);
const [pointOverRightZone, setPointOverRightZone] = useState(false);
const shouldDisplayRightZone = pointOverLeftZone || pointOverRightZone;
return (
<div className="App">
<div
className="zone light-cyan"
onPointerOver={() => {
if (!pointOverLeftZone) setPointOverLeftZone(true);
}}
onPointerOut={() => {
if (pointOverLeftZone) setPointOverLeftZone(false);
}}
>
<p>Point over here to display the right zone</p>
</div>
{shouldDisplayRightZone && (
<div
className="zone light-yellow"
onPointerOver={() => {
if (!pointOverRightZone) setPointOverRightZone(true);
}}
onPointerOut={() => {
if (pointOverRightZone) setPointOverRightZone(false);
}}
>
<p>
Once open the right zone, both zones should activate the display of
this right zone, but the bug is here: when you mouse the move here
it dissapear
</p>
</div>
)}
</div>
);
}
Value of shouldDisplayRightZone depends on value of pointOverLeftZone, pointOverRightZone so you should make it an independent state and wrap into an useEffect and update whenever there are changes in pointOverLeftZone, pointOverRightZone
const [shouldDisplayRightZone, setShouldDisplayRightZone] = useState(
pointOverLeftZone || pointOverRightZone
);
useEffect(() => {
setShouldDisplayRightZone(pointOverLeftZone || pointOverRightZone);
}, [pointOverLeftZone, pointOverRightZone]);
Forked codesandbox
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [pointOverLeftZone, setPointOverLeftZone] = useState(false);
const [pointOverRightZone] = useState(false);
const shouldDisplayRightZone = pointOverLeftZone || pointOverRightZone;
return (
<div className="App">
<div
className="zone light-cyan"
onPointerOver={() => setPointOverLeftZone(true)}
>
<p>Point over here to display the right zone</p>
</div>
{shouldDisplayRightZone && (
<div
className="zone light-yellow"
onPointerOut={() => setPointOverLeftZone(false)}
>
<p>
Once open the right zone, both zones should activate the display of
this right zone, but the bug is here: when you mouse the move here
it dissapear
</p>
</div>
)}
</div>
);
}
Something like this?
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [pointOverLeftZone, setPointOverLeftZone] = useState(false);
const [pointOverRightZone, setPointOverRightZone] = useState(false);
const [flag, setFlag] = useState(true);
const [int, setIni] = useState(false);
const shouldDisplayRightZone = pointOverLeftZone || pointOverRightZone;
return (
<div className="App">
{flag === true ? (
<div
className="zone light-cyan"
onPointerOver={() => {
if (!pointOverLeftZone) {
setPointOverLeftZone(true);
}
}}
>
<p>Point over here to display the right zone</p>
</div>
) : (
<div>
<div>right zone open</div>
<p>
Once open the right zone, both zones should activate the display of
this right zone, but the bug is here: when you mouse the move here
it dissapear
</p>
</div>
)}
{shouldDisplayRightZone && (
<div
className="zone light-yellow"
onPointerOver={() => {
if (!pointOverRightZone) {
setFlag(false);
setPointOverRightZone(true);
}
}}
onPointerOut={() => {
if (pointOverRightZone) setPointOverRightZone(false);
}}
>
<p>
Once open the right zone, both zones should activate the display of
this right zone, but the bug is here: when you mouse the move here
it dissapear
</p>
</div>
)}
</div>
);
}
i have changed the code in sandbox you can check it there.Let me know if it works

React DatePicker toggle issue

i'm using this plugin in my project.
https://reactdatepicker.com
There is have some prop showTimeSelect this prop takes boolean value and hide or show time picker.
I'm trying to give option to user about selecting time picker, so i tried to make some onClick event and make this prop conditional.
But it's work sometimes, sometimes not..
I don't understand where is the problem here is my code:
import React from "react";
import ReactDOM from "react-dom";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import "./styles.css";
class App extends React.Component {
state = {
startDate: new Date()
};
handleChange = date => {
this.setState({
startDate: date,
showTime: false
});
};
showTimeSelection = () => {
this.setState({
showTime: !this.state.showTime
});
};
render() {
return (
<div>
<DatePicker
selected={this.state.startDate}
onChange={this.handleChange}
showTimeSelect={this.state.showTime}
>
{" "}
<div>
<a onClick={() => this.showTimeSelection()}>
TOGGLE TIME SELECTION
</a>
</div>{" "}
</DatePicker>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
and here is the codesandbox example
You can try on codeSandBox it's sometimes work directly sometimes you need to click outside of datepicker and click inside again.
I have noticed it only works if showTimeSelect is true before the DatePicker is going to be displayed. So, before closing DatePicker you have to set showTimeSelect to true. you can do it in prop onClickOutside
state = {
startDate: new Date(),
showTime: true
};
handleChange = date => {
this.setState({
startDate: date
});
};
showTimeSelection = () => {
this.setState({
showTime: !this.state.showTime
});
};
render() {
const { startDate, showTime } = this.state;
return (
<div>
<DatePicker
selected={startDate}
onChange={this.handleChange}
showTimeSelect={showTime}
onClickOutside={() => this.setState({ showTime: true })}
>
<div onClick={this.showTimeSelection} style={{ cursor: "pointer" }}>
<h4>TOGGLE TIME SELECTION</h4>
</div>
</DatePicker>
</div>
);
}
}
check out code sandbox . check out two other useful props onCalendarClose and onCalendarOpen

Categories