Move to day view when click on month view cell - react-big-calendar

Want to change the view programatically from month to day using state when month cell is clicked, the click event is getting captured, but isn't working:
const localizer = BigCalendar.momentLocalizer(moment);
export default class Calendario extends React.Component {
state = {
defaultView: "month",
defaultDate: new Date()
};
renderCell = props => (
<Card
{...props.children.props}
onClick={() => {
this.handleSelect(props.value);
}}
>
{props.children}
</Card>
);
handleSelect = (date) => {
this.setState({ defaultView: "day" });
};
render() {
const { defaultView, defaultDate } = this.state;
return (
<div>
<h4>Agenda</h4>
<div style={{ display: "flex", height: "600px" }}>
<BigCalendar
components={{
dateCellWrapper: this.renderCell
}}
defaultDate={defaultDate}
defaultView={defaultView}
localizer={localizer}
startAccessor="start"
endAccessor="end"
/>
</div>
</div>
);
}
}
I've looking the API docs, the most similar is onView, but it's triggered from within the library.

You can create a custom Toolbar in which you will have access to onView
export const CustomToolbar = ({ onView, views = ['month', 'week', 'day', 'agenda'] }) => (
<div>
{
views.map(view => (
<button
key={view}
onClick={() => onView(view)}
>
{view}
</button>
))
}
</div>
)
<BigCalendar components={{ toolbar: CustomToolbar }} />

Related

How to make native-base Modal works well with KeyboardAvoildingView in Android?

I try to add KeyboardAvoidingView to the Modal Component.
But when i call the keyboard up, the modal doesnt move and still be covered by keyboard.
This is my code : https://snack.expo.dev/#tikkhun/joyous-blueberries
After searching and asking. I get a way to work well: just use behavior: "position"
Here is My example Component:
/**
* #file: 弹出框
*/
import React, { useRef, useEffect, useState } from 'react';
import { Center, Button, HStack, Input, KeyboardAvoidingView, Modal, Spacer, Text } from 'native-base';
import { useTranslation } from 'react-i18next';
export default function ModalContent({ isOpen, onClose, title, defaultValue, type = 'input', onSave }) {
const { t } = useTranslation();
const [value, setValue] = useState();
const inputRef = useRef(null);
useEffect(() => {
// 这里的 setTimeout 是为了让键盘正常弹出
setTimeout(() => {
if (inputRef?.current) {
inputRef.current.focus();
}
}, 10);
});
useEffect(() => {
setValue(defaultValue);
return () => {
setValue('');
};
});
return (
<Modal isOpen={isOpen} onClose={onClose}>
<KeyboardAvoidingView style={{ width: '100%' }} behavior="position">
<Center>
<Modal.Content style={{ width: '100%' }}>
<Modal.Header>
<HStack space="3" alignItems="center">
<Text fontSize="md">{title}</Text>
<Spacer />
<Button
_text={{ fontSize: 'md' }}
variant="ghost"
onPress={() => {
onSave && onSave(value);
}}>
{t('settings.save')}
</Button>
</HStack>
</Modal.Header>
<Modal.Body>
<Input size="2xl" ref={inputRef} defaultValue={value} onChangeText={v => setValue(v)} />
</Modal.Body>
</Modal.Content>
</Center>
</KeyboardAvoidingView>
</Modal>
);
}

i used DateTimePicker in react-native I want to show Selected Date

