Here there are two tabs invoice_specific and as_hoc and one button where I am displaying sum(this.state.sum) value .
by default when I open the screen in sum state "invoice_specific" value should come I have written this in render function below .
Now if I change the tabs I am calling function handleChangeTab() ,here on tab change I have to update the state sum .
If I am in first tab invoice_specific value should display else I am in as_hoc tab them this value should assign in sum .
constructor() {
this.state = {
sum: 0,
invoice_specific: 0,
as_hoc: 0
}
this.handleChangeTab = this.handleChangeTab.bind(this)
}
handleChangeTab=(obj) =>{
console.log({ obj })
}
console value of obj in function handleChangeTab()
{ i: 1, ref: {…}, from: 0 }
from: 0
i: 1
ref: $$typeof: Symbol(react.element)
key: ".1"
props:
children: {
$$typeof: Symbol(react.element),
type: ƒ,
key: null,
ref: null,
props: {…},
…
}
heading: "AD-HOC"
tabLabel: "AD-HOC"
virtual: undefined
return function
render(){
const viewStyle = {flexDirection: 'column', padding:10, backgroundColor: '#fff', minHeight:deviceHeight }
return(
<Tabs onChangeTab={(obj)=> this.handleChangeTab(obj)}>
<Tab heading="INVOICE SPECIFIC" tabLabel="SPECIFIC">
<View style={viewStyle}>
<RegularText text="Enter Specific Amount to pay" style={{paddingBottom:5}} textColor="#959595" />
<View>
<Item style={{borderColor: '#00fff', borderBottomWidth:1}}>
<Input autoFocus={true}
onPress={()=> this.handleChange('sumValue')}
onChangeText={(sumValue) => this.handleChangeSum(sumValue)} />
</Item>
</View>
</View>
</Tab>
<Tab heading="AD-HOC" tabLabel="AD-HOC">
<View style={viewStyle}>
<RegularText text="Enter Specific Amount to pay" style={{paddingBottom:5}} textColor="#959595" />
<View>
<Item style={{borderColor: '#00fff', borderBottomWidth:1}}>
<Input autoFocus={true}
onPress={()=> this.handleChange('sumValue')}
onChangeText={(sumValue) => this.handleChangeSum(sumValue)} />
</Item>
</View>
</View>
</Tab>
</Tabs>
)
}
I didn't see that you have called setState() anywhere. You need to call setState appropriately while avoiding infinite re-rendering. Also if you can go further and change it to a functional component where you would find ref and useEffect make the code much more simpler and readable.
Related
Absolute react-native noob here. I am struggling with updating the 'selected item'. I'm using this as a piece of dummy data:
this.state = {
branch: '',
completedBy: '',
reportedTo: '',
branchData: {
text: 'Branch',
value: '',
options: [
{code: '0001', name: 'TEST 1', key: 1},
{code: '0002', name: 'TEST 2', key: 2},
{code: '0003', name: 'TEST 3', key: 3},
]
}
};
I then made a separate file for my dropdown component, it looks like this:
super(props);
this.state = {
modalVisible: false
};
}
render() {
return (
<>
<TouchableWithoutFeedback style={styles.refreshBtn} onPress={() => this.setState({ modalVisible: true })} >
<View style={styles.container} >
{
this.props.data.value ?
<Text style={styles.selectedText} >{this.props.data.value}</Text>
:
<Text style={styles.placeholderText} >{this.props.data.text}</Text>
}
<MaterialCommunityIcons name={'chevron-down'} size={30} color={Colors.grey} />
</View>
</TouchableWithoutFeedback>
<Modal
animationType="slide"
visible={this.state.modalVisible}
onRequestClose={() => {
this.setState({ modalVisible: false })
}}
>
<TouchableOpacity onPress={() => this.setState({ modalVisible: false })} style={{ flexDirection: "row", justifyContent: "flex-end", margin: 10, paddingLeft: 50}}>
<Ionicons name="md-close" size={30} />
</TouchableOpacity>
<FlatList
data={this.props.data.options}
keyExtractor={(item) => item.key.toString()}
renderItem={({ item }) => (
<TouchableOpacity style={styles.itemContainer} onPress={() => console.log('tapped'} >
<Text style={styles.itemText}>{item.code + ' ' + item.name}</Text>
</TouchableOpacity>
)}
/>
</Modal>
</>
);
}
}
And then back to my initial file, I am simply calling the component like this:
<DropDownMenu data={this.state.branchData}/>
How do I update the value in the branch data object in order to display the selected branch on the dropdown in order to indicate to the user that their choice has been selected instead of displaying the placeholder text which displays as long as value is = to an empty string.
You can pass down a state updating function as a prop to your DropDownMenu component, add this function to the same file where state has been initialized
function updateBranch(dataFromDropDownComponent) {
// modify branch data as required
// this.setState({...this.state, branchData: ... })
}
and then in JSX, pass it as a prop:
<DropDownMenu data={this.state.branchData} updateBranch={updateBranch}/>
Now in your DropDownMenu component, you can access and call the updateBranch function via this.props.updateBranch to update the state whenever required.
Here in both tabs value is different first tab value is coming in invoice_specific state and second in as_hoc ,there is another state sum:0 .
I have to update that sum state on condition in handleChangeTab() function : If I am at tab 1 then in sum state invoice_specific value should go and if I am in
secon tab then in sum state as_hoc value should go .
Hear in my code there are two tabs and one button .
Tab value is coming from array(props) and populating and getting their sum (TransactionAmount 1050+1050+1050=3150) and displaying in below button.
In Second tab there is input field where I am entering any value and that value am displaying in below button .
Now if I go to 2nd tab then only that value should display whaic I'll enter in input field else 0 and again if I come back to first tab that sum value should come whihc is coming from the array .
All this value should display in single button .
I am taking both tabs value is state and on condition I am changing state ,but its not working .
Please help
below link for screen refrence
https://xd.adobe.com/view/d733da48-5d0c-47ca-7ded-6fc8f0f609cf-a102/screen/37cb15c6-b56a-4b98-8612-e9b86d0dd34c/Android-Mobile-147/?fullscreen
console value of obj in function handleChangeTab()
{i: 1, ref: {…}, from: 0}
from: 0
i: 1
ref:
$$typeof: Symbol(react.element)
key: ".1"
props:
children: {$$typeof: Symbol(react.element), type: ƒ, key: null, ref: null, props: {…}, …}
heading: "AD-HOC"
tabLabel: "AD-HOC"
virtual: undefined
// Below is array value
financialTransactionDetail: Array(3)
0:
AdjustedAmount: "0"
NetTransactionAmount: "1050"
TransactionAmount: 1050
1:
AdjustedAmount: "0"
NetTransactionAmount: "1050"
TransactionAmount: 1050
2:
AdjustedAmount: "0"
NetTransactionAmount: "1050"
Status: "Unpaid"
TransactionAmount: 1050
this.state={
sum:0,
invoice_specific:0,
as_hoc:0
}
handleChangeTab=(obj) =>{
console.log("0000",obj);
let objform=obj.form;
console.log("0000",objform);
this.setState({
sum: objform === 0 ? this.state.as_hoc: this.state.invoice_specific ,
})
}
}
render(){
this.state.checked.map((value, index) => { if(value)
{ invoice_specific += financialTransactionDetail.financialTransactionDetail[index].TransactionAmount; } });
retun(
<Tabs onChangeTab={(obj) => this.handleChangeTab(obj)}>
<Tab heading="INVOICE SPECIFIC" tabLabel="SPECIFIC">
{ !_.isEmpty(financialTransactionDetail.financialTransactionDetail) && financialTransactionDetail.financialTransactionDetail.map(
(data, index) => {
const formatedate = data.DueDate;
const formateDate = formatedate.split(' ')[0];
return(
<View key={index} style={{flexDirection:'row', padding:10, alignItems:'center', justifyContent:'space-between',backgroundColor:'#fff'}}>
<View style={{paddingRight:10, marginRight:10}}>
<CheckBox style={styles.checkBox} color="#00678f" checked={this.state.checked[index]} onPress={() =>this.handleChange(index)}/>
</View>
<View style={{flexDirection:'column',flex:1, padding:10, borderWidth:1, borderColor:'lightgrey', borderRadius:3}}>
<View style={{flexDirection:'row', alignItems:'center'}}>
{!this.state.checked[index] && <RegularText text={`₦ ${data.TransactionAmount}`} style={{paddingBottom:10, paddingRight:5}}/>}
<SmallText text={`Due by ${(formateDate)}`} style={{paddingBottom:10}}/>
</View>
{this.state.checked[index] &&
<RegularText text={`₦ ${data.TransactionAmount}`} style={{borderColor: '#00fff', borderBottomWidth:1}}>
</RegularText>
}
</View>
</View>
)
}
)
}
</Tab>
<Tab heading="AD-HOC" tabLabel="AD-HOC">
<View style={{flexDirection:'column', padding:10, backgroundColor:'#fff', minHeight:deviceHeight }}>
<RegularText text="Enter Specific Amount to pay" style={{paddingBottom:5}} textColor="#959595"/>
<View>
<Item style={{borderColor: '#00fff', borderBottomWidth:1}}>
<Input
autoFocus={true}
onPress={() => this.handleChange('sumValue')}
onChangeText={(sumValue) => this.handleChangeSum(sumValue)}
/>
</Item>
</View>
</View>
</Tab>
</Tabs>
</View>
</View>
</ScrollView>
<View style={{bottom:0,position:'absolute', width: '100%'}}>
<Button full onPress={()=>navigation.navigate('PaymentOptionsContainer',sum)}>
<Text>Receive Payment ({sum})</Text>
</Button>
</View>
Here in this screen there are two tabs 1.INVOICE SPECIFIC and 2.AD-HOC .
Now In 1.Invoice SPECIFIC I am maping array ("above array) value with checkbox ,there are some amout "data.TransactionAmount" I have to calculate the sum of all and send to next screen,
but if I uncheck any of the list amount should minus .Like there are 3 values - 1050 ,1050,150 =3150 and if I unchecked single value then it should be 1050+1050=2100.
If i am uncheking single list all list is getting unchecked .
2. Ad Hoc , here I can enter any digint and send in button press , but value is not updating ,1 tab value is going .
Please help , Thanks ,
Below link is refrence what i am implementing .
https://xd.adobe.com/view/d733da48-5d0c-47ca-7ded-6fc8f0f609cf-a102/screen/37cb15c6-b56a-4b98-8612-e9b86d0dd34c/Android-Mobile-147/?fullscreen
// Below is the array value
financialTransactionDetail: Array(3)
0:
AdjustedAmount: "0"
NetTransactionAmount: "1050"
TransactionAmount: 1050
1:
AdjustedAmount: "0"
NetTransactionAmount: "1050"
TransactionAmount: 1050
2:
AdjustedAmount: "0"
NetTransactionAmount: "1050"
Status: "Unpaid"
TransactionAmount: 1050
__typename: "FinancialTransactionDetail"
import React, { Component } from 'react';
import { ImageBackground, ScrollView } from 'react-native';
import { Body, Button, Card, CardItem, CheckBox, Text, View, Item, Input, Tab, Tabs, Container } from 'native-base';
import Header from '../../ui/header';
import BG from '../../../images/bg.jpg';
import _ from 'lodash';
import { RegularText, SmallText } from '../../ui/text';
const styles = {
container: {
flexDirection: 'column',
alignItems: 'stretch'
},
imgBG:{
width: '100%'
},
dataContainer:{
backgroundColor:'#fff', width:'100%', flexDirection:'column', justifyContent:'center', alignItems:'center'
},
checkBox : {paddingBottom:2}
}
class PaymentsInvoice extends Component {
constructor(props) {
super(props);
this.state = {
title: 'Payments against invoice',
icon: 'sim',
mobile:this.props.navigation.state.params.customer.service.serviceNumber,
isChecked:true,
sum :{},
transactionAmount :''
}
}
handleChange(){
this.setState({isChecked:!this.state.isChecked})
}
render() {
let { title, icon, mobile,sum } = this.state;
const { navigation,invoiceDetailsinfo } = this.props;
const{financialTransactionDetail} = invoiceDetailsinfo;
sum = financialTransactionDetail.financialTransactionDetail.reduce((a, c) => { return a + c.TransactionAmount}, 0);
console.log('sum: ', sum)
return (
<ImageBackground source={BG} style={styles.imgBG}>
<ScrollView keyboardShouldPersistTaps='always'>
<View style={styles.container}>
<View>
<Header title={title} icon={icon} subtitle={mobile} navigation={navigation} />
</View>
<View style={styles.dataContainer}>
<Container>
<Tabs>
<Tab heading="INVOICE SPECIFIC">
{ !_.isEmpty(financialTransactionDetail.financialTransactionDetail) && financialTransactionDetail.financialTransactionDetail.map(
(data, index) => {
return(
<View key={index} style={{flexDirection:'row', padding:10, alignItems:'center', justifyContent:'space-between'}}>
<View style={{paddingRight:10, marginRight:10}}>
<CheckBox style={styles.checkBox} color="#00678f" checked={this.state.isChecked} onPress={() =>this.handleChange()}/>
</View>
<View style={{flexDirection:'column',flex:1, padding:10, borderWidth:1, borderColor:'lightgrey', borderRadius:10}}>
<View style={{flexDirection:'row', alignItems:'center'}}>
{!this.state.isChecked && <RegularText text={`₦ ${data.TransactionAmount}`} style={{paddingBottom:10, paddingRight:5}}/>}
<SmallText text="From 1-Jan-2019 to 31-Jan-2019" style={{paddingBottom:10}}/>
</View>
{this.state.isChecked &&
<RegularText text={`₦ ${data.TransactionAmount}`} style={{borderColor: '#00fff', borderBottomWidth:1}}>
</RegularText>
/* <Input
value={this.state.transactionAmount}
onChangeText={(text) => this.setState({value1:text})}
/> */
}
</View>
</View>
)
}
)
}
</Tab>
<Tab heading="AD-HOC">
<View style={{flexDirection:'column', padding:20}}>
<RegularText text="Enter Specific Amount to pay" style={{paddingBottom:10}} textColor="darkgrey"/>
<View>
<Item style={{borderColor: '#00fff', borderBottomWidth:1}}>
<Input
value={this.state.sum}
onChangeText={(text) => this.setState({sum:text})}
/>
</Item>
</View>
</View>
</Tab>
</Tabs>
</Container>
</View>
<View>
<Button full onPress={()=>navigation.navigate('PaymentOptionsContainer',sum)}>
<Text>Receive Payment ({sum})</Text>
</Button>
</View>
</View>
</ScrollView>
</ImageBackground>
);
}
}
export default PaymentsInvoice;
Thanks
I have built sample test application for your requirements.
And it's on this repository: https://github.com/danZheng1993/sample_for_Abhigyan
Please check it
I am using react-native-sectioned-multi-select library. I want to open another modal view after I click the confirm button.
I feel like I did the code correctly but this isn't working. Is it possible to open a new modal inside this library?
const items = [
{
name: "Fruits",
id: 0,
children: [{
name: "Apple",
id: 10,
},{
name: "Strawberry",
id: 17,
},{
name: "Pineapple",
id: 13,
},{
name: "Banana",
id: 14,
},{
name: "Watermelon",
id: 15,
},{
name: "Kiwi fruit",
id: 16,
}]
}]
export default class TestScreen extends Component {
constructor(){
super()
this.state = {
selectedItems: [],
modalVisible: false,
}
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
onSelectedItemsChange = (selectedItems) => {
this.setState({ selectedItems });
console.log(selectedItems)
}
openModal = () => {
return(
<SafeAreaView style={{flex:1}}>
<View style={{width:300, height:400, backgroundColor:'red'}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
<TouchableHighlight
onPress={() => {
this.setModalVisible(true);
}}>
<Text>Show Modal</Text>
</TouchableHighlight>
</View>
</SafeAreaView>
)
}
render() {
return (
<SafeAreaView style={{flex:1}}>
<View>
<SectionedMultiSelect
items={items}
uniqueKey='id'
subKey='children'
selectText='Choose some things...'
showDropDowns={true}
readOnlyHeadings={true}
onSelectedItemsChange={this.onSelectedItemsChange}
selectedItems={this.state.selectedItems}
//Here I call the openModal function but nothing appears
onConfirm={()=> {this.openModal}}
/>
</View>
</SafeAreaView>
);
}
}
Any comments or advise would be really appreciated! Thanks in advance! :)
Edited
If I can't open two modals at a time, I want my new modal to open after I close my first modal.
Multiple simultaneously open modals do not work in React Native. You could:
close the first modal before opening the second one, then reopening the first one when you're done with the second
roll your own modal using 'position: absolute' styling
Firstly, make sure both the Modal's aren't using the same state values for the visible prop in Modal.
You can use visible prop as visible={this.state.modalPage1}. The state modalPage1 should be initiated to bool value.
So if the scenario is that you are closing the first Modal and opening another one, then
this.setState({
modalPage1: false,
modalPage2: true
});
Hope I could help you. Do comment if any other Doubts.
You could manipulate multiple modal visibility with Conditional Rendering using logical operator. Here is the snippet code that might work in your case:
{
this.state.isFirstModalOpen && (
<Modal
animationType="slide"
transparent={false}
visible={this.state.isModalOpen}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={{ marginTop: 22 }}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setState({
isFirstModalOpen: false,
isSecondModalOpen: true
});
}}
>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
);
}
{
this.state.isSecondModalOpen && (
<Modal
animationType="slide"
transparent={false}
visible={this.state.isSecondModalOpen}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={{ marginTop: 22 }}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight
onPress={() => {
this.setState({ isSecondModalOpen: false });
}}
>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
);
}
render() {
return (
<SafeAreaView style={{flex:1}}>
<View>
<SectionedMultiSelect
items={items}
uniqueKey='id'
subKey='children'
selectText='Choose some things...'
showDropDowns={true}
readOnlyHeadings={true}
onSelectedItemsChange={this.onSelectedItemsChange}
selectedItems={this.state.selectedItems}
//Here I call the openModal function but nothing appears
//onConfirm={()=> {this.openModal}} <-- change this with
onConfirm={() => this.setState({modalVisible: true})}
/>
</View>
</SafeAreaView>
);
}
You dont call directly a modal, you have to toggle the visible state of modal
And then you need to close the modal as well whenever your task is completed, all you need to do is, on click or on Press....
this.setState({ modalVisible: false });
I want to submit value from text input, but when I console.log, the text that inputed before is undefined. I've already follow the instruction from react native get TextInput value, but still undefined.
this is state that I've made before:
this.state = {
comment_value: '',
comments: props.comments
}
submit = (args) => {
this.props.submit(args.comment_value)
}
this is the the function for submitted text:
addComment () {
var comment_value = this.state.comment_value
console.log('success!', comment_value)
})
this.props.submit('410c8d94985511e7b308b870f44877c8', '', 'e18e4e557de511e7b664b870f44877c8')
}
and this is my textinput code:
<TextInput
underlineColorAndroid='transparent'
placeholder='Enter your comment here'
multiline numberOfLines={4}
onChangeText={(text) => this.setState({comment_value: text})}
value={this.state.comment_value}
style={styles.textinput}
/>
</View>
<TouchableOpacity onPress={this.addComment.bind(this)}>
<View style={{flex: 1, flexDirection: 'column', backgroundColor: Colors.background, width: 70}}>
<Icon name='direction' type='entypo' color='#000'size={30} style={styles.icon} />
</View>
</TouchableOpacity>
This should definately be working try cleaning up your code like this
contructor(props) {
super(props);
this.state = {
comment_value: '',
}
}
addComment () {
console.log(this.state.comment_value); // should be defined
this.props.submit(this.state.comment_value);
}
render() {
return (
<View>
<TextInput
underlineColorAndroid='transparent'
placeholder='Enter your comment here'
multiline numberOfLines={4}
value={this.state.comment_value}
onChangeText={(text) => this.setState({comment_value: text})}
style={styles.textinput}
/>
<TouchableOpacity onPress={this.addComment.bind(this)}>
<View style={{flex: 1, flexDirection: 'column', backgroundColor: Colors.background, width: 70}}>
<Icon name='direction' type='entypo' color='#000'size={30} style={styles.icon} />
</View>
</TouchableOpacity>
</View>
);
}
EDIT: Based on your complete code sample it seems like you're incorrectly trying to update state by doing multiple this.state = ... which is incorrect, to update state you have to use this.setState({ ... })