How to disable TouchableOpacity when pressed? React-Native - react-native

How can I disable TouchableOpacity when I click on it?
This is my code:
<TouchableOpacity onPress={() => this._pickupHandler(item.p, deliv.party, index)}>
<View style={styles.carg}>
<Text style={styles.delivered_text}>Ok{deliv.loca} {deliv.addres} {deliv.pos} </Text>
</View>
</TouchableOpacity>

just pass disabled prop to TouchableOpacity for your example
export default class Touchable extends Component {
constructor(props) {
super(props);
this.state = {
disabled: false,
};
}
onPressButton = (state) => {
this.setState({
disabled: state,
});
};
render() {
return (
<TouchableOpacity disabled={this.state.disabled} onPress={() => {
this.onPressButton(true);
this._pickupHandler(item.p, deliv.party, index)
}}>
<View style={styles.carg}>
<Text style={styles.delivered_text}>Ok{deliv.loca} {deliv.addres} {deliv.pos} </Text>
</View>
</TouchableOpacity>
);
}
}

Okay so you need another state which will refer to if you want to disable it.
lets make a state var TODISABLED and set it to false initially .
Now suppose you want to disable it after 1 click , you can do this by setting state to true after click :
<TouchableOpacity disabled={this.state.TODISABLED} onPress={() => {this._pickupHandler(item.p, deliv.party, index);this.setState({TODISABLED:true})}}>
<View style={styles.carg}>
<Text style={styles.delivered_text}>Ok{deliv.loca} {deliv.addres} {deliv.pos} </Text>
</View>
</TouchableOpacity>
Hope it helps. feel free for doubts

Related

Call function on another file JS React Native