I am new to react native. I want to show My selected date it show in console. now in below code of dateTimePicker .what do you think the best solution please help. thanks
import React, { Component } from "react";
import DateTimePicker from "react-native-modal-datetime-picker";
export default class booking extends React.Component {
showDateTimePicker = () => {
this.setState({ isDateTimePickerVisible: true });
};
hideDateTimePicker = () => {
this.setState({ isDateTimePickerVisible: false });
};
handleDatePicked = date => {
console.warn("A date has been picked: ", date);
this.hideDateTimePicker();
};
}
render(){
return (
<View style={styles.container}>
<Text style={styles.selectDate}>Select Date:</Text>
<Button title="click:" onPress={this.showDateTimePicker} />
<Text>ateTime: {String(this.state.date)}</Text>
<DateTimePicker
maximumDate={new Date(2022, 10, 20)}
minimumDate={new Date(2021, 5, 2)}
isVisible={this.state.isDateTimePickerVisible}
mode="date"
onChange={ date => this.setState({ date }) }
onConfirm={this.showDateTimePicker}
onCancel={this.hideDateTimePicker}
/>
}
You were not using DateTimePicker properly. The simplest way to implement the DateTimePicker is to create a function that will trigger the Calendar or the Clock inside an input field when user click on the button or Text.
<TextInput
placeholder=""
onFocus={()=>RenderStartClock()}
/>
The function may be as below:
const RenderStartClock = () => {
<DateTimePicker
testID="dateTimePicker"
value={startTime}
mode={timeMode}
is24Hour={true}
display="clock"
onChange={onChangeStartTime}
/>
}

Why can't I edit a text again in TextInput using state of hooks?

I'm currently developing an application using React Native.
This trial app has a component that has a TextInput and two buttons (ADD and DELETE).
When I press the ADD Button, a new component appears. If I press the DELETE Button that the same component disappears.
I control the TextInput with the index which is the same number as the index of the component.
The screen is like the photo bellow:
In this code, there is a bug when I edit some text I already inputes.
For Exanple:
enter some text at the input area index[0], then it works well.
press ADD button
edit the text I already done at the input area index[0] again, then I can't enter
text well...
My question is: why can't I edit the text I already inputted?
Here is the code:
import React, { useState } from "react";
import { View, Text, Button, TextInput, StyleSheet } from "react-native";
function Item({ number, handleInput, handleAdd, handleDelete, index }) {
return (
<View style={styles.list}>
<Text>{index}</Text>
<TextInput
style={{ borderWidth: 1 }}
value={number[index]}
onChangeText={(text) => {
handleInput(index, text);
}}
></TextInput>
<Button
title="ADD"
onPress={() => {
handleAdd();
}}
/>
<Button
title="DELETE"
onPress={() => {
handleDelete(index);
}}
/>
</View>
);
}
export default function SOFStateArray() {
const [count, setCount] = useState(1);
const [number, setNumber] = useState([]);
function handleAdd() {
setCount((v) => v + 1);
}
function handleDelete(index) {
setCount((v) => v - 1);
setNumber((v) => {
const ret = v.slice();
ret.splice(index, 1);
return ret;
});
}
function handleInput(index, text) {
setNumber((v) => {
v.splice(index, 1, text);
return v;
});
}
// function handleInput(index, text) {
// setNumber((v) => {
// const ret = v.slice();
// ret.splice(index, 1, text);
// return ret;
// });
// }
return (
<View>
{Array.from({ length: count }, (_, i) => (
<Item
number={number}
handleInput={handleInput}
handleAdd={handleAdd}
handleDelete={handleDelete}
key={i + "-" + number}
index={i}
/>
))}
</View>
);
}
const styles = StyleSheet.create({
list: {
margin: 10,
padding: 10,
backgroundColor: "#ddd",
},
});
Here is the first modified code(with roop to make components):
import React, { useState } from "react";
import { View, Text, Button, TextInput, StyleSheet } from "react-native";
function Item({ number, handleInput, handleAdd, handleDelete, index }) {
return (
<View style={styles.list}>
<Text>{index}</Text>
<TextInput
style={{ borderWidth: 1 }}
value={String(number)}
onChangeText={(text) => {
console.log(text);
handleInput(index, text);
}}
></TextInput>
<Button
title="ADD"
onPress={() => {
handleAdd();
}}
/>
<Button
title="DELETE"
onPress={() => {
handleDelete(index);
}}
/>
</View>
);
}
export default function SOFStateArray() {
const [count, setCount] = useState(1);
const [numbers, setNumber] = useState([0]);
function handleAdd() {
setCount((v) => v + 1);
}
function handleDelete(index) {
setCount((v) => v - 1);
setNumber((v) => {
const ret = v.slice();
ret.splice(index, 1);
return ret;
});
}
function handleInput(index, text) {
setNumber((v) => {
v.splice(index, 1, text);
return v;
});
}
// function handleInput(index, text) {
// setNumber((v) => {
// const ret = v.slice();
// ret.splice(index, 1, text);
// return ret;
// });
// }
return (
<View>
{numbers.map((number, i) => (
<Item
number={number}
handleInput={handleInput}
handleAdd={handleAdd}
handleDelete={handleDelete}
key={i + "-" + number}
index={i}
/>
))}
</View>
);
}
const styles = StyleSheet.create({
list: {
margin: 10,
padding: 10,
backgroundColor: "#ddd",
},
});
node : 12.18.3
react native : 4.10.1
expo : 3.22.3
JavaScript array splice modifies the original array. And this means the array variable itself doesn't change. I suggest you to clone the original array, splice the cloned array and return it. This can work because react compares the old props to the new props and rerenders the component only when the props are different. For now, even though you removed an item from array, the array variable didn't change and it doesn't rerender the component.
import React from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
StatusBar,
TextInput,
Button,
} from 'react-native';
function Item({text, handleInput, handleAdd, handleDelete, index}) {
return (
<View style={styles.list}>
<Text>{index}</Text>
<TextInput
style={{borderWidth: 1}}
value={text}
onChangeText={(t) => {
handleInput(index, t);
}}
/>
<Button
title="ADD"
onPress={() => {
handleAdd();
}}
/>
<Button
title="DELETE"
onPress={() => {
handleDelete(index);
}}
/>
</View>
);
}
class App extends React.Component {
state = {
texts: [''],
};
handleAdd = () => {
const {texts} = this.state;
this.setState({texts: [...texts, '']});
};
handleDelete = (index) => {
const texts = [...this.state.texts];
texts.splice(index, 1);
this.setState({texts: texts});
};
handleInput = (index, text) => {
const {texts} = this.state;
texts[index] = text;
this.setState({texts});
};
render() {
const {texts} = this.state;
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<View style={styles.body}>
{texts.map((text, i) => (
<Item
key={'' + i}
text={text}
handleInput={this.handleInput}
handleAdd={this.handleAdd}
handleDelete={this.handleDelete}
index={i}
/>
))}
</View>
</SafeAreaView>
</>
);
}
}
const styles = StyleSheet.create({
body: {
backgroundColor: '#ffffff',
},
});
export default App;

