React Hooks selecting data to a date picker - reactjs

I have a MUI date picker in my React app that I want to use with serverside data.
I'm returning the correct data in my console log that I pass in my useState hook const [availableDate, setAvailableDate] = useState({}); and now want to pass the selected date into the picker:
returned JSON
const data = [
{
date: '05/05/21',
timeSlots: [
{
end: '11:00',
start: '12:00'
}
]
},
{
date: '05/05/24',
timeSlots: [
{
end: '13:00',
start: '14:00'
}
]
}
];
Date Picker
const [availableDate, setAvailableDate] = useState({});
const [filteredData, setFilteredData] = useState(availableDate);
//set current date as default
var curr = new Date();
function setDate(dat) {
let datt = {
date: {// ... returend date},
start: '11:40',
end: '13:00',
};
service.stepDate.setCvData(datt);
}
curr.setDate(curr.getDate());
var date = curr.toISOString().substr(0, 10);
Date Picker
I tried mapping the array data in my date picker but this just returns multiple pickers.
{availableDates.map((index) => (
<div className="calendarWrapper">
<form noValidate>
<TextField
key={index.id}
minDate={today}
id="date"
type="date"
onChange={setDate}
defaultValue={date}
/>
</form>
</div>
))}
How do I extract the selected date ex: date: "2021/05/24" from the json and pass it into my setDate() function?

First of all, onChange interface is the following
onChange(e) {
// e.target.value
}
so you won't be able to get your date from e directly.
Also date is an object, which can't be {} initially, null could be one option, or new Date().

Related

ReactJS Date Range Picker with disabled dates - Rsuite

I am looking to a solution for my ReactJS project.
In a property page I want to display a Date Range Picker with the availability of the property.
By running a query with Postman I get the availability from the calendar with the following format, although there is no problem for me to manipulate the array in order to fit the requirements for the date range picker.
How to display inside the date range picker the blocked days so they are not clickable. I already tried with the DateRangePicker of rsuite and storybook but no luck for me. For the rsuite the data should have the following format:
It will depend on the date range picker you decide to use (or if you write your own) - a quick look at this component's API, for example, will tell you that it has a disabledDates: Date[] prop that you can use to disable certain dates.
The way I managed to do it was to get the data from the API.
Manipulated and syntax in a way the DateRangePicker could import it via a function.
axios(config)
.then(function (response) {
//console.log(JSON.stringify(response.data));
calendar= response.data.calendar;
console.log(calendar);
var highlighted = [];
var disabled_days=[];
for(var i=0;i<calendar.length;i++) {
var item = calendar[i];
if(item.status === 'available') {
highlighted.push(new Date(item.date));
//console.log(item.date);
}
else{
disabled_days.push(new Date(item.date));
}
};
modifiers = {
disabled: disabled_days,
highlight: highlighted
}
self.setState({
modifiers: modifiers})
//console.log(modifiers);
})
.catch(function (error) {
console.log(error);
});
Then I used the package 'react-calendar' and import it to my node project.
npm i 'react-calendar' --save
Then I used the component Calendar as I have import it via the following command:
import Calendar from '../Components/CalendarRangePicker';
...
<Calendar modifiers={modifiers}/>
...
CalendarRangePicker.js
import { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
function CalendarRangePicker(props){
const [value, onChange] = useState(new Date());
const dataNotYetFetched = useState();
// disabled some days until I fetched the data...
var disabledDates = [
new Date(2021, 7, 1),
new Date(2021, 7, 2),
];
//console.log(disabledDates);
var modifiers = null;
if(props.modifiers != null) {
modifiers = props.modifiers;
console.log(modifiers);
disabledDates = modifiers.disabled;
}
return (
<div>
<Calendar
// Make calendar not viewable for previous months
minDate={new Date()}
// Whether to show two months
showDoubleView = {false}
ActiveStartDate = {new Date()}
returnValue={"range"}
// settings for the calendar
onChange={onChange}
value={value}
selectRange={true}
locale="en-US"
autofocus={false}
// disabled dates. Got data from channel manager
tileDisabled={({date, view}) =>
(view === 'month') && // Block day tiles only
disabledDates.some(disabledDate =>
date.getFullYear() === disabledDate.getFullYear() &&
date.getMonth() === disabledDate.getMonth() &&
date.getDate() === disabledDate.getDate()
)}
/>
</div>
);
}
export default CalendarRangePicker;

Identify selected date range in react-date-range

I am using react-date-range plugin to select a date range.
import { DateRangePicker} from 'react-date-range';
import 'react-date-range/dist/styles.css';
import 'react-date-range/dist/theme/default.css';
Following function is used to handle the date range when a range is selected
function handleSelect() {
}
I have added the DateRangePicker like this
const selectionRange = {
startDate: new Date(),
endDate: new Date(),
key: 'selection',
}
<div>
<DateRangePicker
ranges={[selectionRange]}
onChange={handleSelect}/>
</div>
I want to make some operations on the selected date range in side the handleChange function. But I cannot find how to identify which date range is selected and the respective start and end dates.
In documentation onChange callback is described as
But I cannot understand how to get these startDate and endDate parameters.
Can someone help me to get this values.
Documentation: https://openbase.io/js/react-date-range/documentation
According to the documentation the onChange callback receives the ranges as an argument:
import { DateRangePicker } from 'react-date-range';
class MyComponent extends Component {
handleSelect(ranges){
console.log(ranges);
// {
// selection: {
// startDate: [native Date Object],
// endDate: [native Date Object],
// }
// }
}
render(){
const selectionRange = {
startDate: new Date(),
endDate: new Date(),
key: 'selection',
}
return (
<DateRangePicker
ranges={[selectionRange]}
onChange={this.handleSelect}
/>
)
}
}
It should be an object that has a key selection which is itself an object that contains the startDate and endDate.
My solution is:
const onChange = (item) => {
if (item.selection.endDate !== item.selection.startDate) {
console.log(item);
setIsPopoverOpen(false);
}
setRange([item.selection]);
}

defaultValue of showTime attribute in antd datePicker couldn't set the time

I'm using ant design for my react hook based development. I am retrieving date from database over a network call and the date retrieved from database is look like "2020-09-01T05:02:00.000+0000". It is a string. I have to parse this date and show the date value and time value through antd datePicker in my page. Though I've success with setting up date part but I'm stuck with setting up the time. Here is my code,
###########
Here is my datepicker
###########
<DatePicker
name="Campaign-date"
defaultValue={moment(formData['Campaign-date'].split('T')[0])}
showTime={{
defaultValue: moment(formData['Campaign-date'].split('T')[1],'HH:mm'),
format: 'HH:mm'
}}
format={'YYYY-MM-DD HH:mm'}
style={{ width: '100%' }}
onChange={handleDateChange}
/>
##########################
Here is my handleDateChange function
##########################
const handleDateChange = date => {
setFormdata({
...formData,
'Campaign-date': date
.format('YYYY-MM-DD HH:mm')
.split(' ')
.join('T')
});
};
formData['Campaign-date'] is the date retrieved from the database. I feel the showTime attribute is not working as expected. I want to get a result of "05:02" but instead the value shown is, "00:00".
I have tried different variation in showTime such as,
defaultValue: moment('05:02','HH:mm'),
//or
defaultValue: moment(formData['Campaign-date'],'HH:mm')
//or
defaultValue: moment(formData['Campaign-date'].split('T')[1].split('.),'HH:mm')
but nothing is working. It is always setting the value as "00:00".
And I have no problem with my onChange functionality. It is working perfect. The date/time change code wise working as expected. It is just the view on my page is not showing correct time.
I'm really stuck with. Any help therefore, is much appreciated.
Ant Design DatePicker:
(sandbox)
import React from "react";
import ReactDOM from "react-dom";
import { DatePicker, Space } from "antd";
import moment from "moment";
import "./index.css";
import "antd/dist/antd.css";
const initialState = {
data1: "form field",
data2: "form field 2",
"Campaign-date": "2020-09-01T05:02:00.000+0000"
};
function FormComponent() {
const [formData, setFormData] = React.useState(initialState);
console.log(formData);
function onChange(value, dateString) {
if (value) {
setFormData({
...formData,
"Campaign-date": value.toISOString(true)
});
}
//console.log("Selected Time: ", value); //Moment object
//console.log("Formatted Selected Time: ", dateString); //String
}
return (
<Space direction="vertical" size={12}>
<DatePicker
name="Campaign-date"
defaultValue={moment(formData["Campaign-date"], "YYYY/MM/DD HH:mm")}
format={"YYYY/MM/DD HH:mm"}
showTime={{ format: "HH:mm" }}
onChange={onChange}
/>
<div style={{ marginTop: 16 }}>
Selected Date:{" "}
{formData["Campaign-date"]
? moment(formData["Campaign-date"]).format("YYYY-MM-YY HH:mm")
: "None"}
</div>
</Space>
);
}
ReactDOM.render(<FormComponent />, document.getElementById("container"));
If you are using react-datepicker 2.0 or up, you need to use a javascript Date object. Here is a working setup.
function parseISOString(s) {
var b = s.split(/\D+/);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6]));
}
const isoString = '2020-09-01T05:02:00.000+0000';
const dateFromISOString = parseISOString(isoString);
<DatePicker
selected={dateFromISOString}
dateFormat="dd/MM/yyyy HH:mm"
showTimeSelect
timeFormat="HH:mm"
timeIntervals={15}
placeholderText="Select date"
onChange={handleChange}
/>
Overview
The string you are receiving from the database is an ISO date string.
You can use moment.js to easily parse it or parse it manually and create a new Date object from it.
Here is a snippet illustrating both. The Date example uses this answer: Change ISO Date String to Date Object - JavaScript
const isoString = "2020-09-01T05:02:00.000+0000"
// with Moment
console.log("With Moment");
const timeFromMoment = moment(isoString).format("HH:mm");
console.log(timeFromMoment);
// with Date
console.log("With Date");
// https://stackoverflow.com/questions/27012854/change-iso-date-string-to-date-object-javascript
function parseISOString(s) {
var b = s.split(/\D+/);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6]));
}
const dateFromISOString = parseISOString(isoString);
console.log(dateFromISOString);
// return Local adusted time
const localHours = dateFromISOString.getHours();
console.log(localHours);
// return UTC time
const utcHours = dateFromISOString.getUTCHours();
console.log(utcHours);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
<DatePicker
name="Campaign-date"
defaultValue={moment(formData['Campaign-date'].split('T')[0])}
showTime={{
defaultValue: moment(formData['Campaign-date'].split('T')[1].split('.')[0],'HH:mm:ss'),
format: 'HH:mm:ss'
}}
format={'YYYY-MM-DD HH:mm'}
style={{ width: '100%' }}
onChange={handleDateChange}
/>

