changing the styling of one text element from inside another text element - reactjs

so basically, am trying to achieve something like so, such that when +100 is pressed, the color of say, Upload ID Card changes to really show that that field is completed.
<View
style={{ justifyContent: "flex-start", marginTop: 25 }}
>
<Text
style={ styles.scoreTitle }
>
{item.key}
</Text>
</View>
<View style={styles.perScoreRightContentView}>
<Text
style={styles.scorePlus100}
onPress={() => // change style of the the text child above}
>
+ 100
</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</View>
</View>
So, this is what I have tried out but with no success;
...
const [isSelected, setIsSelected] = React.useState(false);
...
<Text
style={[
isSelected
? { ...styles.scoreTitle, color: "#C6C6C6" }
: styles.scoreTitle
]}
>
{item.key}
</Text>
</View>
<TouchableOpacity
style={styles.perScoreRightContentView}
onPress={() => setIsSelected(!isSelected)}
>
<Text style={styles.scorePlus100}>+ 100</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</TouchableOpacity>
...
const styles = StyleSheet.create({
scoreTitle: {
color: style.color.blackText,
fontSize: 13,
fontFamily: style.fontFamily.medium
}
});

Now I understand, you can put a ref on the text element and access to syle of that text element from the press function.
some thing like that :
<View style={{ justifyContent: "flex-start", marginTop: 25 }}>
<Text style={ styles.scoreTitle } ref='colorText'>
{item.key}
</Text>
</View>
<View style={styles.perScoreRightContentView}>
<Text style={styles.scorePlus100} onPress={() => changeStyle()}>
+ 100
</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</View>
const changeStyle = () => {
const myReference = this.colorText.current // The DOM element
myReference.style.color = "yellow";
}
don't forget to useRef to declar the ref.

I actually found a solution, thanks rovas
So basically what had to be done was to split components such that they manage different state, that is to say,
const Score = ({ title }: { title: string }) => {
const [scoreSelected, setScoreSelected] = React.useState(false);
return (
<View style={styles.perSectionScore}>
<View style={{ justifyContent: "flex-start", marginTop: 25 }}>
<Text
style={[
scoreSelected
? { ...styles.scoreTitle, color: "#C6C6C6" }
: styles.scoreTitle
]}
>
{title}
</Text>
</View>
<View
style={styles.perScoreRightContentView}
>
<Text
style={styles.scorePlus100}
onPress={() => {
setScoreSelected(!scoreSelected);
}}
>
+ 100
</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</View>
</View>
);
};
and then use in a to-be rendered component, i.e
<View style={styles.scoresContainer}>
<FlatList
data={scoreTitles}
renderItem={({ item }) => {
const index = scoreTitles.indexOf(item);
return (
<>
{
<View
key={index}
style={{
padding: 10
}}
>
<Score title={item.key}/>
<View style={{ flex: 0.5 }}>
<Input
disabled={true}
inputContainerStyle={{ borderBottomColor: "#EAEAEA" }}
/>
</View>
</View>
}
</>
);
}}
/>
</View>
</View>
);
...

Related

How to make the radio button to change depending to the modal answer in react-native