Redux reducer not changing prop

I am making a todo list application with redux. I am able to add todos perfectly fine with redux however my toggle todos and remove todos are having problems.
The toggle todo action gets called by the redux store (I see it happening in the debugger), however, it does not update the prop to be the opposite of completed and I am not sure why.
I have tried playing around with the syntax and modeling other people's redux todo lists for hours but have not been able to solve this issue.
My toggleTodo and removeTodo actions:
export const toggleTodo = (item) => {
return {
type: TOGGLE_TODO,
id: item.id
};
};
export const removeTodo = (item) => {
return {
type: REMOVE_TODO,
id: item.id
};
};
My TodoReducer: // this is where I suspect the problem is
const initialState = {
todos: []
};
const todos = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_TODO:
if (state.id !== action.id) {
return state;
}
return {
...state, completed: !state.todos.completed
};
case REMOVE_TODO: {
const newState = [...state];
newState.splice(action.id, 1);
return { ...newState };
}
My main flatlist where I call the actions:
render() {
return (
<View style={{ height: HEIGHT }}>
<FlatList
data={this.props.todos}
extraData={this.state}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => {
return (
<TodoItem
todoItem={item}
pressToToggle={() => this.props.toggleTodo(item)}
deleteTodo={() => this.props.removeTodo(item)}
/>
);
}}
/>
</View>
);
}
}
export default connect(mapStateToProps, { addTodo, toggleTodo, removeTodo })(MainTodo);
// I call the actions I am using here and don't use mapDispatchToProps
And my TodoItem component where I pass in the props:
class TodoItem extends Component {
render() {
const todoItem = this.props.todoItem;
return (
<View>
<TouchableOpacity
style={styles.todoItem}
onPress={this.props.pressToToggle}
>
<Text
style={{
color: todoItem.completed ? '#aaaaaa' : '#f5f5f5',
textDecorationLine: todoItem.completed ? 'line-through' : 'none',
fontSize: 16 }}
>
{todoItem.text}
</Text>
<Button
title='Remove'
color='#ff5330'
onPress={this.props.deleteTodo}
/>
</TouchableOpacity>
</View>
);
}
}
When I hit toggle todo instead of the prop changing and the line coming through over the text nothing happens.
And when I try to remove a todo I get this error- "invalid attempt to spread non-iterable instance."
when you pass a function to component, try to pass it's reference, instead of
<TodoItem
todoItem={item}
pressToToggle={() => this.props.toggleTodo(item)}
deleteTodo={() => this.props.removeTodo(item)}
/>
try
<TodoItem
todoItem={item}
pressToToggle={this.props.toggleTodo.bind(this)}
deleteTodo={this.props.removeTodo.bind(this)}
/>
and in your TodoItem component call the function like
class TodoItem extends Component {
render() {
const todoItem = this.props.todoItem;
return (
<View>
<TouchableOpacity
style={styles.todoItem}
onPress={() => this.props.pressToToggle(todoItem)} /* this line */
>
<Text
style={{
color: todoItem.completed ? '#aaaaaa' : '#f5f5f5',
textDecorationLine: todoItem.completed ? 'line-through' : 'none',
fontSize: 16 }}
>
{todoItem.text}
</Text>
<Button
title='Remove'
color='#ff5330'
onPress={this.props.deleteTodo}
/>
</TouchableOpacity>
</View>
);
}
}

