how to get selected dates in react calendar? - reactjs

I downloaded react-native-material-calandarview inside my project.
They just give some piece of code to get calendar. https://github.com/NuclleaR/react-native-material-calendarview.
I just selected datesSelection={'range'}, but I dont know where I get the selected dates. If datesSelection={'single'} it return date in
onDateChange={data => {
console.log(data.date);//date selected
}}
More code:
render() {
return (
<Calendar
width={(Dimensions.get('window').width)-32}
height={280}
tileHeight={35}
style={{alignSelf: 'center'}}
topbarVisible={true}
datesSelection={'range'}
firstDayOfWeek="monday"
showOtherDates="none"
currentDate={this.state.today}
selectedDates={this.state.dates}
eventsDates={[]}
eventsColor="#9C27B0"
onDateChange={data => {
//alert(sel_date);
console.log(this.state.data);
}}
onMonthChange={month => {
//alert(month)
console.log(month);
}}
/>
);
}

So the onChange will show you the date the user selects it's up to you to make a function to store these in redux/local state. Same for a range the onChange will return you that range in the argument you're passing to it
So what you can do is
In HTML:
onDateChange={this.onChange}
Component method:
onChange = (date) => { this.setState({ selectedDate: date }) };

Related

ant design - datepicker with time saves with 00:00:00 as time?

So im using antd for my design in frontend with React. I want to store an object with datetime in database. I see that antd's Datepicker is capable of that but it always stores in my database with 00:00:00 as time. Date, month year are ok.
I tried to use moment().format('YYYY-MM-DD HH:mm:ss') and save it like that in the database but i get error Uncaught TypeError: date.clone is not a function
This is my datepicker. The issue raises when i try to use my setPickedFrom function from useState. Why is this a problem?
<DatePicker
allowClear={false}
placeholder="Rent from: "
// format="YYYY-MM-DD HH:mm:ss"
disabledDate={disabledDate}
onChange={(e) => onDateClear(e, "from")}
onOk={(date) =>
setPickedFrom(
moment(date).format("YYYY-MM-DD HH:mm:ss"),
"to"
)
}
value={pickedFrom ? pickedFrom : null}
showTime
className="date-picker2"
/>
Saving the dates function (Create Rent)
const createRent = () => {
axios
.post("http://localhost:5000/rents/createRent", {
date_from: pickedFrom,
date_to: pickedUntil,
userId: user.id,
itemId: currentItem.id,
})
.then(() => {
showNotification("Item rented");
setCurrentItem({});
setDifference(null);
setIsModalVisible(false);
setPickedFrom(null);
setPickedUntil(null);
})
.catch((e) => {
showNotification(e.response.data.message, "error");
});
};
I just need to find a way to save date and time in my database in the following format (YYYY-MM-DD HH:mm:ss) because this is the accepted format for my database.
This is what you are looking for
const onOk = (value) => {
console.log("onOk: ", moment().format());
console.log("onOk: ", typeof value);
console.log("onOk: ", value.format("YYYY-MM-DD HH:mm:ss"));
};
<DatePicker format="YYYY-MM-DD HH:mm:ss" showTime={true} onOk={onOK}/>

autosuggest not showing item immediately

