one Collapsible should open at one time - javascript

// Here in my code there are three Collapsibles, after clicking one it will expand, but to close it again i have to click on that particular text.
I would like to make a change: if any of the three Collapsibles are already open, and I click the new button, then the existing Collapsibles should close automatically.
{isSimUAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ simUpgrade: !this.state.simUpgrade });
}}>
<RegularText text="SIM Upgrade" textColor={this.state.simUpgrade?'#006288':'black'} style={{fontWeight:this.state.simUpgrade?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={!this.state.simUpgrade}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'swap',1)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
{isSimCAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ lostSim: !this.state.lostSim });
}}>
<RegularText text="SIM Change" textColor={this.state.lostSim?'#006288':'black'} style={{fontWeight:this.state.lostSim?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={!this.state.lostSim}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'lost',1)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
{isSimEAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ validator: !this.state.validator });
}}>
<RegularText text="E-validator" textColor={this.state.validator?'#006288':'black'} style={{fontWeight:this.state.validator?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={!this.state.validator}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'validate',0)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
Thanks

You can use one common property for state instead of three different property, that single property can have different values in your case it can have 'simUpgrade', 'lostSim' and 'validator' i.e
this.state = {
active : 'simUpgrade'
}
And than in your code you can use it like this
{isSimUAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ active: 'simUpgrade' });
}}>
<RegularText text="SIM Upgrade" textColor={this.state.simUpgrade?'#006288':'black'} style={{fontWeight:this.state.simUpgrade?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={this.state.active !== 'simUpgrade'}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'swap',1)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
{isSimCAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ active: 'lostSim'});
}}>
<RegularText text="SIM Change" textColor={this.state.lostSim?'#006288':'black'} style={{fontWeight:this.state.lostSim?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={this.state.active !== 'lostSim'}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'lost',1)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
{isSimEAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ active: 'validator' });
}}>
<RegularText text="E-validator" textColor={this.state.validator?'#006288':'black'} style={{fontWeight:this.state.validator?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={this.state.active !== 'validator'}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'validate',0)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}

Related

react-native webview button hide and enable