I have a Parent Class and Child Class but however i can't call a function on Parent Class from Child Class
It just for close the Modal and send a few data from Sorting on my modal. Sorry im a newbie on RN
On OrderScreen i want to separate a modal and screen, so i call modal on another file JS, then on ModalSort.js i want to call back that function has been on his Parents or Order.screen.js
so many way i try but that modal still can't close, if i put onBackdropPress={() => ()} the modal can be close but no respon that i got
Order.screen.js (a.k.a Parents.js)
class OrderScreen extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
};
};
exit = () => this.setState({ visibleModal: false });
_applySort = () => {
this.setState({ visibleModal: false });
this.onRefresh();
};
pressSort = () => this.setState({ visibleModal: 4 });
render() {
return (
<View style={styles.containerTop}>
<Modal isVisible={this.state.visibleModal === 5} style={styles.bottomModal}>
{this._renderModal()}
</Modal>
<Modal isVisible={this.state.visibleModal === 4}
style={styles.bottomModal} onBackdropPress={() => {this.toggleModal();}}>
{this._renderModalSort()}
</Modal>
<Modal isVisible={this.state.visibleModal === 3} style={styles.bottomModal}>
{this._renderModalFilter()}
</Modal>
<Modal isVisible={this.state.visibleModal === 2} style={styles.bottomModal}>
{this._renderModalEmail()}
</Modal>
<NavigationEvents
onWillFocus={this.willFocusAction} />
<GeneralStatusBarColor backgroundColor="#FFF" barStyle="light-content" />
</View>
)
};
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit.bind(this);
}}
/>
)
};
const mapStateToProps = ({ authOrder }) => {
const { orderSummary, error, loading, loadingSummary, loadingEmail, typeOfLocation, openNext, openList, closedList, closedNext } = authOrder;
return { orderSummary, error, loading, loadingSummary, loadingEmail, typeOfLocation, openNext, openList, closedList, closedNext };
};
export default connect(mapStateToProps, { getOrderSummary, getOpenOrderList, getClosedOrderList, sendEmailCsvAllOrder, logoutSession })(OrderScreen);
ModalSort.js (a.k.a Child.js)
class ModalSort extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
}
};
sorter = (isi) => this.setState({ sorted: isi });
_applySort = () => {
this.setState({ visibleModal: false });
// this.onRefresh();
};
render() {
return(
<View style={styles.modalContentSort}>
<View style={styles.modalCenter}>
<View style={styles.headerModel}>
<View style={styles.headerBack}>
<TouchableOpacity onPress={()=>{this.props.exit()}}>
{/* <NavigationEvents onWillFocus={this.willFocusAction} /> */}
<Image style={styles.logoClose} source={require('../../assets/icons/iconClose.png')} />
</TouchableOpacity>
</View>
<View style={styles.headerSort}>
<Text style={styles.textFilter}>Sort by</Text>
</View>
</View>
<Text style={styles.textFilter}>SO Number</Text>
<View style={styles.headerModel}>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(1)}>
<Text style={this.state.sorted == 1 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberAscending.png')} />Ascending</Text>
</TouchableOpacity>
</View>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(2)}>
<Text style={this.state.sorted == 2 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberDescending.png')} />Descending</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.textFilter}>PO Customer</Text>
<View style={styles.headerModel}>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(3)}>
<Text style={this.state.sorted == 3 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberAscending.png')} />Ascending</Text>
</TouchableOpacity>
</View>
<View style={styles.headerFilterItem}>
<TouchableOpacity onPress={() => this.sorter(4)}>
<Text style={this.state.sorted == 4 ? styles.headerBorderItemActive : styles.headerBorderItem}>
<Image style={styles.imageSort} source={require('../../assets/icons/iconNumberDescending.png')} />Descending</Text>
</TouchableOpacity>
</View>
</View>
<Text style={styles.textFilter}>SO Date</Text>
<View style={styles.headerModel}>
<TouchableOpacity onPress={() => this.sorter(6)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 6 ? styles.headerBorderItemActive : styles.headerBorderItem}>Newest</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.sorter(5)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 5 ? styles.headerBorderItemActive : styles.headerBorderItem}>Oldest</Text>
</View>
</TouchableOpacity>
</View>
<Text style={styles.textFilter}>ETA</Text>
<View style={styles.headerModel}>
<TouchableOpacity onPress={() => this.sorter(8)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 8 ? styles.headerBorderItemActive : styles.headerBorderItem}>Newest</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.sorter(7)}>
<View style={styles.headerFilterItem}>
<Text style={this.state.sorted == 7 ? styles.headerBorderItemActive : styles.headerBorderItem}>Oldest</Text>
</View>
</TouchableOpacity>
</View>
<TouchableHighlight style={styles.buttonSort} onPress={this._applySort.bind(this)} >
<Text style={styles.textApply}>Apply</Text>
</TouchableHighlight>
</View>
</View>
)
};
}
export default ModalSort;
Close modal in Parent component from Child component:
Your Order.screen.js has a mistake that make your program wouldn't run properly. When you use this.exit.bind(this);, it will return a callback, not a function. So, when you call this.props.exit() in ModalSort.js, it will call exit that actually shows nothing. To resolve this, you have 2 ways:
Order.screen.js
_renderModalSort = () => {
return (
<ModalSort
exit={this.exit.bind(this)}
/>
)
};
or
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit();
}}
/>
)
};
Send data from sorting modal:
Since you're using Redux, I suggest you create 2 actions. First action is to save your data to your state tree. Second one is to get those data. If you're not good at Redux, or you don't want to use it, you can try these step:
Initialize a variable to hold your data in Parent:
class OrderScreen extends Component {
constructor(props) {
super(props);
this.state = {
visibleModal: null,
};
this.data = null; // Your data goes here.
/*
You can store your data in state if you want to re-render when updating your data.
this.state = {
visibleModal: null,
data: null
}
*/
}
}
Create a function that save your data in Parent:
saveData(data) {
this.data = data;
}
Pass that function to Child:
_renderModalSort = () => {
return (
<ModalSort
exit={() => {
this.exit();
}}
saveData={(data) => {
this.saveData(data);
}}
/>
)
};
Lastly, you can call it from Child:
class ModalSort extends Component {
sorting() {
data = null; // Your data will be stored in this variable
// You sorting function goes here
this.props.saveData(data); // Save your data
}
}
In case you have other works to do with saved data, you can modify the saveData(data) function in Parent.
Hope this will help you!