Custom Arrows react-slick

I am using react-slick to create a carousel in my project.
I've read through the documents and tried different things but could not find a way to customize it exactly the way I need... Does anyone knows if there a way to have the nextArrow show on/in front of the image and not on its right?
See image below for desired result:
image
Thanks for your help!
I faced the same problem and have been trying to search for the solutions by following this CustomArrows documentation and some other suggestions but none of them working as what I wanted to (use different icons for the arrow and display the arrow on top of the slides). Then I tried to follow this previousNextMethods documentation, and try to adjust it from there.
index.js
renderArrows = () => {
return (
<div className="slider-arrow">
<ButtonBase
className="arrow-btn prev"
onClick={() => this.slider.slickPrev()}
>
<ArrowLeft />
</ButtonBase>
<ButtonBase
className="arrow-btn next"
onClick={() => this.slider.slickNext()}
>
<ArrowRight />
</ButtonBase>
</div>
);
};
render() {
return (
<div className="App">
<div style={{ position: "relative", marginTop: "2rem" }}>
{this.renderArrows()}
<Slider
ref={c => (this.slider = c)}
dots={true}
arrows={false}
centerMode={true}
slidesToShow={2}
>
<div>
<img src="http://placekitten.com/g/400/200" alt="cat" />
</div>
<div>
<img src="http://placekitten.com/400/200" alt="cat" />
</div>
<div>
<img src="http://placekitten.com/g/400/200" alt="cat" />
</div>
<div>
<img src="http://placekitten.com/400/200" alt="cat" />
</div>
</Slider>
</div>
</div>
);
}
style.css
.App {
font-family: sans-serif;
}
.slider-arrow {
position: absolute;
z-index: 1;
height: 100%;
width: 100%;
}
.arrow-btn {
top: 45%;
}
.next {
float: right;
}
I hope this will help. codesandbox
I tend to disable the arrows and build them myself.
Create a reference
const slider = React.useRef(null);
Attach to the slider
<Slider ref={slider} {...settings}>
Add your buttons wherever you want
<button onClick={() => slider?.current?.slickPrev()}>Prev</button>
<button onClick={() => slider?.current?.slickNext()}>Next</button>
See official documentation
https://react-slick.neostack.com/docs/example/custom-arrows/
https://react-slick.neostack.com/docs/example/previous-next-methods
Code from there:
import React, { Component } from "react";
import Slider from "react-slick";
function SampleNextArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "red" }}
onClick={onClick}
/>
);
}
function SamplePrevArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "green" }}
onClick={onClick}
/>
);
}
export default class CustomArrows extends Component {
render() {
const settings = {
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div>
<h2>Custom Arrows</h2>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
}
OR
import React, { Component } from "react";
import Slider from "react-slick";
export default class PreviousNextMethods extends Component {
constructor(props) {
super(props);
this.next = this.next.bind(this);
this.previous = this.previous.bind(this);
}
next() {
this.slider.slickNext();
}
previous() {
this.slider.slickPrev();
}
render() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
return (
<div>
<h2>Previous and Next methods</h2>
<Slider ref={c => (this.slider = c)} {...settings}>
<div key={1}>
<h3>1</h3>
</div>
<div key={2}>
<h3>2</h3>
</div>
<div key={3}>
<h3>3</h3>
</div>
<div key={4}>
<h3>4</h3>
</div>
<div key={5}>
<h3>5</h3>
</div>
<div key={6}>
<h3>6</h3>
</div>
</Slider>
<div style={{ textAlign: "center" }}>
<button className="button" onClick={this.previous}>
Previous
</button>
<button className="button" onClick={this.next}>
Next
</button>
</div>
</div>
);
}
}
You can try this way
render() {
const ArrowLeft = (props) => (
<button
{...props}
className={'prev'}/>
);
const ArrowRight = (props) => (
<button
{...props}
className={'next'}/>
);
const settings = {
arrows: true,
prevArrow: <ArrowLeft />,
nextArrow: <ArrowRight />,
};
return (
<Slider {...settings}>
{/* items... */}
</Slider>
)
}
If anyone tries to achieve the same result, the way to do it is with some css:
.slick-next {
right: 25px;
}
import React, { Component } from "react";
import Slider from "react-slick";
function SampleNextArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "red" }}
onClick={onClick}
/>
);
}
function SamplePrevArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "green" }}
onClick={onClick}
/>
);
}
export default class CustomArrows extends Component {
render() {
const settings = {
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div>
<h2>Custom Arrows</h2>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
}
Check the React-slick Custom Next & Prev buttons here : https://react-slick.neostack.com/docs/example/custom-arrows
Add custom css style
.slick-next {
background: url('./images/next.png') center center no-repeat!important;
&::before {
display: none;
}
}
.slick-prev {
background: url('./images/back.png') center center no-repeat!important;
&::before {
display: none;
}
}
You can build your own arrows and it is mentioned in their documentation like everyone pointed out above.
But if you want to change the images (which mostly would be the case) so what I did was just added 2 lines of code for slider .slick-next:before & .slick-prev:beforeand replaced the content with images. With this you dont need to handle disabling the arrows on last item (which is default). Using the code below just changes your arrows and rest of the behavior remains the same.
See the code below
.some_class .slick-slider {
button.slick-next:before {
content: url("your_image_here.svg");
}
button.slick-prev:before {
content: url("your_image_here.svg");
}
}
Remember that it is required to add onClick prop to your buttons:
const SlickArrow = ({onClick}: props) => (
<button onClick={onClick}><Icon.Arrow /></button>
);
I started with the answer from Oleg above and changed it just a bit to use FontAwesome icons. This method works well to keeps the extra properties from being sent to the FontAwesome components that result in errors such as "React does not recognize the currentSlide prop on a DOM element". Thanks to Oleg for the pattern.
import React from 'react';
import Slider from 'react-slick';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
const SomeComponent: React.FC = (): JSX.Element => {
const NextArrow = (props: any) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: 'block' }}
onClick={onClick}
>
<FontAwesomeIcon icon="fa-solid fa-chevron-right" />
</div>
);
};
const PrevArrow = (props: any) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: 'block' }}
onClick={onClick}
>
<FontAwesomeIcon icon="fa-solid fa-chevron-left" />
</div>
);
};
const settings = {
// other settings here ...
nextArrow: <NextArrow />,
prevArrow: <PrevArrow />,
// more settings here ...
};
return (
<Slider {...settings}>
{/* inner stuff here */}
</Slider>
);
};
This example replaces the default arrow by another icon
import Slider from "react-slick";
import './Example2.css'
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import { FaBeer } from 'react-icons/fa'
function SampleNextArrow(props: any) {
const { className, style, onClick } = props;
return (
<div
className={className}
onClick={onClick}
><FaBeer style={{ ...style, color: "red", fontSize: "30px" }} /></div>
);
}
function SamplePrevArrow(props: any) {
const { className, style, onClick } = props;
return (
<div
className={className}
onClick={onClick}
><FaBeer style={{ ...style, color: "red", fontSize: "30px" }} /></div>
);
}
const Example2 = () => {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div className="wrapper">
<h1>example 2</h1>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
export default Example2;
and the css
.slick-arrow.slick-next:before {
content: "";
}
.slick-arrow.slick-prev:before {
content: "";
}
import React from 'react';
import Slider from 'react-slick';
import prevArrow from './prev-arrow.svg';
import nextArrow from './next-arrow.svg';
const SliderCarousel = () => {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
prevArrow: <CustomPrevArrow />,
nextArrow: <CustomNextArrow />
};
return (
<Slider {...settings}>
{/* Slides */}
</Slider>
);
};
const CustomPrevArrow = (props) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, width: '50px', height: '50px', backgroundImage: `url(${prevArrow})`}}
onClick={onClick}
/>
);
}
const CustomNextArrow = (props) => {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, width: '50px', height: '50px', backgroundImage: `url(${nextArrow})`}}
onClick={onClick}
/>
);
}
export default SliderCarousel;
You can do like this