I started developing new application in React. I have a webview application and I want to add a feature like this, I want the basket icon at the bottom to not appear when the user login is not provided, but I need to ensure that the bottom basket button is active again when the user logs in. Can you help me on how to do this ?
onPressButtonURL = (url) => {
console.log("==========>>> URL: ", url);
this.setState({ url:`${url}?t=${Date.now()}` });
}
mystyles = {
display: "none"
};
render()
{
return (
<Container>
<WebView source={{uri:this.state.url}} ref={WEBVIEW_REF} useWebKit={true} cacheEnabled={true} style={{marginTop: 30, flex: 1}}
onLoadProgress={({ nativeEvent }) => {this.loadingProgress = nativeEvent.progress;}}/>
<View style={{ alignSelf: "auto"}}>
<Fab active={this.state.active} direction="up" containerStyle={{bottom: 100 }} style={{ backgroundColor: '#5067FF'}} position="bottomRight" onPress={() => this.setState({ active: !this.state.active })}>
<Icon type="FontAwesome" name="share-alt" />
<Button style={{ backgroundColor:'#34A34F'}} ref="whatsapp" onPress={() => Linking.openURL('whatsapp://send?text='+wa_message+'&phone='+wa_number) }><Icon type="FontAwesome" name="whatsapp"/></Button>
<Button style={{ backgroundColor:'#3B5998'}} ref="facebook" onPress={() => Linking.openURL(fb_url) }><Icon type="FontAwesome" name="facebook"/></Button>
<Button style={{ backgroundColor:'#f09433'}} ref="inst" onPress={() => Linking.openURL(inst_url) }><Icon type="FontAwesome" name="instagram"/></Button>
<Button style={{ backgroundColor:'#DD5144'}} ref="mail" onPress={() => Linking.openURL('mailto:'+mail_url) }><Icon type="FontAwesome" name="envelope"/></Button>
</Fab>
<Footer>
<FooterTab>
<Button vertical onPress={() => this.onPressButtonURL(this.site_url+'index.php')} danger={this.state.clicked}><Icon type="FontAwesome" name="home" /><Text></Text></Button>
<Button vertical onPress={() => this.onPressButtonURL(this.site_url+'sepetimigoster.html')} danger={this.state.clicked}><Icon type="FontAwesome" name="shopping-basket" id="shopping-basket" /><Text></Text></Button>
<Button vertical onPress={() => this.onPressButtonURL(this.site_url+'uyegiris.html')}><Icon type="FontAwesome" name="user" /><Text></Text></Button>
<Button vertical onPress={() =>this.refs[WEBVIEW_REF].goBack()}><Icon type="FontAwesome" name="arrow-left" /><Text></Text></Button>
<Button vertical onPress={() =>this.refs[WEBVIEW_REF].goForward()}><Icon type="FontAwesome" name="arrow-right" /><Text></Text></Button>
</FooterTab>
</Footer>
</View>
</Container>
);
}
}
If you want the button to be omitted completely you can just conditionally include it with something like this:
onPressButtonURL = (url) => {
console.log("==========>>> URL: ", url);
this.setState({ url:`${url}?t=${Date.now()}` });
}
mystyles = {
display: "none"
};
render()
{
let isLoggedIn = false; // wherever this comes from
return (
<Container>
<WebView source={{uri:this.state.url}} ref={WEBVIEW_REF} useWebKit={true} cacheEnabled={true} style={{marginTop: 30, flex: 1}}
onLoadProgress={({ nativeEvent }) => {this.loadingProgress = nativeEvent.progress;}}/>
<View style={{ alignSelf: "auto"}}>
<Fab active={this.state.active} direction="up" containerStyle={{bottom: 100 }} style={{ backgroundColor: '#5067FF'}} position="bottomRight" onPress={() => this.setState({ active: !this.state.active })}>
<Icon type="FontAwesome" name="share-alt" />
<Button style={{ backgroundColor:'#34A34F'}} ref="whatsapp" onPress={() => Linking.openURL('whatsapp://send?text='+wa_message+'&phone='+wa_number) }><Icon type="FontAwesome" name="whatsapp"/></Button>
<Button style={{ backgroundColor:'#3B5998'}} ref="facebook" onPress={() => Linking.openURL(fb_url) }><Icon type="FontAwesome" name="facebook"/></Button>
<Button style={{ backgroundColor:'#f09433'}} ref="inst" onPress={() => Linking.openURL(inst_url) }><Icon type="FontAwesome" name="instagram"/></Button>
<Button style={{ backgroundColor:'#DD5144'}} ref="mail" onPress={() => Linking.openURL('mailto:'+mail_url) }><Icon type="FontAwesome" name="envelope"/></Button>
</Fab>
<Footer>
<FooterTab>
<Button vertical onPress={() => this.onPressButtonURL(this.site_url+'index.php')} danger={this.state.clicked}><Icon type="FontAwesome" name="home" /><Text></Text></Button>
{isLoggedIn &&
<Button vertical onPress={() => this.onPressButtonURL(this.site_url+'sepetimigoster.html')} danger={this.state.clicked}><Icon type="FontAwesome" name="shopping-basket" id="shopping-basket" /><Text></Text></Button>}
<Button vertical onPress={() => this.onPressButtonURL(this.site_url+'uyegiris.html')}><Icon type="FontAwesome" name="user" /><Text></Text></Button>
<Button vertical onPress={() =>this.refs[WEBVIEW_REF].goBack()}><Icon type="FontAwesome" name="arrow-left" /><Text></Text></Button>
<Button vertical onPress={() =>this.refs[WEBVIEW_REF].goForward()}><Icon type="FontAwesome" name="arrow-right" /><Text></Text></Button>
</FooterTab>
</Footer>
</View>
</Container>
);
}
}

"undefined is not an object", need to check if allNotes array is empty. How?