I am looking into fixing a bug in the code. There is a form with many form fields. Project Name is one of them. There is a button next to it.So when a user clicks on the button (plus icon), a popup window shows up, user enters Project Name and Description and hits submit button to save the project.
The form has Submit, Reset and Cancel button (not shown in the code for breviety purpose).
The project name field of the form has auto suggest feature. The code snippet below shows the part of the form for Project Name field.So when a user starts typing, it shows the list of projects
and user can select from the list.
<div id="formDiv">
<Growl ref={growl}/>
<Form className="form-column-3">
<div className="form-field project-name-field">
<label className="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-animated custom-label">Project Name</label>
<AutoProjects
fieldName='projectId'
value={values.projectId}
onChange={setFieldValue}
error={errors.projects}
touched={touched.projects}
/>{touched.projects && errors.v && <Message severity="error" text={errors.projects}/>}
<Button className="add-project-btn" title="Add Project" variant="contained" color="primary"
type="button" onClick={props.addProject}><i className="pi pi-plus" /></Button>
</div>
The problem I am facing is when some one creates a new project. Basically, the autosuggest list is not showing the newly added project immediately after adding/creating a new project. In order to see the newly added project
in the auto suggest list, after creating a new project,user would have to hit cancel button of the form and then open the same form again. In this way, they can see the list when they type ahead to search for the project they recently
created.
How should I make sure that the list gets immediately updated as soon as they have added the project?
Below is how my AutoProjects component looks like that has been used above:
import React, { Component } from 'react';
import Autosuggest from 'react-autosuggest';
import axios from "axios";
import { css } from "#emotion/core";
import ClockLoader from 'react-spinners/ClockLoader'
function escapeRegexCharacters(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// Use your imagination to render suggestions.
const renderSuggestion = suggestion => (
<div>
{suggestion.name}, {suggestion.firstName}
</div>
);
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
export class AutoProjects extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
projects: [],
suggestions: [],
loading: false
}
this.getSuggestionValue = this.getSuggestionValue.bind(this)
this.setAutoSuggestValue = this.setAutoSuggestValue.bind(this)
}
// Teach Autosuggest how to calculate suggestions for any given input value.
getSuggestions = value => {
const escapedValue = escapeRegexCharacters(value.trim());
if (escapedValue === '') {
return [];
}
const regex = new RegExp(escapedValue, 'i');
const projectData = this.state.projects;
if (projectData) {
return projectData.filter(per => regex.test(per.name));
}
else {
return [];
}
};
// When suggestion is clicked, Autosuggest needs to populate the input
// based on the clicked suggestion. Teach Autosuggest how to calculate the
// input value for every given suggestion.
getSuggestionValue = suggestion => {
this.props.onChange(this.props.fieldName, suggestion.id)//Update the parent with the new institutionId
return suggestion.name;
}
fetchRecords() {
const loggedInUser = JSON.parse(sessionStorage.getItem("loggedInUser"));
return axios
.get("api/projects/search/getProjectSetByUserId?value="+loggedInUser.userId)//Get all personnel
.then(response => {
return response.data._embedded.projects
}).catch(err => console.log(err));
}
setAutoSuggestValue(response) {
let projects = response.filter(per => this.props.value === per.id)[0]
let projectName = '';
if (projects) {
projectName = projects.name
}
this.setState({ value: projectName})
}
componentDidMount() {
this.setState({ loading: true}, () => {
this.fetchRecords().then((response) => {
this.setState({ projects: response, loading: false }, () => this.setAutoSuggestValue(response))
}).catch(error => error)
})
}
onChange = (event, { newValue }) => {
this.setState({
value: newValue
});
};
// Autosuggest will call this function every time you need to update suggestions.
// You already implemented this logic above, so just use it.
onSuggestionsFetchRequested = ({ value }) => {
this.setState({
suggestions: this.getSuggestions(value)
});
};
// Autosuggest will call this function every time you need to clear suggestions.
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
});
};
render() {
const { value, suggestions } = this.state;
// Autosuggest will pass through all these props to the input.
const inputProps = {
placeholder: value,
value,
onChange: this.onChange
};
// Finally, render it!
return (
<div>
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={this.getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
/>
<div className="sweet-loading">
<ClockLoader
css={override}
size={50}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
</div>
);
}
}
The problem is you only call the fetchRecord when component AutoProjects did mount. That's why whenever you added a new project, the list didn't update. It's only updated when you close the form and open it again ( AutoProjects component mount again)
For this case I think you should lift the logic of fetchProjects to parent component and past the value to AutoProjects. Whenever you add new project you need to call the api again to get a new list.

how to use react-big-calendar onRangeChange option

enter image description here
i want don't move calendar month so use this code
const FullCalendar = (props) => {
const { calendarInfos, height, dateInfo } = props
const { selectDate } = dateInfo
const localizer = momentLocalizer(moment);
return (
<>
<CalendarCss />
<Calendar
toolbar={false}
popup={false}
localizer={localizer}
culture='ko'
views={['month']}
events={calendarInfos}
defaultDate={new Date(moment(selectDate))}
startAccessor="start"
endAccessor="end"
onRangeChange={(e)=>{console.log(e)}}
style={{
height: height + 'px',
width: '100%',
}}
components={
{
event: (e) =>
(
<FullCalendarEvent
event={e}
/>
)
,
}
}
/>
</>
);
};
but there is an error in this code.
enter image description here
how to use react-big-calendar option onRangeChange
According to the documentation, it depends on the view (sorta).
const onRangChange = (Range: [Date]) => do something
// or, the more likely
const onRangChange = ({start: Date, end: Date}) => do something
Supposed to use the second type for all builtin views, so unsure when that first type would qualify...
If you're trying to restrict it from moving month to month, better option is to use the controlled date prop and do some check to determine wether you set it or not.