Access data from an array of dates

My application can get data from user. For this i have different inputs. One of my inputs is date Picker.
<Form.Item name="Picker" label="date">
<RangePicker
showTime={{ format: "HH:mm" }}
format="YYYY-MM-DD HH:mm"
onChange={onChange2}
onOk={onOk}
/>
</Form.Item>
The issue appear when i try to access data after clicking on submit button. In console i have all data from each input, but from RangePicker, the data is not structured, and i get:
Picker: Array[2]
0: Moment
1: Moment
The problem is that i can access this array, and display on fron end. How to do this?
link to my app: https://codesandbox.io/s/form-methods-ant-design-demo-kbwgk
Try this
import moment from 'moment'
const onFinish = values => {
const startDate = moment(values.Picker[0]).format("YYYY-MM-DD HH:mm");
const endDate = moment(values.Picker[1]).format("YYYY-MM-DD HH:mm");
console.log(startDate, endDate)
};
I got it,
on your rangepicker use
onFinish instead of onOk
<RangePicker
showTime={{ format: "HH:mm" }}
format="YYYY-MM-DD HH:mm"
onChange={onChange2}
onFinish={onFinish}
/>
working as specified
you press Ok twice , so the first onOk still doesnt include the second part of the range
sorry for not giving professional answer
Since you are getting it as an array of moment objects,try using moment js for formatting the moment js according to your needs
https://codesandbox.io/s/form-methods-ant-design-demo-sy4uq
function onOk(value) {
const start = moment(value[0]).format("YYYY-MM-DD HH:mm:ss");
const end = moment(value[1]).format("YYYY-MM-DD HH:mm:ss");
console.log(start, end);
}
const onFinish = values => {
const start = moment(values.Picker[0]).format("YYYY-MM-DD HH:mm:ss");
const end = moment(values.Picker[1]).format("YYYY-MM-DD HH:mm:ss");
console.log(start, end)
};

