React-Calendar month view change - javascript

I am using React-Calendar and I am unable to change the month bu clicking the arrows (back/ forward) in the navigation panel, where the month name is displayed. My code:
...
const onActiveStartDateChangeHandler = ({ activeStartDate, value, view }) => {
console.log("vv:", activeStartDate, value, view);
};
...
return (
<div className="popupFormSelector arrowLft pb-8">
<h2 className="text-center font-bold mt-7 mb-5">Set a deadline</h2>
<Delete classes="right-5 top-5" onClickHandler={toggleCalendar} />
<Calendar
activeStartDate={teamStartDate}
calendarType="US"
defaultView="month"
maxDetail="month"
maxDate={endDate}
minDate={teamStartDate}
next2Label={null}
onActiveStartDateChange={onActiveStartDateChangeHandler}
onChange={onChangeHandler}
prev2Label={null}
selectRange={false}
showDoubleView={false}
showFixedNumberOfWeeks={false}
showNavigation={true}
showNeighboringMonth={true}
tileClassName={tileClasses}
tileDisabled={({ activeStartDate, date, view }) =>
date < teamStartDate || date > endDate
}
value={new Date()}
view={"month"}
/>
From console.log on handler for onActiveStartDateChange, I can see that the date is changed in the log, however, the view stays at the current month. What am I doing wrong?

The month view doesn't change because it is tied to the value you provided here:
activeStartDate={teamStartDate}
As stated in the docs, this initiates a "controlled" behavior:
activeStartDate The beginning of a period that shall be displayed. If you wish to use React-Calendar in an uncontrolled way, use defaultActiveStartDate instead.
So either use defaultActiveStartDate instead of activeStartDate if it matches your use case, or you could simply update the value of teamStartDate in the method, like this:
const onActiveStartDateChange = ({activeStartDate}) => teamStartDate = activeStartDate

Related

React JS How to change value in #material-ui keyboarddatepicker which is already bound to a model field

In React JS I have a dropdown and a #material-ui keyboarddatepicker.
My datepicker is bound to a field in a json file...
<div>
Expiry Date:<KeyboardDatePicker
id="ExpiryDate"
disablePast
minDate={new Date()}
format="D/MM/yyyy"
mask="__/__/____"
value={Person.LocationExpiryDate}
/>
</div>
Note the bound value above from the'Person' model.
I have a dropdown control which on it's onChange event I would like to change the value in the keyboarddatepicker to 6 months hence....
{this.DropdownControl(lookups.PracticeLocations, true, Person.CPPEPracticeLocation, event => this.HandleChangePerson(event, 'Location'))}
</div>
HandleChangePerson (event, propertyName) {
if (propertyName == 'Location') {
// Get date 6 months from today
const todayDate = new Date().toISOString().slice(0, 10);
const newExpiryDate = moment(todayDate).add(6, 'M').format('D/MM/YYYY')
// TODO: code here to change the keyboarddatepicker value.
}
I've tried using state and plain js to change the value but because it is already bound it doesn't change the value
I've looked up 'two way binding' but can't seem to find anything that references using a model.

Please is there any way i can get access to a key 🗝 that matches a value selected on a dropdown in JavaScript?

I am learning Javascript / React and I have been doing this react project to make memes and I have all the data regarding the memes in an array of objects but I am stuck now for days without getting it to do what I want.
Inside each object is a name with a value, an ID with a value, A blank with the image URLs. I want to display the names to the user in a dropdown and I want to get access to the ID and blank value of the selected name from the dropdown so that I can feed the image to the user.
I have tried extracting the names and the IDs into separate strings and check for a matching word but sometimes the string value of the ID is not even included in the string values of the name, so that didn't work at all and now I did it like a kind of a hack with a counter that increases each time the onChange function is called and I used the number to feed the image according to the index matching the number but this gives me the wrong image anytime that a user decides to choose image randomly. This may sound a bit abstract so I have included some screenshots here and my code with a link to a code sandbox where all the program lives and hoping to get the help that I need, please.
Hers is the Code Snippets;
export default function MyComponent() {
const [bulkImageArray, setBulkImageArray] = useState([]);
const [counter, setCounter] = useState(1);
const [imageUrls, setImageUrls] = useState();
const [imagesNames, setImagesNames] = useState();
// This is the function that should get me access to the object id value when any value is selected.
function handleChange(event) {
setCounter(counter + 1);
console.log('You just selected: ' + event.target.value);
// setImagesNames(event.target.value);
setImagesNames(bulkImageArray[counter].name);
setImageUrls(bulkImageArray[counter].blank);
console.log(typeof event.target.value);
}
return (
<div>
<select onChange={handleChange}>
{bulkImageArray.map((item) => (
<option key={item.id}>
{/* {item.id} */}
{item.name}
</option>
))}
</select>
<img src={imageUrls} alt={imagesNames} />
<div>
{bulkImageArray.map((item) => (
<img
style={{
width: '400px',
height: '400px',
cursor: 'pointer',
}}
key={item.id}
alt={item.name}
src={item.blank}
/>
))}
</div>
</div>
);
}
}
screenshots:
Array of Objects Structure:
Single Object Structure:
Function Tigered on select:
The dropdown for users to select the image:
I don't know if all this information is enough but this is the code sandbox to the complete project.
Thanks in advance.
You should add value={item.id} to option, so that select onChange can select the value to id, then use the id to find the selected item.

how to reverse fetch images from nasa APOD api in react

** I fetched content from API with this code**
import React from "react";
import styles from "./Space.module.css";
import {useState,useEffect} from "react";
function Space() {
const [photoData,setPhotoData]=useState(null);
useEffect(()=>{
fetchPhoto();
async function fetchPhoto(){
const res = await fetch(`https://api.nasa.gov/planetary/apod?api_key=hETQq0FPsZJnUP9C3sUEFtwmJH3edb4I5bghfWDM`);
const data=await res.json();
setPhotoData(data);
console.log(data);
}
},[]); //empty array for running only once then empty array for that
if (!photoData) return <div />;
return (
<>
<div className={styles.space}>
{photoData.media_type === "image" ? (
<img
src={photoData.url}
alt={photoData.title}
className={styles.space}
/>
) : (
<iframe
title="space-video"
src={photoData.url}
frameBorder="0"
gesture="media"
allow="encrypted-media"
allowFullScreen
className={styles.space}
/>
)}
<div>
<h1>{photoData.title}</h1>
<p className={styles.space.date}>{photoData.date}</p>
<p className={styles.space.explanation}>{photoData.explanation}</p>
</div>
</div>
</>
);
}
export default Space;
and output of this code is like this
and I want Button here with next and then that will show previous day images
so can anyone tell me how to reverse that means after clicking on the next button by reversing the previous day images will show because NASA APOD(astronomy picture of the day )daily shown to all users like that is updated daily I know we can reverse that but can anyone tell me how to do that?
You can use date query parameter of apod api to get data for a specific date. This has default value today. Date needs to be in YYYY-MM-DD format. See apod section at https://api.nasa.gov/
If you want to request data for 2 January 2021 you'll have to send request to this :
https://api.nasa.gov/planetary/apod?date=2021-01-02&api_key=hETQq0FPsZJnUP9C3sUEFtwmJH3edb4I5bghfWDM
Note the date parameter
To get the previous day date use :
let today = new Date();
let yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
console.log(yesterday.toString());
for formatting date in YYYY-MM-DD format see this question.
In onClick function of your button you'll make this http request and then change state with setPhotoData function.

How to separate items from array?

I'm making weather app for 7 days and I need to create abillity for users to open some of days to see more information about weather of current day. So, it means that every item choosen by user has to contain unique id (i don't know could I use in this situation index instead of id) to show information only about some of day. So before this I had some code:
const DailyWeatherData = ({dailyData, isLoading}) => {
const getWeatherStatistic = (value0,value1) => {
if(dailyData && Array.isArray(dailyData.daily)){
return (
<div className="col-lg-3 box-daily-weather">
<NavLink to={'/WeatherDayStat'}>
{setDay([value1])}
<div className="temp-day">{Math.ceil(dailyData.daily[value0].temp.day)}°C</div>
<div className="feels-like">Feels like: {Math.ceil(dailyData.daily[value0].feels_like.day)}°C</div>
<div className="daily-weather-condition">Conditions: {dailyData.daily[value0].weather.map(e => e.main)}</div>
</NavLink>
</div>
)
}else {
return isLoading === true ? <Preloader /> : null
}
}
const setDay = (param) => {
return checkCod ? null : setCurrentDate(new Date(),param)
}
return (
<div>
<div className="daily-weather-container">
{checkCod ? null : <div className="daily-title">Daily Weather</div>}
<div className='row scrolling-wrapper justify-content-center'>
{getWeatherStatistic(1,1)}
{getWeatherStatistic(2,2)}
{getWeatherStatistic(3,3)}
{getWeatherStatistic(4,4)}
{getWeatherStatistic(5,5)}
{getWeatherStatistic(6,6)}
</div>
</div>
</div>
)
}
export default DailyWeatherData
In function getWeatherStatistic you can see 2 arguments, value0 - doesn't matter here, value1 - using to show only 1st-6 object, because array which i have got from ajax request contains more days(10) but I need to show only 6 of them. And most importantly, each of them is separate. Logically I'd use map, but It shows all items, so I can use slice but it also shows 6 items in 1 column.
The next problem, this array has not contain parameter like ID, that's why I can't add to NavLink id. If there were ID, I would make something like that dailyData.daily.map(p => <NavLink to={'/WeatherDayStat' + p.id}>)
Also, just in case, add the state code (daily - array which I need):
So I have 2 questions:
How to show only 6 days from array?
How to add unique ID to every Item from array?
Making something like this:
//making new array with data I need
let sliceDailyData = dailyData.daily ? dailyData.daily.slice(1,7) : null
//using map with new array
{sliceDailyData ? sliceDailyData.map((i) => <div key={i.dt} className="col-lg-3 box-daily-weather">
{getCurrentDate(new Date())}
<NavLink to={'/WeatherDayStat'}>
<div className="temp-day">{Math.ceil(i.temp.day)}°C</div>
<div className="feels-like">Feels like: {Math.ceil(i.feels_like.day)} °C</div>
<div className="daily-weather-condition">Conditions: {i.weather.map(i => i.main)} </div>
</NavLink>
</div>
): null}
Speaking about ID, I have created variable which generte id and push it to array.
You can store your dailyData.daily array in an object and then retrieve it with key, you can use something simple but SEO friendly like obj['day'+(dailyData.daily.indexOf(d)+1)]
obj{}
dailyData.daily.forEach(d=>array.indexOf(d)<=5?obj[String(Math.random())]=d:null)