React: ChecBox checked state programmatically not reflecting checkbox state

I have a react table where I am showing and hiding columns individually on a checkbox click. If I remove the checked property from the checkbox input element things work as expected. However if I add it in and track the checked property using state, the check box will click off the first time but not back on but the column state does update and reappears.
Eventually my end goal is to be able to click the "remove all columns" option at the top of this list to show hide all columns. The show/hide piece works but the checking of the boxes does not.
updateColumnShow = fieldName => {
this.setState({ [fieldName]: !fieldName });
this.setState(state => {
const columns = state.columns.map(column => {
if (column.Header === fieldName) {
column.show = !column.show;
return column;
} else {
return column;
}
});
return { columns };
});
};
render() {
return (
<div>
{this.state.columnList.map(listItem => (
<li key={listItem}>
<input
id={listItem}
checked={this.state[listItem]}
className="form-check-input"
type="checkbox"
name={listItem}
onChange={() => this.updateColumnShow(listItem)}
/>
<label>{listItem}</label>
</li>
))}
</div>
);
}
I have created a CodeSandbox to demo the issue.
What am I overlooking?
You're passing a string (fieldName) to updateColumnShow, and then negating it as a boolean; this will always be false.
updateColumnShow = fieldName => {
this.setState({ [fieldName]: !fieldName });
}
The immediate fix is to invert your state value instead:
this.setState({ [fieldName]: !this.state[fieldName] });

Material ui pickers, how to prevent closing on redraw

I have a picker which is a part of a component where the date is given from another, super, component.
If the super component is redrawn (say due to a date change) the component that holds the datepicker is destroyed and recreated, thus losing the "open" state.
How would I make this managed? - I can manually state if a picker is "open" or not. However I cannot seem to hook up to the "click on date bar" or "click outside calendar", thus I cannot actually control this.
The component containing the picker:
export class DateDisplay extends React.Component {
render() {
const {date, onChange, onAccept, onOpen, label, openState} = this.props;
return <>
{label && <Typography variant={'subtitle2'} display={'inline'} style={{marginRight: '1ch'}}>
{label}
</Typography>}
<DatePicker
value={date}
onOpen={() => {
this.setState({open: true},onOpen)
}}
onChange={onChange}
onAccept={onAccept}
format={'ddd, D MMMM YYYY'}
variant={'inline'}
open={openState}
onClick={e => {
console.log('we clicked the picker')
}}
/>
</>
}
}
And the super component which would be responsible for "managing" the datepicker:
export class DatesList extends React.Component {
this.onSave = async () {/*code to request a save to the backend*/};
onStartEditing = () {/*code to visually indicate we're editing a field*/};
render() {
const {dates} = this.props; //date is a moment + meta data.
const sorted_dates = Array.from(eventData.dates.values()).sort(
(l, r) =>
(!l.start_date ? 0 : l.start_date.valueOf()) - (!r.start_date ? 0 : r.start_date.valueOf())
);
sorted_dates.map(date => {<div>
<DateDisplay
label={'Event start date:'}
date={date.start_date}
onOpen={(e) => {
this.onStartEditing(e, 'start_date');
}}
onChange={(newDate) => {
date.start_date = !nullOrUndefined(newDate) ? newDate.toDate() : newDate;
}}
onAccept={async () => {
await this.onSave('start_date');
}}
/>
</div>});
}
}
As a side question: I notice that the components are not rebuild if the sorting is removed, even though there is a single element in the list thus sorting would always give the same "order", why's that?
You can use your own state for opening/closing.
Use open prop and onClose and onOpen callbacks. Deeper example from documentation: https://material-ui-pickers.dev/guides/controlling-programmatically

Resources