I'm working on flatlist with checkbox but could not select multiple checkboxes inside flatlist. Every time only single item is selected. Wanted to add dynamic checkbox according to the list and have to handle all checkbox using one function. I have used the following code but its not working. Any help would be appreciated.
import React, { useState, useEffect } from 'react';
import {
SafeAreaView,
StyleSheet,
Text,
View,
FlatList,
TouchableOpacity,
Image,
ActivityIndicator,
} from 'react-native';
import CheckBox from '#react-native-community/checkbox';
const App = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
getListPhotos();
return () => {
}
}, [])
getListPhotos = () => {
const apiUrl = 'https://jsonplaceholder.typicode.com/photos';
fetch(apiUrl)
.then((res) => res.json())
.then((resJson) => {
setData(resJson);
}).catch((err) => { console.error('Error', err); })
.finally(() => setIsLoading(false))
}
onChangeValue = (item, index) => {
const newData = data.map(newItem => {
if (newItem.id == item.id) {
return {
...newItem,
selected: true,
}
}
return {
...newItem,
selected: false,
}
})
setData(newData);
}
renderItem = ({ item, index }) => {
return (
<View style={styles.item}>
<Image style={styles.image}
source={{ uri: item.url }}
resizeMode='contain'
/>
<View style={styles.wrapText}>
<Text >{item.title}</Text>
<CheckBox
value={item.selected}
style={styles.ckItem}
disabled={false}
onAnimationType='fill'
offAnimationType='fade'
boxType='square'
onValueChange={() => onChangeValue(item, index)}
/>
</View>
</View>
)
}
return (
<SafeAreaView style={styles.container}>
{isLoading ? <ActivityIndicator /> : (<FlatList
style={styles.list}
data={data}
renderItem={renderItem}
//keyExtractor={(item, index) => item.id}
keyExtractor={item => `key-${item.id}`}
/>)}
<View>
<Text style={styles.wrapButton}></Text>
<TouchableOpacity style={styles.button}>
<Text>
Show item you selected
</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
list: {
flex: 1,
padding: 8,
},
wrapButton: {
width: '100%',
justifyContent: 'center',
alignItems: 'center',
},
button: {
padding: 16,
backgroundColor: 'orange',
// justifyContent:'center',
// alignItems:'center',
alignSelf: 'center',
width: '50%'
},
item: {
marginTop: 8,
flexDirection: 'row',
padding: 4,
shadowColor: '#000',
shadowOffset: {
width: 0, height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
image: {
width: 100,
height: 150,
},
wrapText: {
flex: 1,
marginTop: 16,
marginLeft: 8,
},
ckItem: {
width: 20,
height: 20,
marginTop: 5,
},
});
export default App;
onValueChange={newValue => onChangeValue(item, index, newValue)}
onChangeValue = (item, index, newValue) => {
const newData = data.map(newItem => {
if (newItem.id == item.id) {
return {
...newItem,
selected: newValue,
}
}
return newItem
})
setData(newData);
}
You can achieve by using below plugins
https://bestofreactjs.com/repo/tableflip-react-native-select-multiple-react-react-native-awesome-components
https://github.com/vakiller/react-native-flatlist-multiple-choose/blob/master/readme.md
Related
I am not able to push the number index in the array of useState.
Where I am going wrong, do I want to push the index of numbers when I click them?
I am extracting the previous state array and then I push new but nothing happens.
How to push a new element inside useState array React hook? My code doesn't work!!
Please someone check.
Game.js
import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import RandomNumber from "./RandomNumber";
export default function Game(props) {
const [state, setstate] = useState([]);
let randomNumber = Array.from({ length: props.randomNumberCount }).map(
() => 1 + Math.floor(10 * Math.random())
);
let target = randomNumber
.slice(0, props.randomNumberCount - 2)
.reduce((acc, curr) => acc + curr, 0);
const isNumberSelected = (numberIndex) => {
return state.indexOf(numberIndex) >= 0;
};
const selectNumber = (numberIndex) => {
setstate((arr) => [...arr, numberIndex]);
};
return (
<View style={styles.container}>
<Text style={styles.header}>Target Sum Game</Text>
<Text style={styles.target}>{target}</Text>
<View style={styles.randomContainer}>
{randomNumber.map((randomNumber, index) => (
<RandomNumber
key={index}
id={index}
number={randomNumber}
isSelected={isNumberSelected(index)}
onClick={() => selectNumber}
/>
))}
</View>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#ddd",
paddingTop: 30,
},
target: {
fontSize: 30,
backgroundColor: "#aaa",
margin: 50,
marginHorizontal: 70,
textAlign: "center",
},
header: {
fontSize: 35,
backgroundColor: "dodgerblue",
textAlign: "center",
marginHorizontal: 30,
marginTop: 50,
},
randomContainer: {
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-around",
},
});
RandomNumber.js
import React from "react";
import { StyleSheet, Text, TouchableOpacity } from "react-native";
export default function RandomNumber(props) {
const handlePress = () => {
props.onClick(props.id);
};
return (
<TouchableOpacity onPress={handlePress()}>
<Text style={[styles.random, props.isSelected && styles.selected]}>
{props.number}
</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
random: {
backgroundColor: "#999",
width: 100,
marginHorizontal: 35,
marginVertical: 25,
fontSize: 35,
textAlign: "center",
},
selected: {
opacity: 0.3,
},
});
you are not calling the function
onClick={() => selectNumber(index)}
You need to change the onClick prop and pass the randomNumber (or index depending of what you want to do) to the selectNumber function:
// Not sure if you want to pass randonNumber or index but you get the idea
onClick={() => selectNumber(randomNumber)}
<TouchableOpacity onPress={handlePress()}>
should be
<TouchableOpacity onPress={()=>handlePress()}>
and
() => selectNumber
should be
() => selectNumber()
please try it
Might Be This Helpful:
Home.Js
import React, {useState, useEffect} from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import RandomNumber from './RandomNumber';
const Home = props => {
const [state, setstate] = useState([]);
useEffect(() => {
console.log('state', state);
}, [state]);
let randomNumber = Array.from({length: 10}).map(
() => 1 + Math.floor(10 * Math.random()),
);
let target = randomNumber
.slice(0, props.randomNumberCount - 2)
.reduce((acc, curr) => acc + curr, 0);
const isNumberSelected = numberIndex => {
return state.indexOf(numberIndex) >= 0;
};
const selectNumber = numberIndex => {
console.log('numberIndex', numberIndex);
setstate(arr => [...arr, numberIndex]);
};
return (
<View style={styles.container}>
<Text style={styles.header}>Target Sum Game</Text>
<Text style={styles.target}>{target}</Text>
<View style={styles.randomContainer}>
{randomNumber.map((randomNumber, index) => {
return (
<RandomNumber
key={index}
id={index}
number={randomNumber}
isSelected={isNumberSelected(index)}
onClick={() => selectNumber(randomNumber)}
/>
);
})}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ddd',
paddingTop: 30,
},
target: {
fontSize: 30,
backgroundColor: '#aaa',
margin: 50,
marginHorizontal: 70,
textAlign: 'center',
},
header: {
fontSize: 35,
backgroundColor: 'dodgerblue',
textAlign: 'center',
marginHorizontal: 30,
marginTop: 50,
},
randomContainer: {},
});
export default Home;
RandomNumber.js
import React from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
export default function RandomNumber(props) {
const handlePress = () => {
props.onClick(props.id);
};
return (
<View style={{}}>
<TouchableOpacity onPress={() => handlePress()}>
<Text style={[styles.random, props.isSelected && styles.selected]}>
{props.number}
</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
random: {
backgroundColor: '#999',
width: 100,
height: 100,
marginHorizontal: 35,
marginVertical: 25,
fontSize: 35,
textAlign: 'center',
},
selected: {
opacity: 0.3,
},
});
Output Log:
I have an array which displays a list of jobs with the radio button(each).If I click any radio button I want to get its value so far I'm getting an error input must be a function received undefined. how can I achieve something like this in react native?
Code
import React, {useState} from 'react';
import {View, Text, TextInput, Image,Button,Body,Pressable,ScrollView,Switch} from 'react-native';
export default function Home({ navigation}){
let roles = navigation.getParam('roles')
const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
const handleClick = (data, e) => {
alert(e.target.value, data);
}
<View>
{
Object.keys(roles).map((key) => {
return (
<View>
<View style={styles.XYQHC}>
<Text>{roles[key]['name']}</Text>
<Switch
trackColor={{ false: "#767577", true: "#81b0ff" }}
thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
ios_backgroundColor="#3e3e3e"
onValueChange={toggleSwitch}
value={isEnabled}
/>
<input type="radio" name="roles" value={roles[key]['name']} defaultChecked={roles[key]['id'] == 3 ? true : false } onClick={handleClick.bind(this, roles[key]['name'])}/>
</View>
</View>
)
})
}
</View>
};
I had to edit a little bit to make it work and to assume some input data but here is a working example of your code:
import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
function RadioButton({ label, onPress, selected, style }) {
return (
<TouchableOpacity
style={[
{
flexDirection: 'row',
alignItems: 'center',
marginLeft: 12,
marginVertical: 20,
},
style,
]}
onPress={onPress}>
<View
style={{
height: 24,
width: 24,
borderRadius: 12,
borderWidth: 2,
borderColor: '#000',
alignItems: 'center',
justifyContent: 'center',
marginRight: 12,
}}>
{selected ? (
<View
style={{
height: 12,
width: 12,
borderRadius: 6,
backgroundColor: '#000',
}}
/>
) : null}
</View>
<Text>{label}</Text>
</TouchableOpacity>
);
}
export default function Home({ navigation }) {
// let status = navigation.getParam('status');
let status = 2;
// let roles = navigation.getParam('roles');
let roles = [
{
id: 1,
name: 'lawyer',
},
{
id: 2,
name: 'farmer',
},
{
id: 3,
name: 'architect',
},
];
const [isEnabled, setIsEnabled] = useState(false);
const [chosenRole, setChosenRole] = useState(false);
useEffect(() => {
roles.find((role) => {
if (role.id === status) {
setChosenRole(role);
return true;
}
return false;
});
}, []);
const handleClick = (data) => {
console.log(data);
setChosenRole(data);
};
return (
<View style={{ marginTop: 30 }}>
{roles.map((role) => {
return (
<View>
<RadioButton
label={role.name}
selected={role.name === chosenRole.name}
onPress={() => handleClick(role)}
/>
</View>
);
})}
</View>
);
}
I have an issue with React Native Redux where I am calling a Redux action from the onChangeText function from inside a TextField. Normally, an update like this would only cause the TextField itself to update, however the whole page is being re-rendered upon each call of the function.
Here is the code for the TextField. The method in question is this.props.updateURL(value)
<TextField label='Server'
value={this.props.profile.url}
labelFontSize={textFont(16)}
tintColor='#B3B2B6'
autoCapitalize="none"
autoCorrect={false}
returnKeyType={'next'}
blurOnSubmit={false}
autoFocus={!this.props.profile.edited}
style={styles.inputStyle}
selectionColor={CUSRSOR_COLOR}
editable={!this.props.profile.edited}
onChangeText={async value => {
this.props.updateURL(value)
}}
renderAccessory={()=>{
return(<TouchableOpacity onPress={this.handleScanPress} >
<Image source={ImgScan} style={{height: 25, width: 25, overflow:'visible', marginBottom:20, marginRight: 10}}/>
</TouchableOpacity>);
}}
>
</TextField>
This is for the Redux methods mapStateToProps and mapDispatchToProps:
const mapStateToProps = (state) => {
return {
profile : state.profileReducer,
deviceUid: state.GlobalReducer.deviceUid,
locationsList: state.LogsReducer.locationList,
errorList: state.ErrorsReducer.failedList,
watermarkText: state.GlobalReducer.watermarkText,
alertPresent: state.LogsReducer.alertPresent
}
};
const mapDispatchToProps = (dispatch) => {
return {
updateURL : (url) => dispatch(updateURL(url)),
updateUserName : (userName) => dispatch(updateUserName(userName)),
updatePassword : (password) => dispatch(updatePassword(password)),
updateDeviceName : (deviceName) => dispatch(updateDeviceName(deviceName)),
allFieldsEntered : (url,userName,password) => dispatch(allFieldsEntered(url,userName,password)),
loginDevice: (url,userName,password,deviceName,deviceId,navigation,existingUser) => dispatch(callLoginApi(url,userName,password,deviceName,deviceId,navigation,existingUser)),
updateFailureMessage: (message) => dispatch(updateFailureMessage(message)),
showLoader: () => dispatch(showLoader()),
hideLoader: () => dispatch(hideLoader()),
updateRegistrationSuccess: (value) => dispatch(updateRegistrationSuccess(value)),
checkForInternet: () => dispatch(checkConnectivity()),
getProfileDetails: async(isToken) => await dispatch(fetchProfileDetails(isToken)),
updateLocationSwitch: (value) => dispatch(updateLocationStatus(value)),
updateIsEdit: (value) => dispatch(updateIsEdit(value)),
storeRegistrationFlagInAsync: () => dispatch(storeRegistrationFlagInAsync()),
isDeviceConnected: (value) => dispatch(isDeviceConnected(value)),
requestLocationPermissions: () => dispatch(requestLocationPermissions()),
passwordChanged: (value) => dispatch(updateIsPasswordChanged(value)),
isEditPage: (value) => dispatch(isEditPage(value)),
getDeviceName: () => dispatch(getDeviceName()),
shouldEnableLocation: (value) => dispatch(shouldEnableLocation(value)),
fetchLocationList: () => dispatch(fetchLocations()),
syncRecords: (url,userName,password,locationList,deviceId,isFromError,shouldPresentErrorMsg) => dispatch(syncFailedRecords(url,userName,password,locationList,deviceId,isFromError,shouldPresentErrorMsg)),
fetchFailedRecords: (shouldShowLoader) => dispatch(fetchFailedRecords(shouldShowLoader)),
updateDeviceAction: (action,deviceId,url) => dispatch(performDeviceAction(action,deviceId,url)),
callLogoutApi: (userName,password) => dispatch(callLogoutApi(userName,password)),
syncDeviceActions: () => dispatch(syncDeviceActions()),
syncPendingUpdates: (url,userName,password,deviceId) => dispatch(syncPendingUpdates(url,userName,password,deviceId)),
fetchPendingLocationsList: () => dispatch(fetchPendingLocationsList()),
showPasswordChangeAlert: (alertFlag,navigation) => dispatch(handleUIForPasswordChange(alertFlag,navigation)),
}
}
export default connect(mapStateToProps,mapDispatchToProps)(Profile);
Here are the reducers:
const initialState = {
url: '',
userName : '',
password : '',
deviceName : '',
resourceCode : '',
isDeviceConnected : false,
allFieldsFilled: false,
token: '',
gpsTrackingInterval : 5,
apiPostingInterval : 30,
failureMessage : '',
registered : false,
edited: false,
editPage: false,
isConnected: true,
shouldEnableLocation: false,
resourceDesc: '',
adminEmail: '',
companyName: ''
}
const profileReducer = (state=initialState,action) => {
switch (action.type) {
case actionTypes.UPDATE_URL :
return {
...state,
url: action.payload
}
...
}
This is the Redux action:
export const updateURL = (url) => {
return {
type: actionTypes.UPDATE_URL,
payload: url
};
};
Any help would be much appreciated.
import React, { Component } from 'react';
import {
StyleSheet, Text, View, TextInput, TouchableOpacity, Image,
KeyboardAvoidingView, ScrollView, SafeAreaView, Linking
} from 'react-native';
import { COLOR_BLACK, COLOR_GRAY_9, COLOR_TRANSPARENT, COLOR_GRAY_4 } from '../../../constants/colors';
import ImgProntoLogo from '../../../assets/images/pronto-logo.png';
import ImgPasswordVisibleIcon from '../../../assets/images/visibility.png';
import ImgUrl from '../../../assets/images/url.png';
import ImgBarcode from '../../../assets/images/scan-barcode.png';
import ImgUsernameIcon from '../../../assets/images/username.png';
import ImgPasswordIcon from '../../../assets/images/password.png';
import ImgPasswordHide from '../../../assets/images/password-hide.png';
import GlobalStyleSheet from '../../../constants/styles';
import {
PASSWORD, USERNAME, URL_CONNECT
} from '../../../constants/strings';
import { StackActions, NavigationActions } from 'react-navigation';
import Sync from '../../../utils/Syncing';
import { AsyncStorage } from 'react-native';
export default class Configuration extends Component {
constructor(props) {
super(props)
this.handleOpenURL = this.handleOpenURL.bind(this);
this.handleScanPress = this.handleScanPress.bind(this);
}
async componentWillMount() {
this.props.clearConfiguration();
this.props.checkConnectivity();
Linking.addEventListener('url', this.handleOpenURL);
Sync.removeDataFromUserTable();
Sync.removeDataFromCompanyTable();
}
componentDidMount() {
console.log("COMPONENT MOUNTING");
Linking.getInitialURL().then((url) => {
if (url) {
url = url.substring(18);
this.props.updateURL(url);
}
}).catch(err => console.error('An error occurred', err))
}
componentWillReceiveProps(props) {
console.log("WILL RECEIVE")
}
handleOpenURL = (event) => {
this.props.updateURL(event.url.substring(18))
}
copyRights() {
var currentYear = new Date().getFullYear().toString();
return '© '.concat(currentYear).concat(' Pronto Software Limited.All Rights Reserved.');
}
// Connect the device to the pronto connect
async connectDevice() {
this.props.showLoader();
this.props.resetConnectPasswordVisibility();
await this.props.connectDevice(this.props.configuration.url,
this.props.configuration.username, this.props.configuration.password);
let isDeviceConnected = await AsyncStorage.getItem("isConnected");
if (isDeviceConnected === "true") {
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Register' })],
});
this.props.navigation.dispatch(resetAction);
}
this.props.hideLoader();
}
static navigationOptions = {
header: null
}
handleScanPress() {
const action = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Scanner' })],
});
this.props.navigation.push('Scanner');
}
render() {
return (
<SafeAreaView style={GlobalStyleSheet.container}>
<KeyboardAvoidingView style={GlobalStyleSheet.container} >
<View style={styles.headerLogoView}>
<Image source={ImgProntoLogo} style={styles.logo} />
</View>
<ScrollView keyboardShouldPersistTaps="handled" style={styles.scrollViewStyle}>
<View style={{ flex: 1, height: '100%' }}>
<View style={styles.viewContainer}>
<Text style={[GlobalStyleSheet.textHeading4, GlobalStyleSheet.marginTop10,
GlobalStyleSheet.marginBottom10]}>CONFIGURE DEVICE</Text>
<View style={[GlobalStyleSheet.textInputView, GlobalStyleSheet.marginBottom10]}>
<Image style={GlobalStyleSheet.iconInputBar} source={ImgUrl} />
<TextInput
underlineColorAndroid={COLOR_TRANSPARENT}
style={GlobalStyleSheet.textInput}
autoCapitalize='none'
placeholder={URL_CONNECT}
value={this.props.configuration.url}
onChangeText={(value) => { this.props.updateURL(value) }}
editable={!(this.props.configuration.isDeviceConnected)}
/>
<TouchableOpacity style={[GlobalStyleSheet.passwordTouchable]} onPress={this.handleScanPress}>
<Image style={[GlobalStyleSheet.passwordShowHideIcon]} source={ImgBarcode} />
</TouchableOpacity>
</View>
<View style={[GlobalStyleSheet.textInputView, GlobalStyleSheet.marginBottom10]}>
<Image style={GlobalStyleSheet.iconInputBar} source={ImgUsernameIcon} />
<View style={[GlobalStyleSheet.flexRow, { flex: 1 }]}>
<TextInput
placeholder={USERNAME}
underlineColorAndroid={COLOR_TRANSPARENT}
style={GlobalStyleSheet.textInput}
onChangeText={(value) => { this.props.updateUsername(value) }}
editable={!(this.props.configuration.isDeviceConnected)}
/>
</View>
</View>
<View style={[GlobalStyleSheet.textInputView, GlobalStyleSheet.marginBottom10]} >
<Image style={[GlobalStyleSheet.iconInputBar]} source={ImgPasswordIcon} />
<View style={[GlobalStyleSheet.flexRow, { flex: 1 }]}>
<TextInput
placeholder={PASSWORD}
underlineColorAndroid={COLOR_TRANSPARENT}
contextMenuHidden={true}
style={GlobalStyleSheet.textInput}
autoCapitalize='none'
onChangeText={(value) => { this.props.updatePassword(value) }}
editable={!(this.props.configuration.isDeviceConnected)}
secureTextEntry={!(this.props.configuration.passwordVisibility)} />
<TouchableOpacity style={[GlobalStyleSheet.passwordTouchable]}
onPress={() => {
if (!this.props.configuration.isDeviceConnected) {
this.props.togglePasswordVisibility(this.props.configuration.passwordVisibility)
}
}}>
{
this.props.configuration.passwordVisibility ?
(<Image style={[GlobalStyleSheet.passwordShowHideIcon]} source={ImgPasswordVisibleIcon} />) :
(<Image style={[GlobalStyleSheet.passwordShowHideIcon]} source={ImgPasswordHide} />)
}
</TouchableOpacity>
</View>
</View>
{
this.props.configuration.isDeviceConnected ?
(
<TouchableOpacity style={GlobalStyleSheet.touchableBarProcessed} disabled={true} >
<Text style={GlobalStyleSheet.textTouchableBarProcessed}>CONNECTED</Text>
</TouchableOpacity>
) :
(this.props.configuration.url != "" &&
this.props.configuration.username != "" && this.props.configuration.password != "" ?
(
<TouchableOpacity style={[GlobalStyleSheet.touchableBarEnabled]}
onPress={async () => { await this.connectDevice() }}>
<Text style={GlobalStyleSheet.textTouchableBarEnabled}>CONNECT</Text>
</TouchableOpacity>
) :
(
<TouchableOpacity style={[GlobalStyleSheet.touchableBarDisabled]} disabled={true}>
<Text style={[GlobalStyleSheet.textTouchableBarDisabled]}>CONNECT</Text>
</TouchableOpacity>
)
)
}
</View>
</View>
<View style={styles.copyRightsView}>
<Text style={GlobalStyleSheet.copyRightsText}>{this.copyRights()}</Text>
</View>
</ScrollView>
</KeyboardAvoidingView >
</SafeAreaView >
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
height: '100%',
width: '100%',
backgroundColor: COLOR_GRAY_9,
},
headerLogoView: {
height: 50,
backgroundColor: COLOR_GRAY_9,
elevation: 5,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 2,
shadowOffset: { width: 2, height: 2, },
shadowColor: COLOR_BLACK,
shadowOpacity: 0.1,
},
logo: {
height: 40,
width: '80%',
resizeMode: 'contain',
},
viewContainer: {
marginLeft: 15,
marginRight: 15,
paddingBottom: 10
},
copyRightsView: {
alignItems: 'center',
minHeight: 40,
paddingBottom: 5,
},
scrollViewStyle: {
flex: 1,
height: '100%',
paddingTop: 10
},
});
I know how to populate jSON data on FlatList and I have done that , but now here , I am populating data in between button and table data , In componentDidMount i am calling both function , first table create and then JSON call , Table data I am taking from QRCode scan from another screen and taking here .
import React, { Component } from 'react';
import { StyleSheet, View, ActivityIndicator, ScrollView } from 'react-native';
import { Table, Row, Rows } from 'react-native-table-component';
import {Button, Text, DatePicker, Item, Picker, Input,
Textarea,FlatList} from 'native-base';
export default class OpenApplianceIssue extends Component {
constructor(props) {
super(props);
this.state = {
// tableHead: ['Head', 'Head2', 'Head3', 'Head4'],
tableData: [], qrData: '', loading: false, selectedPriority: '',
selectedIssue: '', selectedReason: '', selectedTriedRestart: '',
selectedPowerLED: '', selectedBurning: '', selectedNoise: '',
AbcSdata : null, loading : true,
}
this.setDate = this.setDate.bind(this);
}
setDate(newDate) {
}
_loadInitialState = async () => {
const { navigation } = this.props;
const qdata = navigation.getParam('data', 'NA').split(',');
var len = qdata.length;
const tData = [];
console.log(len);
for(let i=0; i<len; i++)
{
var data = qdata[i].split(':');
const entry = []
entry.push(`${data[0]}`);
entry.push(`${data[1]}`);
tData.push(entry);
}
this.setState({tableData: tData } );
console.log(this.state.tableData);
this.setState({loading: true});
}
componentDidMount() {
this._loadInitialState().done();
// this.createViewGroup();
}
// componentDidMount() {
// this.createViewGroup();
// }
createViewGroup = async () => {
try {
const response = await fetch(
'http://Dsenze/userapi/sensor/viewsensor',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"password": 'admin',
"username": 'admin',
"startlimit":"0",
"valuelimit":"10",
}),
}
);
const responseJson = await response.json();
const { sensorData } = responseJson;
this.setState({
AbcSdata: sensorData,
loading: false,
});
} catch (e) {
console.error(e);
}
};
updateSearch = search => {
this.setState({ search });
};
keyExtractor = ({ id }) => id.toString();
keyExtractor = ({ inventory }) => inventory.toString();
renderItem = ({ item }) => (
<TouchableOpacity
style={styles.item}
activeOpacity={0.4}
onPress={() => {
this.clickedItemText(item);
}}>
<Text style={styles.buttonText}>Id {item.inventory}</Text>
<Text>Inv {item.inventory}</Text>
<Text>Sensor {item.inventory}</Text>
</TouchableOpacity>
);
onClickListener = (viewId) => {
if(viewId == 'tag')
{
this.props.navigation.navigate('AddSensors');
}}
render() {
const state = this.state;
const AbcSdata = this.state;
if(this.state.loading == false) {
return ( <ActivityIndicator size='large' style={{height:80}} /> )
}
else {
return (
<ScrollView style={styles.container}>
<Button full rounded light style={{backgroundColor: 'blue', justifyContent: 'center', alignItems: 'center'}}
onPress={() => this.onClickListener('tag')}>
<Text style={{color: 'white'}}>Add Sensors</Text>
</Button>
<View style={styles.container1}>
{this.state.loading ? (
<ActivityIndicator size="large" />
) :
(
<FlatList
AbcSdata={AbcSdata}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
)}
</View>
<View>
<Text
style={{alignSelf: 'center', fontWeight: 'bold', color: 'black'}} >
Inventory Details
</Text>
<Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff', padding:10,paddingBottom: 10}}>
<Rows data={state.tableData} textStyle={styles.text}/>
</Table>
</View>
</ScrollView>
)
}
}
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 16, paddingTop: 30, backgroundColor: '#fff' },
head: { height: 40, backgroundColor: '#f1f8ff' },
text: { margin: 6 }
});
try this code ..
import React, { Component } from 'react';
import { View, Text, TextInput,
FooterTab,Button,TouchableOpacity, ScrollView, StyleSheet,
ActivityIndicator ,Header,FlatList} from 'react-native';
import {Icon} from 'native-base';
import { Table, Row, Rows } from 'react-native-table-component';
import { createStackNavigator } from 'react-navigation';
import { SearchBar } from 'react-native-elements';
export default class OpenApplianceIssue extends Component {
constructor() {
super();
this.state = {
AbcSdata: null,
loading: true,
search: '',
tableData: [], qrData: '', selectedPriority: '',
selectedIssue: '', selectedReason: '', selectedTriedRestart: '',
selectedPowerLED: '', selectedBurning: '', selectedNoise: '',
};
this.setDate = this.setDate.bind(this);
}
setDate(newDate) {
}
_loadInitialState = async () => {
const { navigation } = this.props;
const qdata = navigation.getParam('data', 'NA').split(',');
var len = qdata.length;
const tData = [];
console.log(len);
for(let i=0; i<len; i++)
{
var data = qdata[i].split(':');
const entry = []
entry.push(`${data[0]}`);
entry.push(`${data[1]}`);
tData.push(entry);
}
this.setState({tableData: tData } );
console.log(this.state.tableData);
this.setState({loading: true});
}
componentDidMount() {
this._loadInitialState().done();
this.createViewGroup();
}
createViewGroup = async () => {
try {
const response = await fetch(
'http:Dsenze/userapi/sensor/viewsensor',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"password": 'admin',
"username": 'admin',
"startlimit":"0",
"valuelimit":"10",
}),
}
);
const responseJson = await response.json();
const { sensorData } = responseJson;
this.setState({
AbcSdata: sensorData,
loading: false,
});
} catch (e) {
console.error(e);
}
};
updateSearch = search => {
this.setState({ search });
};
keyExtractor = ({ id }) => id.toString();
keyExtractor = ({ inventory }) => inventory.toString();
renderItem = ({ item }) => (
<TouchableOpacity
style={styles.item}
activeOpacity={0.4}
onPress={() => {
this.clickedItemText(item);
}}>
<Text style={styles.buttonText}>Id {item.id}</Text>
<Text>Hospital Name {item.inventory}</Text>
<Text>User {item.inventory}</Text>
<Text>Date {item.inventory}</Text>
</TouchableOpacity>
);
onClickListener = (viewId) => {
if(viewId == 'tag')
{
this.props.navigation.navigate('AddSensors');
}}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "86%",
backgroundColor: "#CED0CE",
}}
/>
);
};
render() {
const { loading, AbcSdata } = this.state;
const state = this.state;
return (
<ScrollView>
<View style={styles.container1}>
<TouchableOpacity full rounded light style={{backgroundColor: 'blue', justifyContent: 'center', alignItems: 'center'}}
onPress={() => this.onClickListener('tag')}>
<Text style={{color: 'white'}}>Add Sensors</Text>
</TouchableOpacity>
</View>
<View style={styles.container1}>
{this.state.loading ? (
<ActivityIndicator size="large" />
) :
(
<FlatList
data={AbcSdata}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
ItemSeparatorComponent={this.renderSeparator}
/>
)}
</View>
<View>
<Text
style={{alignSelf: 'center', fontWeight: 'bold', color: 'black'}} >
Inventory Details
</Text>
<Table borderStyle={{borderWidth: 2, borderColor: '#c8e1ff', padding:10,paddingBottom: 10}}>
<Rows data={state.tableData} textStyle={styles.text}/>
</Table>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create(
{
container1:
{
flex: 1,
alignItems: 'stretch',
fontFamily: "vincHand",
color: 'blue'
},
header_footer_style:{
width: '100%',
height: 44,
backgroundColor: '#4169E1',
alignItems: 'center',
justifyContent: 'center',
color:'#ffffff',
},
Progressbar:{
justifyContent: 'center',
alignItems: 'center',
color: 'blue',
},
ListContainer :{
borderColor: '#48BBEC',
backgroundColor: '#000000',
color:'red',
alignSelf: 'stretch' ,
},
container2:
{
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
paddingHorizontal: 15
},
inputBox:{
width:300,
borderColor: '#48BBEC',
backgroundColor: '#F8F8FF',
borderRadius:25,
paddingHorizontal:16,
fontSize:16,
color:'#000000',
marginVertical:10,
},
button:{
width:300,
backgroundColor:'#4169E1',
borderRadius:25,
marginVertical:10,
paddingVertical:16
},
buttonText:{
fontSize:16,
fontWeight:'500',
color:'#ffffff',
textAlign:'center'
},
textStyle:{
fontSize:16,
fontWeight:'500',
color:'#ffffff',
textAlign:'center'
},
item:
{
padding: 15
},
text:
{
fontSize: 18
},
button:{
width:300,
backgroundColor:'#4169E1',
borderRadius:25,
marginVertical:10,
paddingVertical:16
},
buttonText:{
fontSize:16,
fontWeight:'500',
color:'red',
textAlign:'center'
},
separator:
{
height: 2,
backgroundColor: 'rgba(0,0,0,0.5)'
},
container: { flex: 1, padding: 16, paddingTop: 30, backgroundColor: '#fff' },
head: { height: 40, backgroundColor: '#f1f8ff' },
text: { margin: 6 }
});
In your FlatList component you are setting AbcSdata={AbcSdata}, while you should be setting the data prop:
<FlatList
data={AbcSdata}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
It could be because _loadInitialState in your componentDidMount is an async call and table is getting rendered initially with no data. You could try passing in some prop to refresh once you have data. Also, in the code you put here, all calls to createViewGroup() are commented out but the definition is still there. Not a big problem but still very confusing for someone looking into your code.
I am creating a Taxi Application just like Uber where user enters two locations in given inputs (Pickup and Dropoff), I done with the PickUp when User enters a location it shows the googleautocomplete listview for location and can select the pickup location, but I am stuch with the Dropoff when I write something in the second input it changes the first too or when I click the clear icon it clears text from both inputs. So what do I have to do to solve this problem kindly help please Thanks.
AutoCompeleteInputs.js
import React from 'react';
import { TextInput, View, StyleSheet, Animated, TouchableOpacity } from "react-native";
import AutoCompleteListView from "./AutoCompleteListView";
import Events from "react-native-simple-events";
import debounce from '../utils/debounce'
import fetch from 'react-native-cancelable-fetch';
import MaterialIcons from "react-native-vector-icons/MaterialIcons";
const AUTOCOMPLETE_URL = "https://maps.googleapis.com/maps/api/place/autocomplete/json";
const REVRSE_GEO_CODE_URL = "https://maps.googleapis.com/maps/api/geocode/json";
export default class AutoCompleteInput extends React.Component {
static defaultProps = {
language: 'en'
};
constructor(props) {
super(props);
}
componentWillUnmount() {
this._abortRequest();
}
state = {
predictions: [],
loading: false,
inFocus: false,
};
_abortRequest = () => {
fetch.abort(this);
};
fetchAddressForLocation = (location) => {
this.setState({ loading: true, predictions: [] });
let { latitude, longitude } = location;
fetch(`${REVRSE_GEO_CODE_URL}?key=${API_KEY}&latlng=${latitude},${longitude}`, null, this)
.then(res => res.json())
.then(data => {
this.setState({ loading: false });
let { results } = data;
if (results.length > 0) {
let { formatted_address } = results[0];
this.setState({ text: formatted_address });
}
});
}
_request = (text) => {
this._abortRequest();
if (text.length >= 3) {
fetch(`${AUTOCOMPLETE_URL}?input=${encodeURIComponent(text)}&key=${API_KEY}&language=${this.props.language}`, null, this)
.then(res => res.json())
.then(data => {
let { predictions } = data;
this.setState({ predictions });
});
} else {
this.setState({ predictions: [] });
}
}
_onChangeText = (text) => {
this._request(text);
this.setState({ text });
}
_onFocus = () => {
this._abortRequest();
this.setState({ loading: false, inFocus: true });
Events.trigger('InputFocus');
}
_onBlur = () => {
this.setState({ inFocus: false });
Events.trigger('InputBlur');
}
blur = () => {
this._input.blur();
}
_onPressClear = () => {
this.setState({ text: '', predictions: [] });
}
_getClearButton = () => {
return this.state.inFocus ?
(<TouchableOpacity style={styles.btn} onPress={this._onPressClear}>
<MaterialIcons name={'clear'} size={20} />
</TouchableOpacity>) : null;
}
getAddress = () => {
return this.state.loading ? '' : this.state.text;
}
render() {
return (
<Animated.View style={this.props.style}>
<View style={{ flexDirection: 'column' }}>
<View
style={styles.textInputPickupContainer}
elevation={5}>
<TextInput
ref={input => this._input = input}
value={this.state.loading ? 'Loading...' : this.state.text}
style={styles.textInput}
underlineColorAndroid={'transparent'}
placeholder={'Pickup'}
onFocus={this._onFocus}
onBlur={this._onBlur}
onChangeText={this._onChangeText}
outlineProvider='bounds'
autoCorrect={false}
spellCheck={false} />
{this._getClearButton()}
</View>
<View
style={styles.textInputDropoffContainer}
elevation={5}>
<TextInput
ref={input => this._input = input}
value={this.state.loading ? 'Loading...' : this.state.dropOff}
style={styles.textInput}
underlineColorAndroid={'transparent'}
placeholder={'Dropoff'}
onFocus={this._onFocus}
onBlur={this._onBlur}
onChangeText={(text) => this.setState({dropOff: text})}
outlineProvider='bounds'
autoCorrect={false}
spellCheck={false} />
{this._getClearButton()}
</View>
</View>
<View style={styles.listViewContainer}>
<AutoCompleteListView
predictions={this.state.predictions} />
</View>
</Animated.View>
);
}
}
const styles = StyleSheet.create({
textInputPickupContainer: {
flexDirection: 'row',
height: 40,
zIndex: 10,
paddingLeft: 10,
borderRadius: 5,
backgroundColor: 'white',
shadowOffset: {
width: 0,
height: 2
},
shadowRadius: 2,
alignItems: 'center'
},
textInputDropoffContainer: {
flexDirection: 'row',
height: 40,
zIndex: 10,
paddingLeft: 10,
marginTop: 10,
borderRadius: 5,
backgroundColor: 'white',
shadowOffset: {
width: 0,
height: 2
},
shadowRadius: 2,
alignItems: 'center'
},
textInput: {
flex: 1,
fontSize: 17,
color: '#404752'
},
btn: {
width: 30,
height: 30,
padding: 5,
justifyContent: 'center',
alignItems: 'center'
},
listViewContainer: {
paddingLeft: 3,
paddingRight: 3,
paddingBottom: 3
},
});
SearchRoute.js(Main)
return (
<View style={styles.container}>
<MapView
ref={(mapView) => this._map = mapView}
style={styles.mapView}
region={this.state.region}
showsMyLocationButton={true}
showsUserLocation={false}
onPress={({ nativeEvent }) => this._setRegion(nativeEvent.coordinate)}
onRegionChange={this._onMapRegionChange}
onRegionChangeComplete={this._onMapRegionChangeComplete}
/>
<Entypo name={'location-pin'} size={30}
color={this.props.markerColor}
style={{ backgroundColor: 'transparent' }} />
<View style={styles.fullWidthContainer}>
<AutoCompleteInput
ref={input => this._input = input}
apiKey={API_KEY}
style={[styles.input, { transform: [{ scale: inputScale }] }]}
debounceDuration={this.props.debounceDuration}
/>
</View>
The error is that you are assigning the same value to both TextInputs, so if you change one, the other TextInput will change too to the same value.
On your AutoCompeleteInputs.js change dropOff TextInput's value to
<TextInput
...
value={this.state.loading ? 'Loading...' : this.state.dropOff}
...
/>
So when you change dropOff value, the pickUp point will be the same you entered before, and if you clear one the other will not change.
Also change dropOff onChangeText={this._onChangeText} to onChangeText={(text) => this.setState({dropOff: text}) to ensure that you are storing the correct value.