Reputation: 723
I'm still new to react native and I have a problem working with picker and text input together.
I get a list of cars and when I select a particular car, in the field below is set the value of km of that selected car.
The problem is that this field needs to be allowed to edit, that is, the user wants to change the kilometers of that car he can.
But at the moment my input field is blocked for editing, I made a gif that shows when I select a car and I try to edit the km and it does not work.
Below my code, I don't know why it is not working on the snack.io so that's why I put it all here:
import * as React from 'react';
import {
Text,
View,
ImageBackground,
Image,
TextInput,
Dimensions,
TouchableOpacity,
Alert,
Button,
Picker,
Animated,
Platform,
TouchableWithoutFeedback,
StyleSheet
} from 'react-native';
import axios from 'axios';
const { width: WIDTH } = Dimensions.get('window')
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
descViatura: '',
descViaturaIOS: 'Select the car',
modalIsVisible: false,
modalAnimatedValue: new Animated.Value(0),
};
}
componentDidMount() {
axios
.get(
`${'http://www.mocky.io/v2/5d304a3c3200005600204352'}`,
{
headers: {
'Content-Type': 'application/json',
},
}
)
.then(jsonResponse => {
this.setState({
viaturas: true,
dataSource: jsonResponse.data['data'],
});
})
.catch(error => console.log(error));
}
onValueChange(value: string, index: string) {
let kms = this.state.dataSource[index].km_actuais
let marcaSelecionada = this.state.dataSource[index].marca
let modeloSelecionado = this.state.dataSource[index].modelo
let matriculaSelecionada = this.state.dataSource[index].matricula
let viaturaSelecionada = marcaSelecionada + ' ' + modeloSelecionado + ' ' + matriculaSelecionada
this.setState({
descViatura: value,
km_actuais: kms,
descViaturaIOS: viaturaSelecionada
});
}
_handlePressOpen = () => {
if (this.state.modalIsVisible) {
return;
}
this.setState({ modalIsVisible: true }, () => {
Animated.timing(this.state.modalAnimatedValue, {
toValue: 1,
duration: 200,
useNativeDriver: true,
}).start();
});
};
_handlePressDone = () => {
Animated.timing(this.state.modalAnimatedValue, {
toValue: 0,
duration: 150,
useNativeDriver: true,
}).start(() => {
this.setState({ modalIsVisible: false });
});
};
render() {
let list_viaturas = this.state.dataSource;
if (typeof (list_viaturas) !== undefined) {
list_viaturas = [list_viaturas][0];
}
let km_selected = typeof (this.state.km_actuais) !== 'undefined' ? this.state.km_actuais : 0
let modalPicker = null
if (Platform.OS === 'ios') {
modalPicker = (
<View style={{
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 45,
marginTop: 30,
width: '90%',
backgroundColor: '#ecf0f1',
borderWidth: 1,
}}>
<TouchableWithoutFeedback onPress={this._handlePressOpen}>
<View
style={{
alignItems: 'center',
width: '100%',
}}>
<Text style={{ paddingLeft: 15, fontSize: 14 }}>{this.state.descViaturaIOS}</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
} else {
modalPicker = (
null
)
}
_maybeRenderModal = () => {
if (!this.state.modalIsVisible) {
return null;
}
const { modalAnimatedValue } = this.state;
const opacity = modalAnimatedValue;
const translateY = modalAnimatedValue.interpolate({
inputRange: [0, 1],
outputRange: [300, 0],
});
return (
<View
style={StyleSheet.absoluteFill}
pointerEvents={this.state.modalIsVisible ? 'auto' : 'none'}>
<TouchableWithoutFeedback onPress={this.props.onCancel}>
<Animated.View style={[styles.overlay, { opacity }]} />
</TouchableWithoutFeedback>
<Animated.View
style={{
width: '100%',
position: 'absolute',
bottom: 0,
left: 0,
transform: [{ translateY }],
}}>
<View style={styles.toolbar}>
<View style={styles.toolbarRight}>
<Button title="OK" onPress={this._handlePressDone} />
</View>
</View>
<Picker
style={{ width: WIDTH, backgroundColor: '#e1e1e1', top: 0 }}
selectedValue={this.state.descViatura}
itemStyle={{
fontSize: 18,
color: '#000',
}}
onValueChange={this.onValueChange.bind(this)}>
{list_viaturas.map((item, key) => {
return (
<Picker.Item
label={item.marca + ' ' + ' ' + item.modelo + ' ' + item.matricula}
value={item.id}
key={key}
/>
);
})}
</Picker>
</Animated.View>
</View>
)
}
return (
<View style={styles.container}>
{modalPicker}
<View style={styles.inputText2}>
<TextInput
style={styles.input}
value={km_selected}
keyboardType={'numeric'}
placeholder={"0"}
placeholderTextColor={'#000'}
underlineColorAndroid='transparent'
/>
</View>
{_maybeRenderModal()}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
padding: 8,
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.65)',
},
toolbar: {
width: '100%',
backgroundColor: '#f1f1f1',
paddingVertical: 5,
paddingHorizontal: 15,
},
toolbarRight: {
alignSelf: 'flex-end',
},
inputText2: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 45,
marginTop: 30,
width: '90%',
backgroundColor: '#ecf0f1',
borderWidth: 1,
},
});
This gif is with accelerated recording, but you can see that I click the button to delete the number and nothing happens.
Upvotes: 1
Views: 1677
Reputation: 595
Change your TextInput with
<TextInput
style={styles.input}
value={km_selected}
keyboardType={'numeric'}
placeholder={"0"}
onChangeText={(text) => { this.setState({ km_selected: text }) }}
placeholderTextColor={'#000'}
underlineColorAndroid='transparent'
/>
Upvotes: 0
Reputation: 5411
I believe the issue is that you are providing a value
on TextInput
.
As you can read here: https://facebook.github.io/react-native/docs/textinput#value
The value to show for the text input. TextInput is a controlled component, which means the native value will be forced to match this value prop if provided. For most uses, this works great, but in some cases this may cause flickering - one common cause is preventing edits by keeping value the same. In addition to simply setting the same value, either set editable={false}, or set/update maxLength to prevent unwanted edits without flicker.
I can't test for you, I'm sorry, but try to set editable={true}
. If it doesn't work, remove value
and use another way through JavaScript to get the value
from Picker to show it there.
Upvotes: 1