Change TextInput editable attribute when I press a button (Not working)

I am trying to change editable with state with the click of a button, but it is not working for some reason. I have seen other people do it this way and it works. Is there another way to do this instead? or am i missing something? Thanks
`class Settings extends Component {
constructor(props) {
super(props);
this.state = {
editable: false,
name: '',
};
this.handleEdit = this.handleEdit.bind(this);
this.handleName = this.handleName.bind(this);
}
handleEdit() {
this.setState({
editable: !this.state.editable,
});
}
handleName = (text) => {
this.setState({
name: text,
});
};
render() {
return(
<View style={styles.container}>
<View style={styles.headerContainer}>
<Text style={styles.header}>Settings</Text>
</View>
<View style={styles.section}>
<View style={styles.sectionTitleContainer}>
<Text style={styles.sectionTitle}>My Account</Text>
</View>
<View>
<Text>Name:</Text>
<TextInput
placeholder="name"
value={this.state.name}
onChangeText={this.handleName}
editable={this.state.editable}
/>
</View>
<View>
<TouchableOpacity onPress={() => this.handleEdit}>
<Text>Edit</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
export default Settings;`
Change your
<TouchableOpacity onPress={() => this.handleEdit}>
To
<TouchableOpacity onPress={this.handleEdit}>
I believe that since you already binded 'this' to the handleEdit function you dont need to pass the () => anymore.

react-native-router-flux. How to change custom navBar programmatically?

