Conditioning a button on React Native - javascript

I have a button that should be able to do an operation only if a previous validation is true, but to be honest I don't know how to do it; what I did is really messy so I belive there should be a correct way of doing this.
So this is what I've tried. I'm using hooks:
<View style={styles.buttonContainer2}>
<TouchableOpacity
style={ styles.logout}
onPress={
if( vValidCellphone == true{
() => onSubmit({
vSecondLastName, vCellphone, vBirthDate, vRFC, vGender, vEmail,vCreationUser
})
})}>
<Text style={styles.loginText}>GUARDAR</Text>
</TouchableOpacity>

You can use touchable opacity props called disabled. Set it true to disable the onclick action as below :
<TouchableOpacity
style={ styles.logout}
disabled={!vValidCellphone}
onPress={() => onSubmit({
vSecondLastName, vCellphone, vBirthDate, vRFC, vGender, vEmail,vCreationUser
})}>
<Text style={styles.loginText}>GUARDAR</Text
</TouchableOpacity>
In addition you can style your button according to disable condition to style button like disabled.

Related

React native - Change styles dynamically

I have a dynamic menu that I created using a map method.
{navigationOptions.map(option => {
return (
<TouchableOpacity key={option.code}
onPress={() => this.procedureOptionSelected(option.code)}
>
<Text bold style={header.NavigationBarOption}>
{option.type}
</Text>
</TouchableOpacity>
);
})}
However, I need an underline when I press a menu option.
So let's assume, that I pressed the first option. So, in the first option, there must be an underscore.
But I don't know how to do this in react native.
Could someone help me with an idea?
Thanks!
You can add a style prop to TouchableOpacity and check if this is the selected button like this:
<TouchableOpacity
style={{ borderBottomWidth: this.state.selected === option.code ? 1 : 0 }}
onPress={() => this.setState({ selected: option.code })
>
...
</TouchableOpacity>
Also I guess you can use this.procedureOptionSelected() since you set that option.code in there too!

Can a single button do different things?

I have two buttons to do two actions, is it possible to have only one button that should change the text and the actions that it does?
<TouchableOpacity style={styles.button} onPress={() => this.stopFunction()}>
<Text style={styles.buttonTesto}>STOP</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={() => this.startFunction()}>
<Text style={styles.buttonTesto}>START</Text>
</TouchableOpacity>
So the first time is Start, when the user clicks, the button launch the startFunction and change the text in Stop.
I suppose you have a state variable running
this.state = { running : true }
Now Inside your render method get the state data :
const { running } = this.state
your button should look like this :
<TouchableOpacity style={styles.button} onPress={() => this.uniqueFunction()}>
<Text style={styles.buttonTesto}>
{ running ? 'STOP' : 'START'}
</Text>
</TouchableOpacity>
Now your unique function have to do the two actions depends on application running status:
uniqueFunction = () => {
const { running } = this.state
if( running ) {
// The action you want to do when start button is pressed
}else
// The action you want to do when stop button is pressed
}
You need a state variable, and then you can use conditional rendering based on value of the variable. Like this:
<TouchableOpacity style={styles.button}
onPress={() => {this.state.flag ? this.stopFunction() : this.startFunction()}}
>
<Text style={styles.buttonTesto}>{this.state.flag? "STOP" : "START"}</Text>
</TouchableOpacity>

React Native FlatList keyboardShouldPersistTaps not persisting

I have a very frustrating situation. Trying to get keyboard to disappear and detect onPress event handler in child row.
Here is what my code looks like:
_renderRow = (prediction) => {
return (
<TouchableOpacity onPress={() => {
Keyboard.dismiss();
this.setState({ location: prediction.description });
}}>
<View style={styles.listItemContainer}>
<Text>{prediction.description}</Text>
</View>
</TouchableOpacity>
)
}
render() {
return (
<View style={styles.wrapper}>
{/* style={[this.state.predictions.length > 0 ? styles.searchContainerSuggest : styles.searchContainer]} */}
<View style={styles.searchContainerSuggest}>
<View style={{paddingLeft: 10, height: 45, display: 'flex', justifyContent: 'center'}}>
<TextInput
placeholder="Enter location"
value={this.state.location}
onChangeText={location => this.onChangeLocation(location)}
style={styles.textInput}
/>
</View>
{this.state.predictions.length && this.state.location !== '' ?
<FlatList
keyboardShouldPersistTaps={'handled'}
refreshing={!this.state.loaded}
initialNumToRender={10}
enableEmptySections={true}
data={this.state.predictions}
keyExtractor={(_, index) => index.toString()}
renderItem={ ({item: prediction}) => this._renderRow(prediction) } />
: null}
</View>
</View>
);
}
I probably need a helping hand or two with regards to how to debug this issue.
Looked up several examples on how to deal with hiding the keyboard and allowing a particular selection to be pressed at the same time.
I thought that keyboardShouldPersistTaps would allow for the child selection to be selected. Upon selection, the onPress event handler will trigger and that will be where I call Keyboard.dismiss() to hide the keyboard. Does not seem to work.
In my case, besides adding keyboardShouldPersistTabs='handled' to the FlatList in question, it was also needed to add keyboardShouldPersistTabs='handled' and nestedScrollEnabled={true} to a parent ScrollView like 2 levels above, wrapping the FlatList I intended to get this behavior with. Check out this issue in react-native repo for more info.
For anyone who is running into the same problem as me. Check whether your FlatList or ScrollView is nested in another FlatList or ScrollView.
If yes, then add
keyboardShouldPersistTaps='handled'
to the element as a props as well.
add keyboardDismissMode="none" to FlatList

onTouch event not working

I am relatively new to React-Native.
I was trying to implement onTouch event but for some reason this doesn't seem to be working.
for example in this code
<View style={[container1,this.state.increased ? {backgroundColor: "#B4EEB4"} : null,this.state.decreased ? {backgroundColor: "#ffe5e5"} : null]} onPress={() => this.touched(this.props.key)}>
<View style={upperRow}>
<Text style={sno}> {this.props.no} </Text>
<Image
source={{uri: "https://coincap.io/images/coins/" + this.props.coinName + ".png"}}
style={img}
/>
<Text style={coinSymbol}>{this.props.coinShortName}</Text>
<Text style={coinPrice}>${this.props.coinPrice}</Text>
<View style={percentageBox}>
<Text style={this.props.percentChange < 0 ? percentChangeMinus : percentChangePlus }>{this.props.percentChange}%</Text>
</View>
</View>
<Display enable={stateToDisplay}>
<View style={statisticsContainer}>
<Text style={marketCap}>Cap: {this.props.marketCap}B </Text>
<Text style={seperator1}>|</Text>
<Text style={vwapData}>24vwap: {this.props.vwapData} </Text>
</View>
</Display>
</View>
Here
View style={[container1,this.state.increased ? {backgroundColor: "#B4EEB4"} : null,this.state.decreased ? {backgroundColor: "#ffe5e5"} : null]} onPress={() => this.touched(this.props.key)}>
I am passing this onPress event
onPress={() => this.touched(this.props.key)
which I expect should have called/run the function touched here
lass CoinCard extends Component {
state = {
increased: false,
decreased: false,
selectedPostId: "none"
}
componentWillReceiveProps(nextProps) {
if (this.props.coinPrice != nextProps.coinPrice ) {
if (this.props.coinPrice > nextProps.coinPrice) {
this.setState({decreased: true, increased: false})
}
if (this.props.coinPrice < nextProps.coinPrice) {
this.setState({increased: true, decreased: false})
}
}
}
touched = (id) => {
this.setState({selectedPostId: id})
console.log("inside touched")
}
[Question] But clicking on the container is doing nothing at the moment. Can anyone tell me what I am doing wrong here?
View component does not provide an onPress prop. You can either use TouchableHighlight or TouchableOpacity.
So while in React Native View does not have an onPress prop, it does have an onTouchStart, onTouchEnd events. This however will be called even if you touch the children inside the view, so its not a good way if you want the touch to be exclusively to the container outside the content in the view.
So you can either have onTouchStart and handle your onPress logic there, or wrap your entire view in a TouchableOpacity, TouchableHighlight or TouchableWithoutFeedback and handle the onPress on that.
More on React Native Touchables

React-native: Pass event to other object

This is my first experience with JS/React/React Native. I don't yet fully grasp mechanics of this framework, so be kind to me.
What I have :
<View style={styles.container}>
<View style={styles.timerContainer}>
<View style={styles.timerBar}>
<Image style={styles.icon} source={require('../../img/time50.png')}/>
{Timer} //First
</View>
<View style={styles.timerBar}>
<Image style={styles.icon} source={require('../../img/break50.png')}/>
{Timer} //Second
</View>
</View>
<View style={styles.buttonContainer}>
<TouchableHighlight onPress={this.startWork}>
<Image style={styles.imageButton} source={require('../../img/start.png')}/>
</TouchableHighlight>
<TouchableHighlight onPress={this.startBreak}>
<Image style={styles.imageButton} source={require('../../img/break.png')}/>
</TouchableHighlight>
<TouchableHighlight onPress={this.stopWork}>
<Image style={styles.imageButton} source={require('../../img/end.png')}/>
</TouchableHighlight>
</View>
</View>
Timer is a custom class, which will have 'start', 'pause' and 'end' methods. I want to call methods of both Timers when TouchableHighlight is pressed.
Overall it would look like this :
when first TouchableHighlight is pressed (startWork), Timer2.end and Timer1.start should be called, when second is pressed (startBreak), Timer1.pause, Timer2.start should be called, for third (stopWork) it would be Timer1.end, Timer2.end.
But how am I supposed to refer to these timers from onPress methods? Should I keep both Timers in some vars of parent class? I am totally stuck and have no idea where to start (and what's acceptable). Such problem is not easily googlable (or I don't know where to look). I would appreciate any help (solution, pointing to tutorial...).
When you render the timer components in this component you should assign a ref to each one of them, like
<Timer ref={r => this.timer1 = r}/>
Then in the Touchable callback functions you can call this.timer1.start()
Note: Cleaner ref setting would be to actually have another function, so you aren't constantly binding in the render function:
setTimerOne = (r) => {
this.timer1 = r;
}
render() {
<Timer ref={this.setTimerOne}/>
}

Categories

Resources