React Datepicker( can't get value of input)

I am new in react. I need use react-datepicker
I want to get value of input, when I change date.
If i click on 20th October 2017, i want put 20th October 2017 in my variable.
But the main problem that I should work with component, not with input.
Before I just took value from state. Like this.state.value. But right now it is object(Moment) in state. And this object doesn't have value field.
There is my code:
export default class DatePicker extends Component {
constructor (props) {
super(props);
// this.props.date should looks like "29 November 2017 00:00"
// second argument for moment() it is format of date, because RFC 2822 date time format
this.state = {
date: moment(this.props.value, 'LLL')
};
}
handleChange = (date) => {
// const valueOfInput = this.state.date <--- I want string with date here
console.log('this.state.date',this.state.date);
this.setState({date: date});
};
render() {
return <Form.Field>
<Label>
<Picker
selected={this.state.date}
onChange={this.handleChange}
dateFormat="LLL"
locale={this.props.language}
/>
</Label>
</Form.Field>
Just use this:
handleChange = date => {
const valueOfInput = date.format();
///...
};
Because this datepicker returns a moment.js object!
For more information, look into the moment.js docs here.
Try this
<DatePicker
onChange={(value, e) => this.handleChange(value, e)}
selected={this.state.inputValue} otherProps={here}
/>
// you can access the value field in handleChange by e.target.value
handleChange(value, e) {
console.log(value); // this will be a moment date object
console.log(e.target.value); // this will be a string value in datepicker input field
}
This solved for me by using the following:
handleDateChange = date => {
let selectedDateFromCalender = date.toUTCString();
this.setState({
actualStartDate: selectedDateFromCalender,
});}
<DatePicker
selected={this.state.startDate}
onChange={this.handleDateChange}/>
You can use the following methods as well, choose according to your requirement:
toISOString: "2020-10-05T09:10:38.000Z"
toJSON: "2020-10-06T09:09:16.000Z"
toUTCString: "Thu, 08 Oct 2020 09:11:24 GMT"
If you want to get the new value (once the user clicks on a new date from DatePicker) pass the event to the method.
class MyComponent extends React.Component {
constructor(props) {
this.state = {inputValue: moment(),} // this will set the initial date to "today",
// you could also put another prop.state value there
this.handleChange = this.handleChange.bind(this);
}
}
handleChange(value) {
console.log(value); // this will be a moment date object
// now you can put this value into state
this.setState({inputValue: value});
}
render(){
...
<DatePicker
onChange={(event) => this.handleChange(event)}
selected={this.state.inputValue} otherProps={here} />
...
}
};
The new version of react-datepicker library stopped using a moment.js object, so here is my solution if you want to get a formatted string representation of the date.
First import
import format from "date-fns/format";
Then
<DatePicker
onChange={(value)=>this.handleChange(format(value, "yyyy/MM/dd", {
awareOfUnicodeTokens: true }))}
dateFormat="yyyy/MM/dd"
selected={this.state.inputValue} otherProps={here} />
...
You can use the getTime() helper function on your date object to get the millisecond timestamp for that specific date, which is a JavaScript number data type. Useful for saving data in the backend of your application. For example Flask Peewee ORM requires a timestamp to be saved for the DateTimeField.
const [startDate, setStartDate] = useState(new Date())
<DatePicker
onSelect( date => {
setStartDate(getTime(date))
}
/>
source: https://date-fns.org/v2.0.0-alpha.7/docs/getTime
Combine it with an effect to set the default state value to a timestamp on page load:
useEffect(() => {
setStartDate(getTime(startDate))
}, [])
Otherwise for your UI, you can use the format() helper function to get the string value of the given object, with any given format:
<h1>{format(startDate, "MMMM d, yyyy h:mm aa")}</h1>
source: https://date-fns.org/v2.0.0-alpha.7/docs/format
I have same problem, and I solved it by using the below solution. Please try it:
<p>{this.state.date.toLocaleDateString()}</p>
<input id="tdate" type="date" name="todate" onchange="getToDate(event);">
function getToDate(e){
const tdate = e.target.value;
//alert(tdate);
//console.log(tdate);
//return tdate;
};
here i am trying to access "tdate" variable outside the function.

Resources