I have a custom navBar in my scene:
<Scene key="myPage"
component={MyPage}
navBar={NavBarCustom}
hideNavBar={false}/>
....
class NavBarCustom extends Component {
constructor(props) {
super(props);
}
onExitPressed(){
App.exit();
}
render() {
return (
<View style={styles.navBar}>
<View style={styles.leftContainer}>
<Image
style={styles.logo}
source={require('./../../res/ic_nav_bar.png')}/>
<Text style={[appStyles.customFontBold, styles.title1]}>
MY TITLE
</Text>
</View>
<View style={styles.centralContainer}>
<Text style={[appStyles.customFontRegular, styles.title2]}>
{strings.benefit_identifier}
</Text>
</View>
<View style={styles.rightButtonContainer}>
<TouchableHighlight
style={{padding: 7}}
underlayColor='#b59d6e'
onPress={() => { this.onExitPressed() }}>
<Text style={[appStyles.customFontRegular, styles.rightButtonTitle]}>
{strings.exit}
</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
It works good. So how can I change title1 of NavBarCustom from my scene MyPage?
Thanks in advance.
You can pass/send information through/with props:
In your render you can declare a const which take the react-native-router-flux Actions, set the route which to point and then set the object which to pass:
If there's a Login main file, which then redirects to a Register view then you declare the const goToRegister and then pass the text with its content:
class Login extends Component {
render() {
const goToRegister = () => Actions.Register({text: 'From Login'});
return(
<View style={{flex:1}}>
<Text>
Login
</Text>
<TouchableHighlight onPress={goToRegister} style={{ marginTop: 100}}>
<Text>Go Register</Text>
</TouchableHighlight>
</View>
)
}
}
Then within your Register you receive it just within your props as this.props.text:
class Register extends Component {
render() {
return(
<View style={{flex:1}}>
<TouchableHighlight onPress={Actions.Login} style={{ marginTop: 100}}>
<Text>{ this.props.text }</Text>
</TouchableHighlight>
</View>
)
}
}
In your case you should send firstly the value of your title maybe as:
render() {
const goToMyPage = () => Actions.MyPage({ title: 'Some Title'})
...
And then you're able to use it:
<Text style={[appStyles.customFontBold, styles.title1]}>
{ this.props.title }
</Text>
Scene takes a title param
<Scene
key="myPage"
component={MyPage}
navBar={NavBarCustom}
hideNavBar={false}
title="myPage"
/>

React Native onpress not working

onRadioPressed does not seem to be called - what am I doing wrong? I also need to get the text contained in the 'clicked' item.
I believe I can get that with event.nativeEvent.text, correct?
Thanks for any help.
class RadioBtn extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
onRadioPressed(event) {
console.log('RADIOBUTTON PUSHED:');
}
render() {
return (
<View style={styles.radioGrp}>
<View style={styles.radioContainer}>
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
</View>
<View style={styles.radioContainer}>
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Right</Text>
</TouchableHighlight>
</View>
</View>
);
}
}
So here:
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
First change onpress to onPress. Here () => this.onRadioPressed.bind(this) you are specifying an arrow function that returns another function this.onRadioPressed.bind(this) but you never trigger it.
Correct ways:
// You can do either this
<TouchableHighlight onPress={() => this.onRadioPressed()} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
// Or you can do either this
<TouchableHighlight onPress={this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
I would recommend checking this article out https://medium.com/#housecor/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56#.irpdw9lh0
You can not bind the function inside onpress link this :
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
use it like this :
<TouchableHighlight onpress={() => this.onRadioPressed()} underlayColor='#f1c40f'>
if you want to bind the function then try this:
<TouchableHighlight onpress={this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
Cheers:)
Use below line
<TouchableHighlight onPress={this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
or using arrow function
<TouchableHighlight onPress={() => this.onRadioPressed()} underlayColor='#f1c40f'>
if https://stackoverflow.com/a/41651845/9264008 doesn't works check the way you have imported TouchableOpacity
✅ correct import import { TouchableOpacity } from 'react-native'
sometimes mistakenly weird import happens example below
❌ Import import { TouchableOpacity } from 'react-native-gesture-handler'
I'm using react-native 0.66 version and it's working fine.
import React, { useState } from 'react';
import { StyleSheet,Text,View } from "react-native";
const App = () => {
const [ prevCount, setCount ] = useState(1)
const onPress = () => setCount(prevCount => prevCount + 1);
return (
<View style={styles.container}>
<Text style={styles.prevCount}> {prevCount} </Text>
<Text style={styles.pressHere} onPress={onPress} > Press Here </Text>
</View>
)
};
const styles = StyleSheet.create({
container: {
marginTop: 50
},
pressHere:{
fontSize: 30
},
prevCount: {
fontSize: 20,
color: 'red'
}
})
export default App;
also, you can use this doc.

Modal View in React Native

I am new to react native, I am trying to present a view modally. I have a table view and when one of the rows is clicked I want the view to show up modally.
This is how I am implementing the transition right now :
renderbooks(books) {
return (
<TouchableHighlight onPress={() => this.showbooksDetail(books)} underlayColor='#dddddd'>
<View>
<View style={styles.container}>
<View style={styles.rightContainer}>
<Text style={styles.title}>{books.title}</Text>
</View>
</View>
<View style={styles.separator} />
</View>
</TouchableHighlight>
);
}
showbooksDetail(books){
this.props.navigator.push({
title:books.title,
component: ProductView,
passProps:{books}
});
}
How can I modify this so that the view can be presented modally?
FYI: I have already looked at multiple questions and sample projects such as these:
How do I create a native looking modal view segue with react-native?
http://facebook.github.io/react-native/docs/modal.html#content
https://github.com/aaronksaunders/React-Modal-Nav-Example
Check out the built-in Modal. It's implemented on iOS, Android implementation should come in one of the next releases of React Native.
The documentation contains an example on how to use it.
In your case it would be something like:
renderBooks(books) {
...
<Modal
animated={true}
transparent={true}
visible={!!this.state.selectedBook}>
<Text>{this.state.selectedBook.title}</Text>
</Modal>
...
}
showDetail(book) {
this.setState({
selectedBook: book,
});
}
Check this simple and powerful small library react-native-modal-animated, simply install it by yarn add react-native-modal-animated, or npm install react-native-modal-animated.
import { AnimatedModal } from 'react-native-modal-animated
<View style={styles.container}>
<TouchableOpacity
onPress={() => {
this.setState({ modalVisible: true });
alert
}}
style={styles.button}
>
<Text style={styles.buttonText}>Show Modal</Text>
</TouchableOpacity>
<AnimatedModal
visible={this.state.modalVisible}
onBackdropPress={() => {
this.setState({ modalVisible: false });
}}
animationType="vertical"
duration={600}
>
{/*Any child can be used here */}
<View style={styles.modalCard}>
<Text>I'm AnimatedModal</Text>
<Text style={{fontWeight: 'bold', marginTop: 10}}>vertical</Text>
</View>
</AnimatedModal>
</View>
);
}
}
I am using the react-native modalbox. Its been awesome you get modals to be displayed in top,center,bottom,etc.Check the below link once:https://github.com/maxs15/react-native-modalbox
Sample:
import React from 'react';
import Modal from 'react-native-modalbox';
import Button from 'react-native-button';
import {
AppRegistry,
Text,
StyleSheet,
ScrollView,
View,
Dimensions
} from 'react-native';
class Example extends React.Component {
constructor() {
super();
this.state = {
isOpen: false,
isDisabled: false,
swipeToClose: true,
sliderValue: 0.3
};
}
onClose() {
console.log('Modal just closed');
}
onOpen() {
console.log('Modal just openned');
}
onClosingState(state) {
console.log('the open/close of the swipeToClose just changed');
}
render() {
return (
<View style={styles.wrapper}>
<Button onPress={() => this.refs.modal1.open()} style={styles.btn}>Basic modal</Button>
<Button onPress={() => this.refs.modal2.open()} style={styles.btn}>Position top</Button>
<Button onPress={() => this.refs.modal3.open()} style={styles.btn}>Position centered + backdrop + disable</Button>
<Button onPress={() => this.refs.modal4.open()} style={styles.btn}>Position bottom + backdrop + slider</Button>
<Modal
style={[styles.modal, styles.modal1]}
ref={"modal1"}
swipeToClose={this.state.swipeToClose}
onClosed={this.onClose}
onOpened={this.onOpen}
onClosingState={this.onClosingState}>
<Text style={styles.text}>Basic modal</Text>
<Button onPress={() => this.setState({swipeToClose: !this.state.swipeToClose})} style={styles.btn}>Disable swipeToClose({this.state.swipeToClose ? "true" : "false"})</Button>
</Modal>
<Modal style={[styles.modal, styles.modal2]} backdrop={false} position={"top"} ref={"modal2"}>
<Text style={[styles.text, {color: "white"}]}>Modal on top</Text>
</Modal>
<Modal style={[styles.modal, styles.modal3]} position={"center"} ref={"modal3"} isDisabled={this.state.isDisabled}>
<Text style={styles.text}>Modal centered</Text>
<Button onPress={() => this.setState({isDisabled: !this.state.isDisabled})} style={styles.btn}>Disable ({this.state.isDisabled ? "true" : "false"})</Button>
</Modal>
<Modal style={[styles.modal, styles.modal4]} position={"bottom"} ref={"modal4"}>
<Text style={styles.text}>Modal on bottom with backdrop</Text>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
modal: {
justifyContent: 'center',
alignItems: 'center'
},
modal2: {
height: 230,
backgroundColor: "#3B5998"
},
modal3: {
height: 300,
width: 300
},
modal4: {
height: 300
},
wrapper: {
paddingTop: 50,
flex: 1
},
});
AppRegistry.registerComponent('Example', () => Example);