Feel like this is kind of a silly question but I need to only return the allNotes map data if allNotes isn't empty (its an array). This seems like just a simple if/else but really can't figure out how to do this in this context (inside view). Right now, I get the error in the title when nothing is in the array. when it has data everything is fine.
{isOpen &&
<TouchableOpacity onPress={() => updateDrop(prev => !prev)} style={styles.flastListUpdated}>
<View style={{ alignItems: 'center' }}>
<Text style={styles.flastlistItemText2}>{props.noteitem.note}</Text>
</View>
<View style={{ height: 1, width: '100%', backgroundColor: 'lightgrey' }} />
<View>
{allNotes.map((item) => {
return (
<View style={{ flexDirection: 'row', margin: 5 }}>
<View style={styles.perItemBar} />
<Text style={styles.noteTextStyle}>{item}</Text>
</View>
)
})}
<View style={styles.bottomBar}>
<TextInput onChangeText={(text) => { updateNoteStatus(text) }} style={{ flex: 2 }} placeholder='Enter New:' />
<TouchableOpacity onPress={addNote} style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>+</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
}
</View>
)
}
Again I Know this is something really simple but I can't get the formatting correct. Don't know what the correct method of doing this would be. Thanks!
Could always double check that allNotes is defined like this although it may be better to default allNotes to an empty array and then confirm here that it's what you'd expect.
{isOpen &&
<TouchableOpacity onPress={() => updateDrop(prev => !prev)} style={styles.flastListUpdated}>
<View style={{ alignItems: 'center' }}>
<Text style={styles.flastlistItemText2}>{props.noteitem.note}</Text>
</View>
<View style={{ height: 1, width: '100%', backgroundColor: 'lightgrey' }} />
<View>
{allNotes && allNotes.map(item => (
<View style={{ flexDirection: 'row', margin: 5 }}>
<View style={styles.perItemBar} />
<Text style={styles.noteTextStyle}>{item}</Text>
</View>
)
)}
<View style={styles.bottomBar}>
<TextInput onChangeText={(text) => { updateNoteStatus(text) }} style={{ flex: 2 }} placeholder='Enter New:' />
<TouchableOpacity onPress={addNote} style={{ flex: 1 }}>
<Text style={{ fontSize: 30 }}>+</Text>
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
}
</View>
)
}

after clicking new Collapsible closed other Collapsible which is open

// Here in my code there are three Collapsibles, after clicking one it will expand, but to close it again i have to click on that particular text.
I would like to make a change: if any of the three Collapsibles are already open, and I click the new button, then the existing Collapsibles should close automatically.
{isSimUAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ simUpgrade: !this.state.simUpgrade });
}}>
<RegularText text="SIM Upgrade" textColor={this.state.simUpgrade?'#006288':'black'} style={{fontWeight:this.state.simUpgrade?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={!this.state.simUpgrade}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'swap',1)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
{isSimCAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ lostSim: !this.state.lostSim });
}}>
<RegularText text="SIM Change" textColor={this.state.lostSim?'#006288':'black'} style={{fontWeight:this.state.lostSim?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={!this.state.lostSim}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'lost',1)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
{isSimEAllowed && <View style={styles.paymentMethod}>
<TouchableOpacity onPress={() => {
this.setState({ validator: !this.state.validator });
}}>
<RegularText text="E-validator" textColor={this.state.validator?'#006288':'black'} style={{fontWeight:this.state.validator?'bold':'normal'}}/>
</TouchableOpacity>
<Collapsible collapsed={!this.state.validator}>
<Button
block
primary
onPress={() => this.loadScreen('CustomerVerification', 'validate',0)}
style={{ marginTop: 10 }}
>
<Text>Proceed</Text>
</Button>
</Collapsible>
</View>}
Thanks
The Accordion component from react-native-collapsible takes care of this particular use case.

How to solve margin problem between two components inside a Modal in React-Native?

In my react-native project inside modal, I am using two buttons in a View. But the problem is - no margin is working between them.
Here's the code
<View style={styles.container}>
<Modal
animationType={"slide"}
transparent={false}
visible={this.state.ModalVisibleStatus}
onRequestClose={() => { console.log("Modal has been closed.") }}
>
{/*All views of Modal*/}
{/*Animation can be slide, slide, none*/}
<View style={styles.modal}>
<Text style={styles.text}>Modal is open!</Text>
<View style={styles.inputContainerEmail}>
<Image style={styles.inputIcon} source={{ uri: this.state.catImage }} />
<TextInput style={styles.inputs}
placeholder="Email Address"
keyboardType="email-address"
underlineColorAndroid='transparent'
onChangeText={(text) => this.updateValue(text, 'email')} />
</View>
<View style={{ flexDirection: 'row' }}>
<Button style={{ marginRight: 10 }} title="Save" onPress={() => {
this.setState({ ModalVisibleStatus: !this.state.ModalVisibleStatus })
}} />
<Button style={{ marginLeft: 10 }} title="Close" onPress={() => {
this.setState({ ModalVisibleStatus: !this.state.ModalVisibleStatus })
}} />
</View>
</View>
</Modal>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#DCDCDC',
},
modal: {
flex: 1,
alignItems: 'center',
backgroundColor: '#aaaa',
padding: 100
},
text: {
color: '#3f2949',
marginTop: 10
}
)}
After running these code it's getting following output-
So how can I add margin between these two buttons?
The React-Native Button is very limited in what you can do, and doesn't support a style property as far as I know. I would suggest looking into using TouchableOpacity or TouchableNativeFeedback to customize your needs.
A potentially dirtier solution would be to wrap both Buttons inside a separate individual parent View component and applying your margin property to these parent View components instead. Alternatively, you could perhaps specify justifyContent:'space-between' on your parent View Component as is and seeing if that gives the desired result too. For example, the multiple view approach might look something like the following:
<View style={{flexDirection: 'row'}}>
<View style={{flex:1 , marginRight:10}} >
<Button title="Save" onPress={() => {
this.setState({ ModalVisibleStatus: !this.state.ModalVisibleStatus })
}} />
</View>
<View style={{flex:1}} >
<Button title="Close" onPress={() => {
this.setState({ ModalVisibleStatus: !this.state.ModalVisibleStatus })
}} />
</View>
</View>
Hopefully that helps!
Add justifyContent:"space-between" in your button view code as
<View style={{ flex:1, flexDirection: 'row' , justifyContent:"space-between"}}>
<Button style={{ flex:1}} title="Save" onPress={() => {
this.setState({ ModalVisibleStatus: !this.state.ModalVisibleStatus })
}} />
<Button style={{ flex:2 }} title="Close" onPress={() => {
this.setState({ ModalVisibleStatus: !this.state.ModalVisibleStatus })
}} />
</View>
Link for reference https://css-tricks.com/almanac/properties/j/justify-content/