I have the following code which is the main page and does have a ratio button:
<Text
style={{
fontSize: 16,
marginTop: 10,
color: "#00357B",
fontWeight: "bold",
}}
>
1. Select your recording option:
</Text>
</View>
<View>
<RadioGroup
radioButtons={radioButtons}
onPress={onPressRadioButton}
layout="row"
style={{ marginBottom: 10 }}
/>
</View>
</View>
Below in the same page I do the section of the modal where the original modal is the CategoryModal and is imported from another file:
<Modal
transparent={true}
animationType="fade"
visible={isModalVisible}
nRequestClose={() => changeModalVisible(false)}
>
<CategoryModal
changeModalVisible={changeModalVisible}
setData={setData}
headerText="Header Text"
descriptionText="Description Text"
/>
</Modal>
The Category Modal file looks like that:
closeModal = (bool, data) => {
props.changeModalVisible(bool, data);
props.setData(data);
};
return (
<TouchableOpacity disabled={true} style={styles.container}>
<View style={styles.modal}>
<View style={styles.textView}>
<Text style={[styles.text, { fontSize: 20 }]}>
{props.headerText}
</Text>
<Text style={[styles.text, { fontWeight: "light" }]}>
{props.descriptionText}
</Text>
</View>
</View>
<View style={styles.buttonsView}>
<TouchableOpacity
style={styles.touchableOpacity}
onPress={() => closeModal(false, "Cancel")}
>
<Text style={[styles.text, { color: "blue" }]}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.touchableOpacity}
onPress={() => closeModal(false, "Proceed")}
>
<Text style={[styles.text, { color: "blue" }]}> Proceed</Text>
</TouchableOpacity>
</View>
</TouchableOpacity>
);
};
And overall I am trying to implement the function for the ratio button to change depending to the modal answer that looks like that :
if (valueDropdown2 != null && recordedWord) {
changeModalVisible(true);
warningModalCategory = true;
const chooseData = await new Promise((resolve) => {
setData(resolve);
});
if (chooseData == "Proceed") {
setRadioButtons(radioButtonsArray);
setValueDropdown1(null);
setIsFocusDropdown1(false);
setValueDropdown2(null);
setIsFocusDropdown2(false);
radioButtonsArray.forEach((button) => {
if (button.selected) {
selectedOptionRadioButton = button.value;
}
});
} else {
radioButtonsArray.forEach((button) => {
if (button.value === "one-word") {
selectedOptionRadioButton = button.value;
}
});
}
} else {
setRadioButtons(radioButtonsArray);
setValueDropdown1(null);
setIsFocusDropdown1(false);
setValueDropdown2(null);
setIsFocusDropdown2(false);
radioButtonsArray.forEach((button) => {
if (button.selected) {
selectedOptionRadioButton = button.value;
}
});
}
}

How to make Detail Screen from flat list React Native Expo

I am trying to open new screen with flat list from Notification. Output like this from Pages Notification (when click the blue, move to another pages).
Here is my notification screen
and this is my detail screen
and this is my Notification View
_renderItem = ({item}) => (
<TouchableOpacity onPress={() => this.props.navigation.navigate('LogHistoryDetail', {UserEmail: this.props.navigation.state.params.UserEmail})}>
<Text style = {styles.item}> {item.history_content}</Text>
</TouchableOpacity>
);
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.btn} onPress={() => this.props.navigation.navigate('HomeScreen')}>
<Ionicons name="arrow-back-circle" size={30} color="black" />
</TouchableOpacity>
<Text style = {{fontSize:30, alignContent:"flex-start", color:'black'}}>Notification</Text>
<FlatList
data={this.state.data}
renderItem = {this._renderItem}
keyExtractor = { (item, index) => index.toString() }
/>
</View>
);
}
}
and this is my Detail Screen View
_renderItem = ({item}) => (
<View style = {{backgroundColor:'#1E90FF',margin:15, justifyContent: 'center', borderTopRightRadius: 15,
borderTopLeftRadius: 15, borderBottomEndRadius: 15, borderBottomLeftRadius: 15 }}>
<Text style = {{fontSize:15,margin:15, justifyContent: 'center' ,color:'white'}}> ID Log: {item.id_log}</Text>
<Text style = {{fontSize:15,margin:15, justifyContent: 'center' ,color:'white'}}> Email: {this.props.navigation.state.params.UserEmail}</Text>
<Text style = {{fontSize:15,margin:15, justifyContent: 'center' ,color:'white'}}> History Title: {item.history_title}</Text>
</View>
);
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.btn2} onPress={() => this.props.navigation.navigate('LogNotification')}>
<Ionicons name="arrow-back-circle" size={30} color="black" />
</TouchableOpacity>
<Text style={styles.headerTxt}>History Detail</Text>
<View style={styles.subView}>
<FlatList
data={this.state.data}
renderItem = {this._renderItem}
keyExtractor = { (item, index) => index.toString() }
/>
</View>
</View>
);
}
}
It seems like i got the wrong output on Detail Screen. I want to get output like this without picture.
Is it possible to make Detail Screen like that? Any suggestion that i need to change my View code or wrong render?
Thank you

