how can i create modal page in function? - javascript

Calendar/index.js
constructor(props) {
this.state = {
CalendarModalVisible: false
};
}
toggleCalendarModal = () => {
this.setState({ CalendarModalVisible: !this.state.CalendarModalVisible });
}
setModalPage = () => {
return(
<Modal isVisible={this.state.CalendarModalVisible} onBackdropPress={() =>
{ this.toggleCalendarModal() }} >
<View style={this.style.modal_container} >
</View>
</Modal>
);
}
renderDay(day, id) {
....
return (
<TouchableOpacity onPress={() => { this.setModalPage();
this.toggleCalendarModal() }}>
<View style={[this.style.home_day, { height: days_len }]} key={day}
>
<View style={{ flex: 1, alignItems: 'center' }} key={id}>
<DayComp
...
>
{date}
</DayComp>
</View>
</View>
</TouchableOpacity>
);
renderWeek(days, id) {
const week = [];
days.forEach((day, id2) => {
week.push(this.renderDay(day, id2));
}, this);
return (<View style={[this.style.home_week} key=
{id}>{week}
</View>);
render() { ...}
return( <View
...calendar component
</View>
);
I am modifying the calendar/index.js in the react-native-calendar module.
I made the calendar page like iphone calendar.
and I want the modal page show if i click the view home_day in renderday function.....
the setModalPage function is working well, but the modal page is not showing.
how can I resolve the problem..?
Edit
I resolve the problem myself.
I added {this.forceUpdate()} in toggleCalendarModal function.

Related

How to make reusable component in react-native and call them inside other component?

I have a modal component that I want to reuse in future component.
For this reason I want to have it in its own file.
I don't manage to call the component inside the other properly though.
Here is my last attempt of it.
The Modal component code:
export const FlyingDescription = (cityDescription) => {
const [modalVisible, setModalVisible] = useState(false);
return (
<View>
<Modal
animation="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => setModalVisible(!modalVisible)}
>
<View style={styleBoxParent}>
<View style={styleBoxChildren}>
<LinearGradient
style={styleLinearGradient}
colors={['#136a8a', '#267871']}
start={[0, 0.65]}
>
<Text style={styleText}>{cityDescription}</Text>
<Pressable
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styleText}>Close</Text>
</Pressable>
</LinearGradient>
</View>
</View>
</Modal>
</View>
);
};
The component where I want to call the Modal component:
import FlyingDescription from './FlyingDescription.js';
var utils = require('./utils');
export default class SearchScreen extends React.Component {
constructor(props) {
super(props);
this.navigation = props.navigation;
this.state = {
searchInput: '',
item : {},
renderSearch: false,
renderFlyingDescription: false,
};
this.errorMessage = 'Search for cities...';
}
resetState = () => {
this.setState({
item: {},
renderable: false,
}); }
setSearchInput = (value) => {
this.setState({
searchInput: value
});
}
searchCity = () => {
this.resetState();
utils.fetchWeather(this.state.searchInput).then(response => {
if (response.cod == 200) {
console.log(response);
this.setItemState(
{
name: response.name,
temp: Math.ceil(response.main.temp),
type: response.weather[0].main,
desc: 'Humidity: ' + response.main.humidity + '% - ' + response.weather[0].main
}
);
this.setRenderSearch();
}
});
}
setItemState = (newItem) => {
this.setState(
{
item: newItem,
}
);
}
setRenderSearch = () => {
this.setState(
{
renderSearch: true,
}
);
}
render = () => {
return(
<View style={utils.style.container}>
<StatusBar barStyle="light-content" />
<Text style={utils.style.titleContainer}>☀️ CityWeather</Text>
<View style={{alignItems: 'center', width:'90%'}}>
<Text>Search for a city</Text>
<TextInput
onChangeText={(value) => this.setSearchInput(value)}
value={this.searchInput}
style={{ width: '80%', padding: 15, margin: 5, backgroundColor: 'black', color: 'white' }}
/>
<TouchableHighlight
style={{backgroundColor: 'grey', padding: 20, borderRadius: 8}}
onPress={this.searchCity}
>
<Text style={{fontSize: 14, color:'white'}}>Search</Text>
</TouchableHighlight>
</View>
{ this.state.renderSearch ? (
<TouchableHighlight
underlayColor="white"
onPress={ () => this.setState({renderFlyingDescription: true})}
>
<LinearGradient
colors={['rgba(0,0,0,0.05)', 'rgba(0,0,0,0)']}
start={[0, 0.5]}
>
<View style={utils.style.row}>
<Text style={[utils.getTempRange(this.state.item.temp), utils.style.temp]}>
{utils.getEmoji(this.state.item.type)} {this.state.item.temp} °C
</Text>
<Text style={utils.style.cityName}>{this.state.item.name}</Text>
</View>
</LinearGradient>
</TouchableHighlight>
) : (
// WHERE I WANT TO RENDER MY MODAL COMPONENT
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center', fontSize: 32}}>
<Text>{this.errorMessage}</Text>
</View>
)
}
{
renderFlyingDescription(this.state.renderFlyingDescription, this.state.item.desc)
}
</View>
);
}
}
export function renderFlyingDescription(isInterpretable, cityDescription) {
if(isInterpretable) {
return <FlyingDescription cityDescription={cityDescription} />
}
}

React Native Swipeable close after onPress not working

So I've seen many posting the same problem, but for some I don't seem to be able to adapt the posted solutions to my case.. I hope someone can tell me exactly what changes I need to do in order to get this working, since I don't know how to implement the suggested solutions!
I am using React Native Swipeable
Example of someone having the same issue
I have a file in which I built the Swipeable Component and an other class which calls the component. I've set a timeout close function on the onSwipeableOpen as a temporary solution. But ideally it should close immediately upon pressing "delete". The "..." stands for other code which I deleted since it's not important for this case.
AgendaCard.js
...
const RightActions = ({ onPress }) => {
return (
<View style={styles.rightAction}>
<TouchableWithoutFeedback onPress={onPress}>
<View style={{ flexDirection: "row", alignSelf: "flex-end" }}>
<Text style={styles.actionText}>Löschen</Text>
<View style={{ margin: 5 }} />
<MaterialIcons name="delete" size={30} color="white" />
</View>
</TouchableWithoutFeedback>
</View>
);
};
...
export class AgendaCardEntry extends React.Component {
updateRef = (ref) => {
this._swipeableRow = ref;
};
close = () => {
setTimeout(() => {
this._swipeableRow.close();
}, 2000);
};
render() {
return (
<Swipeable
ref={this.updateRef}
renderRightActions={() => (
<RightActions onPress={this.props.onRightPress} />
)}
onSwipeableOpen={this.close}
overshootRight={false}
>
<TouchableWithoutFeedback onPress={this.props.onPress}>
<View style={styles.entryContainer}>
<Text style={styles.entryTitle}>{this.props.item.info}</Text>
<Text style={styles.entryTime}>
eingetragen um {this.props.item.time} Uhr
</Text>
</View>
</TouchableWithoutFeedback>
</Swipeable>
);
}
}
Agenda.js
...
renderItem(item) {
...
<AgendaCardAppointment
item={item}
onRightPress={() => firebaseDeleteItem(item)}
/>
...
}
I'm having the same issue and have been for days. I was able to hack through it, but it left me with an animation I don't like, but this is what I did anyways.
export class AgendaCardEntry extends React.Component {
let swipeableRef = null; // NEW CODE
updateRef = (ref) => {
this._swipeableRow = ref;
};
close = () => {
setTimeout(() => {
this._swipeableRow.close();
}, 2000);
};
onRightPress = (ref, item) => { // NEW CODE
ref.close()
// Delete item logic
}
render() {
return (
<Swipeable
ref={(swipe) => swipeableRef = swipe} // NEW CODE
renderRightActions={() => (
<RightActions onPress={() => this.onRightPress(swipeableRef)} /> // NEW CODE
)}
onSwipeableOpen={this.close}
overshootRight={false}
>
<TouchableWithoutFeedback onPress={this.props.onPress}>
<View style={styles.entryContainer}>
<Text style={styles.entryTitle}>{this.props.item.info}</Text>
<Text style={styles.entryTime}>
eingetragen um {this.props.item.time} Uhr
</Text>
</View>
</TouchableWithoutFeedback>
</Swipeable>
);
}
}

How to implement a way to delete an item from a FlatList?

I am not sure how to add a delete function in a FlatList. I know I can make different components, but I want to know how to do it within this one file. I've trying to figure this out for hours, but do not know how to do.
export default function test() {
const [enteredGoal, setEnteredGoal] = useState("");
const [courseGoals, setCourseGoals] = useState([]);
const goalInput = enteredText => {
setEnteredGoal(enteredText);
};
const addGoal = () => {
setCourseGoals(currentGoals => [
...currentGoals,
{ key: Math.random().toString(), value: enteredGoal }
]);
};
const removeGoal = goalId => {
setCourseGoals(currentGoals => {
return currentGoals.filter((goal) => goal.id !== goalId);
})
}
return (
<View style={styles.container}>
<View>
<TextInput
color="lime"
style={styles.placeholderStyle}
placeholder="Type here"
placeholderTextColor="lime"
onChangeText={goalInput}
value={enteredGoal}
/>
</View>
<FlatList
data={courseGoals}
renderItem={itemData => (
<View style={styles.listItem} >
<Text style={{ color: "lime" }}>{itemData.item.value}</Text>
</View>
)}
/>
<View>
<TouchableOpacity>
<Text style={styles.button} onPress={addGoal}>
Add
</Text>
</TouchableOpacity>
</View>
</View>
);
}
You just need to modify your code a bit to handle the delete button. Since you already have delete functionality, call that function when you click the delete button. That's it.
<FlatList
data={courseGoals}
renderItem={itemData => (
<View style={{ flexDirection: "row", justifyContent: "space-between" }}>
<Text style={{ color: "lime" }}>{itemData.item.value}</Text>
<TouchableOpacity onPress={() => removeGoal(itemData.item.key)}>
<Text>Delete</Text>
</TouchableOpacity>
</View>
)}
/>;
EDIT
change your removeGoal function as below
const removeGoal = goalId => {
setCourseGoals(courseGoals => {
return courseGoals.filter(goal => goal.key !== goalId);
});
};
Hope this helps you. Feel free for doubts.

React Native pass data into modal

I'm still new in react native and programming, and i am trying to pass items from my flat list into a modal. What i'm about to pass is the icon, status, and description. How am i supposed to do that?
this is my flatlist
buildPanel(index, item) {
let panel = [];
let keys = DBkeys['Requests'].MyRequest;
let status = item[keys['status']];
panel.push(<View style={{ position: 'absolute', right: 0, bottom: 0, padding: normalize(5), alignItems: 'center' }} key={'status'}>
<TouchableOpacity onPress={this.handleShowModal}>
<Icon name={img.itemStatus[status].name} type={img.itemStatus[status].type} color={img.itemStatus[status].color} size={normalize(38)} />
</TouchableOpacity>
</View>);
return panel;
}
<View style={[styles.panelContainer, status === 'success' ? {} : { backgroundColor: color.white }]}>
<FlatList
showsVerticalScrollIndicator={false}
progressViewOffset={-10}
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
onMomentumScrollEnd={(event) => event.nativeEvent.contentOffset.y === 0 ? this.onRefresh() : null}
data={content}
renderItem={({ item }) => item}
keyExtractor={(item, key) => key.toString()}
/>
</View>
<IconModal visible={this.state.modalVisible} close={this.handleDismissModal}/>
and this is my IconModal.js
const IconModal = (props) => {
return(
<Modal
isVisible={props.visible}
onBackdropPress={props.close}
>
<View style={styles.dialogBox}>
<View style={styles.icon}>
<Icon name='open-book' type='entypo' color='#ffb732' size={normalize(70)} />
</View>
<View style={styles.text}>
<Text style={styles.status}>Status</Text>
<Text>Desc</Text>
</View>
<TouchableOpacity onPress={props.close}>
<View>
<Text style={styles.buttonText}>GOT IT</Text>
</View>
</TouchableOpacity>
</View>
</Modal>
)
}
IconModal.propTypes ={
visible: PropTypes.bool.isRequired,
close: PropTypes.func,
}
from the renderItem of your FlatList,
You must be clicking somewhere to open modal,
when you click store that whole single item in state variable,
like, if you're using TouchableOpacity then
<TouchableOpacity onPress={this.passDataToModal}/>
...
...
passDataToModal=(item)=>{
this.setState({modalData:item},()=>{
//you can open modal here
});
}
and in your modal component,
you can pass data with prop.
<IconModal modalData={this.state.modalData} visible={this.state.modalVisible} close={this.handleDismissModal}/>
and you can use these data in IconModal as this.props.modalData.
If there is more data then you can always add another prop.
Define the following Hooks in your function Component.
const [modalVisible, setModalVisible] = useState(false);
const [modalData, setModalData] = useState([]);
const [modalTitle, setModalTitle] = useState('');
Now Trigger the function which opens the Modal, while simultaneously passing data into it.
<TouchableHighlight underlayColor="skyblue" onPress={() => { openSettingsModal(title,settings) } }>
Open Modal
</TouchableHighlight>
Here is the function code -
const openSettingsModal = (title,settings) => {
setModalTitle(title);
setModalData(settings);
setModalVisible(!modalVisible);
}
And finally a snippet of the Modal Code.
<Modal animationType="none" transparent={true} visible={modalVisible} >
<View style={styles.centeredView}>
<Text> { modalTitle }</Text>
<Text> { modalData }</Text>
</View>
</Modal>
For example:
class Container extends Component {
constructor(props) {
super(props)
this.state = {
modalVisible: false,
activeItemName: '', //state property to hold item name
activeItemId: null, //state property to hold item id
}
}
openModalWithItem(item) {
this.setState({
modalVisible: true,
activeItemName: item.name,
activeItemId: item.id
})
}
render() {
let buttonList = this.props.item.map(item => {
return (
<TouchableOpacity onPress={() => { this.openModalWithItem(item) }}>
<Text>{item.name}</Text>
</TouchableOpacity>
)
});
return (
<View>
{/* Example Modal Component */}
<Modal isOpen={this.state.openDeleteModal}
itemId={this.state.activeItemId}
itemName={this.state.activeItemName} />
{buttonList}
</View>
)
}
}

setState fires and render method gets hit, but nothing rerenders

I have this screen under a DrawerNavigator:
class myScreen extends Component {
state: Object;
constructor(props) {
super(props);
this.getBeers();
this.state = {
is_loading: true,
beers: null,
beers_ds: null,
}
}
componentWillUpdate(nextProps: Object, nextState: Object)
{
if(!nextState.is_loading)
{
let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
nextState.beers_ds = ds.cloneWithRows(nextState.beers);
}
}
async getBeers()
{
let finalApiURL = API_BASE_URL;
let fetchResult = await fetch(finalApiURL)
let Result = await fetchResult.json();
this.setState({users: Result, is_loading: false});
}
render()
{
if(this.state.is_loading)
{
return(
<View style={{ flex: 1, backgroundColor: 'white', marginTop: 50 }}>
<Text>
Loading ...
</Text>
</View>
)
}
else
{
let renderRow = (row) => {
return (
<TouchableOpacity onPress={ () => {} }>
<View >
<Text>{row.name}</Text>
<Text style={{ color: 'blue' }}>ADD</Text>
</View>
</TouchableOpacity>
);
}
return
(
<View >
<ListView dataSource={this.state.beers_ds} renderRow={renderRow.bind(this)} />
</View>
);
}
}
}
export default myScreen;
Now when I get results back from the server, I setState(). Then, componentWillUpdate() gets called, and the else() statement in render() fires.
But my screen does not change and it stays on Loading ...
And sometimes I get see this error:
Can anyone help in finding why this weird behavior is occurring?
Thanks
EDIT:
It works when I change this:
return
(
To this:
return (
Welcome to Javascript!
I will assume that you have the latest react native so ListView is deprecated you can use FlatList (Dod) instead
change your code to be like this
renderRow = (row) => {
return (
<TouchableOpacity onPress={ () => {} }>
<View >
<Text>{row.name}</Text>
<Text style={{ color: 'blue' }}>ADD</Text>
</View>
</TouchableOpacity>
);
}
render() {
return(
<View style={{ flex: 1, backgroundColor: 'white', marginTop: 50 }}>
{this.state.is_loading ?
<Text>
Loading ...
</Text>
:
<FlatList data={this.state.users} renderItem={(item) => this.renderRow(item)} />
}
</View>
);
}

Categories