unable to map data from JSON in render method, empty screen on emulator

I am successfully getting data from API and also am able to pass the object as props in the next component, my code for passing object is:
if (stateItems.length > 0) {
console.log(stateItems[0]);
if (stateItems[i + 1]) {
items.push(
<Grid key={i}>
<Product key={stateItems[i].product_id} product={stateItems[i]} />
<Product key={stateItems[i + 1].product_id} product={stateItems[i + 1]} isRight />
</Grid>
);
}
}
In the receiving end when i console log this.props.product I can see my data:
but when I try to render the data I get an empty screen, my code for rendering the data is:
render() {
console.log(this.props.product)
return (
<Col style={this.props.isRight ? style.leftMargin : style.rightMargin}>
<Card transparent>
<CardItem cardBody>
<Button transparent style={style.button} onPress={() => this.pressed()}>
<Image source={{ uri: this.props.product.image }} style={style.image} />
<View style={style.border} />
</Button>
</CardItem>
<CardItem style={{ paddingTop: 0 }}>
<Button style={{ flex: 1, paddingLeft: 0, paddingRight: 0, paddingBottom: 0, paddingTop: 0 }}
transparent
onPress={() => this.pressed()}
>
<Body>
<Text
style={{ fontSize: 16 }}
numberOfLines={1}
>{this.props.product.name}</Text>
<View style={{ flex: 1, width: '100%', alignItems: 'center' }}>
<View style={style.line} />
<Text style={style.price}>{this.props.product.price}</Text>
<View style={style.line} />
</View>
</Body>
</Button>
</CardItem>
</Card>
</Col>
);}
As per you show this.props.product look like its array of object.
You need to use map for iterate array and display product.
this.props.product.map((singleProduct, index) => {
return (
<Col style={this.props.isRight ? style.leftMargin : style.rightMargin}>
<Card transparent>
<CardItem cardBody>
<Button transparent style={style.button} onPress={() => this.pressed()}>
<Image source={{ uri: singleProduct.image }} style={style.image} />
<View style={style.border} />
</Button>
</CardItem>
<CardItem style={{ paddingTop: 0 }}>
<Button style={{ flex: 1, paddingLeft: 0, paddingRight: 0, paddingBottom: 0, paddingTop: 0 }}
transparent
onPress={() => this.pressed()}
>
<Body>
<Text
style={{ fontSize: 16 }}
numberOfLines={1}
>{singleProduct.name}</Text>
<View style={{ flex: 1, width: '100%', alignItems: 'center' }}>
<View style={style.line} />
<Text style={style.price}>{singleProduct.price}</Text>
<View style={style.line} />
</View>
</Body>
</Button>
</CardItem>
</Card>
);
})

Categories