How to pass numeric input values of components inside flatlist from modal screen to main component screen?

I have a list of items inside a flatlist with numeric inputs of each one of them as follows
My code for the flatlist is as follows:
const BedRoomModal = () => {
return (
<View style={{flex: 1}}>
<ScrollView>
<Text style={Styles.headerText}>Bedroom 1</Text>
<View style={Styles.container}>
<FlatList
data={bedData.BED}
renderItem={renderItem}
keyExtractor={(item) => item.BED_ID}
/>
</View>
</ScrollView>
<TouchableOpacity
onPress={() => BedRoomSave()}
style={{
alignSelf: 'flex-end',
right: 5,
position: 'absolute',
bottom: 10,
}}>
<View
style={{
backgroundColor: '#20B2AA',
alignSelf: 'flex-end',
padding: 10,
}}>
<Text style={{fontSize: 15, fontWeight: 'bold', color: '#fff'}}>
SAVE
</Text>
</View>
</TouchableOpacity>
</View>
);
};
renderItem is as follows:
const renderItem = ({item,index}) => {
return (
<>
<View
style={{
marginBottom: 24,
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Text style={Styles.checklistTitle}>{item.BED_TITLE}</Text>
<NumericInput
value={bed[index]}
onChange={(value) => bedDataFunction(value,index)}
totalWidth={100}
totalHeight={35}
iconSize={22}
step={1}
valueType="integer"
textColor="#B0228C"
iconStyle={{color: 'black'}}
rightButtonBackgroundColor="#fff"
leftButtonBackgroundColor="#fff"
minValue={0}
/>
</View>
<View style={Styles.itemSeparator}></View>
</>
);
};
bedDataFunction:
const bedDataFunction=(value,id)=>{
console.log('VALUE')
console.log(value)
console.log('ID')
console.log(id)
}
The states that I have used are:
const [bed, setBed] = useState([]);
I get the value inside the console of my onchange function but now I need to take that value and display it on screen? could anyone tell what am I doing wrong here?
Any suggestion would be welcomed, am stuck since long now, hopefully would recieve help, thank you.
Let me know if anything is required for better understanding of the code.

how to write a for loop inside a return statement in react native

so i want to display multiple content on the screen using the for loop and it dose not seem to work. with what i want to do using the map method is not going to work because i don't have an array. here is what i tried.
{() => {
for (let i = 0; i < cartnumpass; i++) {
<View style={styles.flyingcard}>
<View style={styles.amt}>
<TouchableOpacity>
<Icon name="ios-add" type="ionicon" color="#0079b1" />
</TouchableOpacity>
<Text style={{fontSize: RFPercentage(2.5)}}>1</Text>
<TouchableOpacity>
<Icon name="ios-remove" type="ionicon" color="#ffaaaa" />
</TouchableOpacity>
</View>
<View style={styles.img}>
<Image
source={require('../resources/Cameras.jpg')}
style={styles.image}
/>
</View>
<View style={styles.des}>
<Text style={styles.heading}>Fuhr Camera</Text>
<Text style={styles.sub}>N 2,000.00 NGN</Text>
<TouchableOpacity
onPress={() => modalfunc(true)}
style={{
justifyContent: 'space-between',
borderColor: '#555',
borderWidth: 1,
borderStyle: 'solid',
width: '90%',
alignItems: 'center',
flexDirection: 'row',
padding: '2%',
}}>
<Text style={{fontSize: RFPercentage(1.7)}}>
Rent Duration
</Text>
<Icon
name="ios-add-circle"
type="ionicon"
color="#888"
size={15}
/>
</TouchableOpacity>
</View>
<View style={styles.cancel}>
<TouchableOpacity style={styles.btn}>
<Icon name="ios-close" type="ionicon" color="#fff" />
</TouchableOpacity>
</View>
</View>;
}
}}
with this code nothing displays on the screen, i don't know if it is possible to write a loop in this form
thanks in advance
You wouldn't do it that way, you would do something like:
return new Array(cartnumpass).fill().map((_, index) => {
<View key={index} style={styles.flyingcard}>
// ...
</View>
});
Or you could do something like:
const views = [];
for (let i = 0; i < cartnumpass; i++) {
views.push(
<View key={i} style={styles.flyingcard}>
// ...
</View>
);
}
return views;

change state individually in react-native

The data is coming dynamically and I want to change state of bookmark icon individually. When we click on first box then only change state of bookmark of that box only others will remain as it is.
My code
this.state={ isTagged: false };
_handle_tag_btn() {
if(this.state.isTagged == true) {
this.setState({isTagged: false})
}
else {
this.setState({isTagged: true})
}
}
render(){
return(
<View style={{flex: 1}}>
{
this.state.product_detail.length <= 0 ?
<ActivityIndicator color = '#bc2b78' size = "large" />
:
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
{
this.state.product_detail.map((data, index) => (
<View style={s.cate_detail_box}>
<TouchableOpacity activeOpacity={0.9} style={{height: 190}} onPress={this._goto_individual_detail}>
<Image source={{uri: data.images[0].src}} style={s.img}/>
</TouchableOpacity>
<View style={{padding: 5}}>
<View activeOpacity={0.9} style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<View>
<CapitalizedText style={s.cate_detail_title}>{data.title}</CapitalizedText>
<Text style={s.cate_detail_price}>{'₹' + data.variants[0].price}</Text>
</View>
<TouchableOpacity activeOpacity={0.7} onPress={this._handle_tag_btn} key={index}>
{
this.state.isTagged ?
<Icon size={icon_size} color="#aaa" name="turned-in-not" />
:
<Icon size={icon_size} color="#aaa" name="turned-in" />
}
</TouchableOpacity>
</View>
</View>
</View>
))
}
</View>
}
</View>
);
}
My output https://i.stack.imgur.com/05uPN.jpg
In this image all bookmarks are selected which is not required.
Any help is appreciated. Thank you.
You can take the bookmark view inside .map and create a new component and then toggle the bookmark status in that component. You pass the data attribute as a prop to this new component -
class Bookmark extends React.Component {
state = { isTagged: false }
_handle_tag_btn() {
if (this.state.isTagged == true) {
this.setState({ isTagged: false })
} else {
this.setState({ isTagged: true })
}
}
render() {
const { data } = this.props
return (
<View style={s.cate_detail_box}>
<TouchableOpacity
activeOpacity={0.9}
style={{ height: 190 }}
onPress={this._goto_individual_detail}
>
<Image source={{ uri: data.images[0].src }} style={s.img} />
</TouchableOpacity>
<View style={{ padding: 5 }}>
<View
activeOpacity={0.9}
style={{ flexDirection: "row", justifyContent: "space-between" }}
>
<View>
<CapitalizedText style={s.cate_detail_title}>
{data.title}
</CapitalizedText>
<Text style={s.cate_detail_price}>
{"₹" + data.variants[0].price}
</Text>
</View>
<TouchableOpacity
activeOpacity={0.7}
onPress={this._handle_tag_btn}
key={index}
>
{this.state.isTagged ? (
<Icon size={icon_size} color="#aaa" name="turned-in-not" />
) : (
<Icon size={icon_size} color="#aaa" name="turned-in" />
)}
</TouchableOpacity>
</View>
</View>
</View>
)
}
}
And then use it inside your .map like this -
this.state.product_detail.map((data, index) => <Bookmark data={data} />)
You could set the tagged object in state, for example:
this.state={ taggedObject: null };
_handle_tag_btn(data) {
if(this.state.taggedObject === data) {
this.setState({taggedObject: null})
}
else {
this.setState({taggedObject: data})
}
}
// ...
<TouchableOpacity activeOpacity={0.7} onPress={() => this._handle_tag_btn(data)} key={index}>
{
this.state.taggedObject === data ?
<Icon size={icon_size} color="#aaa" name="turned-in-not" />:
<Icon size={icon_size} color="#aaa" name="turned-in" />
}
</TouchableOpacity>

Resources