How to implement validation/restriction in react-datepicker

I am trying to implement restriction or validation in a react-datepicker component. I am using redux-form for validation and normalization(to implement restriction)
https://redux-form.com/6.0.0-rc.1/examples/normalizing/
Question : I have observed that neither normalizing function nor validation functions of redux-form is called when we try to enter something in the field
although this value is not submitted when we submit the form but i need to show some validation error or restrict user from typing invalid characters.
I made a wrapper for the date picker component and used it in my form through redux field
my date picker component :-
return (
<div className={"render-date-picker "}>
<div className="input-error-wrapper">
{(input.value) ? <label> {placeholder} </label> : ''}
<DatePicker className="input form-flow" {...input}
placeholderText={placeholder}
selected={input.value ? moment(input.value) : null}
maxDate={maxDate || null}
minDate={minDate || null}
dateFormat={isTimePicker ? "LLL" : "DD/MM/YYYY"}
showYearDropdown
showMonthDropdown
disabledKeyboardNavigation
/>
{touched && error && <span className="error-msg">{t(error)}</span>}
<span className="bar" style={{ 'display': this.state.is_focus ? 'block' : 'none' }} ></span>
</div>
</div>
);
redux form field :-
<Field
name="date_of_birth"
type="text"
className="input form-flow extra-padding-datepicker"
component={RenderDatePicker}
maxDate={moment().subtract(18, "years")}
validate={[required, dateOfBirth]}
normalize={isValidDateFormat}
placeholder={t("DOB (DD/MM/YYYY)")}
/>
my normalizing function:-
export const isValidDateFormat = (value, previousValue) => {
if (value == null || !value.isValid()) {
return previousValue;
}
return value;
}
react-datepicker provides onChangeRaw property to get raw (typed) value inside the datePicker. In order to restrict or validate the datepicker input field we need the raw value which is not available on onChange event of the datepicker component.
for instance if we observe the onChange event :-
It returns a moment object.
In order to get raw value we use onChangeRaw
The raw value is obtained simply from e.target.value.
In my case I simply restrict the user from typing anything in the datepicker input field by a simple function:-
handleChangeRaw = (date) => {
let s=document.getElementById(date_picker_id)
s.value =moment(this.props.input.value).format("DD/MM/YYYY");
}
My datepicker component :-
<DatePicker
.....
disabledKeyboardNavigation
onChangeRaw={(e)=>this.handleChangeRaw(e)}
id={date_picker_id}
.....
/>
This solved my problem. Hope it is useful :)

Categories

Resources