Using the DateRangePicker from react-dates, I wish to disable Mondays, but only during the months of July and August. React is new to me and I don't know how to start solving this problem.
The documentation has a blockedDays prop, but it is not clear to me how I should use it for my particular case.
How can I access the currently displayed month and how can I subsequently block Mondays?
For those who wish to see my code, I have made a gist.
You can achieve this by using the isDayBlocked prop.
This prop is a function callback that will send you a moment date, and require you to send a boolean back, true meaning that the day is blocked and false meaning the opposite.
According to the moment documentation, here is how you will know if your day should be blocked or not :
isDayBlocked = momentDate => {
if (momentDate.format('ddd') === 'Mon' && ['Jul', 'Aug'].includes(momentDate.format('MMM')) return true
return false
}
The following condition would work as well (refer to the doc link above) :
momentDate.format('d') === 0 && [6, 7].includes(momentDate.format('M')
Short syntax :
isDayBlocked = momentDate => momentDate.format('d') === 0 && [6, 7].includes(momentDate.format('M')
And here is the picker :
<DateRangePicker
isDayBlocked={this.isDayBlocked}
// ... your other props
/>
I think I found it. In the code you gave me, you declare the isDayBlocked prop twice :
isDayBlocked={day1 => this.state.disabledDates.some(day2 => isSameDay(day1, day2))} //First time
startDateId="datePickerStart"
endDateId="datePickerEnd"
onDatesChange={this.onDatesChange}
onFocusChange={this.onFocusChange}
focusedInput={focusedInput}
startDate={startDate}
endDate={endDate}
minimumNights={minimumNights}
isOutsideRange={condition}
isDayBlocked = {momentDate => momentDate.format('d') === 0 } // Second one
You can merge them in a single function as shown in my first bit of code and put both conditions inside :
isDayBlocked = momentDate => {
if (momentDate.format('ddd') === 'Mon' && ['Jul', 'Aug'].includes(momentDate.format('MMM')) return true
if(this.state.disabledDates.some(day2 => isSameDay(day1, day2))) return true
return false
}
Following your comment, you have 2 solutions.
Converting the values you want to test to strings :
momentDate => momentDate.format('d') === '0' && ['6','7'].includes(momentDate.format('M')
Or using the non-strict operator :
momentDate => momentDate.format('d') == 0 && ['6', '7'].includes(momentDate.format('M')
Related
I have updated this question with clearer and more concise code on 15/03/22.
I have a text filter and it filters an array (displaying a list) correctly if it matches something in the displayed list, but as the user deletes character by character the filter does not change. I need it to keep matching as the user delete's chars.
Here is the filter which is set as the onChange for the text field:
const [searchInputTitle, setSearchInputTitle] = useState<string>('');
const [filteredItemsArrayState, setFilteredItemsArrayState] = useState<IListItems[]>(props.requests);
const searchTitles = () => {
let filteredArrayByTitle: IListItems[] = [];
filteredArrayByTitle = theRequestsState.filter((item) => {
return item.Title && item.Title.toLowerCase().indexOf(searchInputTitle.toLowerCase()) >= 0;
});
console.log(searchInputTitle, 'searchInputTitle');
if (searchInputTitle && searchInputTitle.length > 0) {
setTheRequestsState(filteredArrayByTitle);
setIsFiltered(true);
} else if (searchInputTitle && searchInputTitle.length === 0) {
const AllItems = props.requests;
let sortedByID: IListItems[] = AllItems.sort((a, b) => a.Id > b.Id ? 1 : -1);
setTheRequestsState(sortedByID);
setIsFiltered(false);
}
};
<TextField
onChange={searchTitles}
value={searchInputTitle}
/>
useEffect(() => {
_onTitleFilterChange(null, searchInputTitle);
if (isFiltered == true) {
setFunctionalArea(null, null);
setRequestingFunction(null, null);
}
}, [isFiltered, searchInputTitle]);
////////
<DetailsList className={styles.DetailsList}
items={filteredItemsArrayState.slice((ListPage - 1) * 50, ((ListPage * 50)))}
/>
Can anyone see why the render is not updating on deletion of char and what I could use to do so?
Update: As I type a character into the search I can see it's finding the searched for char/word and also if I delete chars now it searches and finds actively, but as soon as I stop typing it reverts back to the original array of items.
Can you try to filter the array you give to the DetailsList so you never lost the data ..?
filteredItemsArrayState.filter(s => {
if (searchInputTitle.length === 0)
return true
else
return s.Title.toLowerCase().match(searchInputTitle.toLowerCase())
}).map(....)
Found the reason. Thanks for all your help.
The issue was the setIsFiltered(true); in the title filter function. Other filters were running based on this line and these other filters were recalling the unfiltered list everytime a key was pressed. I removed this line and the issue was fixed.
I have come to realise that useEffect is almost completely mandatory on most of my projects and is React hooks are quite a departure from the original React syntax.
I am just getting started learning React one month ago. I am sorry if I asked a pretty easy question in advance.
Here is an issue,
what's the problem?
: I got data from back-end that is called "setWeekendEventData". When I console WeekendEventData, I can check I received the data that I want.
Here, I only want DayName. In this case, there are two DayNames. So, I tried to use the 'map' method because sometimes the DayName could be one or two or more than three.
First, I tried to like this
{weekendEventData.map((obj, index) => {
return <RedText>{obj[index].DayName}</RedText>;
})}
However, I got this error message "Cannot read properties of undefined (reading 'DayName')"
What I tried to do
{weekendEventData && weekendEventData.map((obj, index) => {
return <RedText>{obj[index].DayName}</RedText>;
})}
and
{[] && weekendEventData.map((obj, index) => {
return <RedText>{obj[index].DayName}</RedText>;
})}
I add the && condition to make it always true but there is the same error message. Usually, I solved this kind of error message by using && condition but it didn't work this time.
Using "Condition ? : " but it also didn't work
What I expected: It should be return DayName which is '개천절' and '한글날'
I would really appreciate your comments or solution!
edit 1:
const holiday = data => {
let array = [];
for (let i = 0; i <= 6; i++) {
if (data) {
if (array.includes(data[i])) i++;
else array.push(data[i]);
}
console.log("데이터 값", data[i]);
console.log("휴무일 배열", array);
}
and in the functional component
<RedText>{holiday(weekendData)}</RedText>
You use index wrongly here
obj[index].DayName
It should be corrected safely as below
obj.DayName || ""
Following will work with duplicates removed
<RedText>
{weekendEventData &&
weekendEventData
.reduce((prevValue, currValue) => {
prevValue.indexOf(currValue.DayName) < 0 &&
prevValue.push(currValue.DayName);
return prevValue;
}, [])
.join(", ")}
</RedText>
Hello I am using filter with map in react.
props.types.filter(data => (data.is_active === 1)).map((data, index) => {
// some code.
});
I am getting props.types in this component. But sometimes props.types does not contain is_active property. So in that case, map function doesn't return anything. I want to run filter only when data.is_active property exists.
How do I do this ?
UPDATE 1:
As I said above I want to run filter only if is_active is exists but I will always run map.
Add a condition to your filter that checks if is_active is not set.
This way your map will always be executed, except when is_active is not 1.
props.types
.filter((data) => data.is_active === undefined || data.is_active === 1)
.map((data, index) => {
// some code.
});
You can add conditional operator "?" after your filter method.
props.types.filter(data => (data.is_active === 1))?.map((data, index) => {
// some code.
});
Yesterday I had a behaviour that I don't understand by using Immer.js and setState together. I was using a setState (in a bad way, by the way) when fetching my data and this fetch was called at each endReached of my SectionList.
This setState looked like this:
this.setState((prev) => {
let sections = prev.sections
/* Extract alive topics from "topics"(array retrieved from fetch)*/
let topicsSection1 = topics.filter((card) => !card.states.is_killed)
/* Extract killed topics from "topics"(array retrieved from fetch)*/
let topicsSection2 = topics.filter((card) => card.states.is_killed)
if (sections[0] && sections[0].data)
sections[0].data = positionExtracted > 1 ? sections[0].data.concat(...topicsSection1) : topicsSection1
if (sections[1] && sections[0].data)
sections[1].data = positionExtracted > 1 ? sections[1].data.concat(...topicsSection2) : topicsSection2
return {
sections: sections,
position: response.position,
lastPage: response.laftPage
}
})
and everything worked just fine.
However, I have a function that is called when you press on the topic, and it changes the "opened" value of the topic in the data array to indicate to the list that "this topic" is open.
This function calls the "produce" function of Immer.js
And this function looks like this:
_onPressTopic = (id_card) => {
this.setState(produce((draft) => {
if (draft.sections[0] && draft.sections[0].data)
draft.sections[0].data = draft.sections[0].data.map((item) => {
if (item.id === id_card)
item.opened = !item.opened
return item
})
if (draft.sections[1] && draft.sections[1].data)
draft.sections[1].data = draft.sections[1].data.map((item) => {
if (item.id === id_card)
item.opened = !item.opened
return item
})
}))
}
MY PROBLEM IS:
If I open a topic and then my list data goes through this function, then when an endReached is called again, either I get an error "This object is not expensive", or my list data is not modified at all. And if instead of my first setState, I use a produce from Immer, everything works again.
What I don't understand is: Why does everything work perfectly if I only use Immer.js or just SetState, but as soon as I try to use both together, they don't seem to get along?
Thank you for your answers,
I hope I made it clear !
Viktor
I created one calendar and I don't find the solution to add one className when the date is equal "today", please see the link demo:
https://compassionate-beaver-fe6c05.netlify.com/
the code is:
https://github.com/fzabra/react-calendar/blob/master/src/Components/Calendar.jsx
The follow condition return the date today:
if (dateDay === today.getDate() && currentYear === today.getFullYear() && currentMonth === today.getMonth()) {
console.log(dateDay)
}
Observe that the console show the date of today. The square today is a it element have one id="dateDay", I think something like document.getElementById doesn't work, anybody has any ideas?
Thank you
Using the .box .green class from your CSS file, you can push the <Table.Cell> inside the if condition or else don't use the className, like so:
if (dateDay === today.getDate() && currentYear === today.getFullYear() && currentMonth === today.getMonth()) {
children.push(<Table.Cell key={j} id={dateDay} className="box green">{dateDay}</Table.Cell>)
} else{
children.push(<Table.Cell key={j} id={dateDay} className="box">{dateDay}</Table.Cell>)
This way the current date will have a green background.
Result
Full code