React native - Change styles dynamically - javascript

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!

Related

Styling array mapped objects in React Native

return arr.map((entry, index) =>
<View style={ this.state.interests.includes(entry) ? styles.optionSelected : styles.option}>
<TouchableOpacity onPress={() => this.addToInt(entry)}>
<Text style={{ color: "#22305D", paddingVertical: 15, paddingHorizontal: 25, fontSize: 18 }} key={entry}>{`${entry}`}</Text>
</TouchableOpacity>
</View>
)
I currently have this code to traverse my array and display all the values, but I want a way to change the styling of an individual object when pressed. The way I have it now, onPress adds that unique value to the array interests (100% sure this works), but the conditional styling isn't working. Is there a different way of handling this? I am trying to avoid setting a state for option1, option2, etc.. Thanks!

Conditioning a button on React Native

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.

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

How to render Container Classes conditionally

firstly, this is what is given to me from designer http://www.giphy.com/gifs/hSRrqF5ObsbXH27V09
Basically, there is a category which is passed from previous screen. and with some ui interactions, i need to render this screen again and again. the flow is like that: you select a category, if it has subCategories, let user select one of those subCategories before rendering input components. i can make it work with if and else clauses but i feel that this is some how not best practice at all. I just need an advice from experieced developer(i am reletively new to react native.)
So before writing any code with native way, i just want to ask it here so maybe i can learn more about it.
Here is my Screen:
<NewAdHoc
contentText={'Kategori Secimi'}
onBackPress={this.handleBackPress}
showContentText={false}
>
<View style={styles.container}>
{currentCategory !== null
? (
<View style={{ ...styles.flatListContainer, paddingLeft: undefined, paddingRight: undefined }}>
<View style={{ marginHorizontal: 20 }}>
<ListViewItem
categoryName={currentCategory.categoryName}
iconName={currentCategory.categoryIcon}
showBorder={false}
key={currentCategory.categoryId}
categoryId={currentCategory.categoryId}
inNewAdScreen={false}
/>
</View>
<Seperator
backgroundColor={colors.SEPERATOR_BCK}
text={'Ilan Turu'}
style={{ paddingHorizontal: 20 }}
/>
{
currentCategory.subCategories.map((subc) => (
<View style={{ marginHorizontal: 20 }}>
<SubCategoryItem
text={subc.subCategoryName}
key={subc.subCategoryId}
showBorder={true}
/>
</View>
))
}
</View>
) : null}
</View>
</NewAdHoc>
right now, i am rendering a category, a <Seperator/> between category and subcategories, and subcategories. what i want is that, when user click on one of the subCategories, i will change the state to isSubCategorySelected = true, selectedSubCategory= subCategoryId and then need to render the whole screen like in gif i provided above.
the For those who came here for answer:
What i did is basically divide and conquer paradigm. I firstly divide my sitution into two main state.
RenderInitialForm(),
renderAfterSubCategorySelected(),
those two rendering functions handle the whole process. when a TouchableOpacity is clicked, i setState with two variables: isSubCategorySelected = true, selectedSubCategory = subCategory
and in my main render() function:
render() {
const { currentCategory, isSubCategorySelected, selectedSubCategory } = this.state
return (
<NewAdHoc
contentText={'Kategori Secimi'}
onBackPress={this.handleBackPress}
showContentText={false}
>
<View style={styles.container}>
{currentCategory !== null
? isSubCategorySelected
? this.renderAfterSubCategorySelected()
: this.renderInitialForm()
: null}
</View>
</NewAdHoc>
);
}
if you have any suggestion with my solution, please feel free to contact me.

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

Categories

Resources