How to create outlined (focused) TextInput in React Native? - react-native

Here is my code:
<View style={styles.inputView} >
<TextInput
style={styles.TextInputStyleClass}
placeholder="Email"
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({email:text})}/>
</View>
Here is textinput style
TextInputStyleClass:{
textAlign: 'auto',
height: 50,
borderWidth: 1,
borderColor: '#c2c2c2',
borderRadius: 5 ,
backgroundColor : "#ffffff"
}
I am new to React Native application development and I am trying to textinput outlined focus. But the textinput is not focused with the code which I wrote above. Also I have tried with textinput mode but nothing helped me.
How can I create textInput outlined focus?

try to use component state.
class textInput extends React.Component {
constructor(props) {
super(props);
this.state = { isFocus: false };
}
render() {
return (
<TextInput
onBlur={() => {
this.setState({ isFocus: false });
}}
onFocus={() => {
this.setState({ isFocus: true });
}}
style={this.isFocus ? { borderColor: 'red' } : { borderColor: 'green' }}
/>
);
}
}

you should add the mode='outlined'
<View style={styles.inputView} >
<TextInput
style={styles.TextInputStyleClass}
placeholder="Email"
mode='outlined'
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({email:text})}
/>
</View>

Related

Add text dynamically to TextInput

I would like to add a UnicodeText viewed inside the textInput when I click a button.
I've tried to create a state {text} then add the UnicodeText to the state text.
The text with the added text is properly shown in the console.log(). Not in the textInput.
import { Icon, Input } from "react-native-elements";
var emoji = require("node-emoji");
export default class MainViewMessageInput extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "",
username: "",
visible: false,
showEmoticons: false
};
}
_sendMessage() {
var texte = this.state.text;
this.setState({ text: "" });
console.log(this.state.text);
}
_addEmoji() {
this.state.text = this.state.text + emoji.get("green_heart");
const emojiChar = this.state.text + emoji.get("green_heart");
this.setState({ text: emojiChar });
console.log(this.state.text);
}
render() {
return (
<View style={styles.container}>
<Input
style={{ flex: 1 }}
leftIcon={
<TouchableHighlight
onPress={() => {
this._addEmoji();
}}
style={styles.icon}
>
<Icon size={40} color="#d2d3d5" name="mood" />
</TouchableHighlight>
}
rightIcon={
<Icon
reverse
onPress={() => this.setState({ visible: true })}
color="#00b5ec"
name="send"
size={23}
/>
}
rightIconContainerStyle={{ marginRight: -7 }}
leftIconContainerStyle={{ marginLeft: 0 }}
inputContainerStyle={styles.inputContainer}
inputStyle={styles.input}
placeholder="Write your message ..."
underlineColorAndroid="transparent"
multiline={true}
editable={true}
onChangeText={text => this.setState({ text })}
/>
</View>
);
}
}
Is it possible to do?
you can push textinput into array in runtime so u get textinput dynamically
for input add field value={this.state.text}
reference
remove this.state.text = this.state.text + emoji.get("green_heart"); from _addEmoji()

GS1 barcode scanner reader in react native app

i used a barcode scanner expo library in my react native app but it's not able to scan the GS1 type barcode so which library i used in my app?
Do you mean which library you should use ? If its that and you are not using expo, then https://github.com/react-native-community/react-native-camera this is pretty good and easy to go dependency which you can use to serve your purpose.
class BarScannerView extends Component {
constructor(props) {
super(props);
this.camera = null;
this.barcodeCodes = [];
this.state = {
changeScreen: false,
camera: {
type: RNCamera.Constants.Type.back,
flashMode: RNCamera.Constants.FlashMode.auto,
barcodeFinderVisible: true
}
};
}
onBarCodeRead = (scanResult) => {
if (scanResult.data !== null) {
let bacodeScanResult = scanResult.data
AsyncStorage.setItem('barcodeValue', bacodeScanResult)
return this.props.navigation.navigate('Stock')
}
return;
}
componentDidMount() {
console.log('componentDidMount', this.props)
this.props.navigation.dismiss()
}
componentWillUnmount() {
console.log('componentWillUnmount', this.props)
}
render() {
return (
<View style={styles.container}>
<RNCamera
ref={ref => {
this.camera = ref;
}}
barcodeFinderVisible={this.state.camera.barcodeFinderVisible}
barcodeFinderWidth={280}
barcodeFinderHeight={220}
barcodeFinderBorderColor="white"
barcodeFinderBorderWidth={2}
defaultTouchToFocus
flashMode={this.state.camera.flashMode}
onBarCodeRead={this.onBarCodeRead}
onFocusChanged={() => {}}
onZoomChanged={() => {}}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your camera phone'}
style={styles.preview}
type={this.state.camera.type}
/>
<View style={[styles.overlay, styles.topOverlay]}>
<Text style={styles.scanScreenMessage}>Please scan the barcode.</Text>
</View>
<View style={{position: 'absolute', top: 150, left: '12%' }}>
<View
style={{
width: 300,
height: 300,
backgroundColor: 'transparent',
borderColor: 'white',
borderWidth: 1
}}
>
</View>
</View>
<View style={[styles.overlay, styles.bottomOverlay]}>
<Button
onPress={() => { console.log('scan clicked'); }}
style={styles.enterBarcodeManualButton}
title="Choose Barcode"
/>
</View>
</View>
);
}
}
You can follow this.

KeyboardAvoidingView works on EXPO but not on APK?

I bought this Theme which in Expo works flawlessly, but as soon as I build the APK, the Keyboard will cover the whole screen and wont work as supposed.
I'm using expo for testing and it works just fine.
return (
<SafeAreaView style={styles.container}>
<NavHeader title={thread.name} {...{navigation}} />
<FlatList
inverted
data={messages}
keyExtractor={message => `${message.date}`}
renderItem={({ item }) => (
<Msg message={item} name={item.me ? name : thread.name} picture={thread.picture} />
)}
/>
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"} enabled>
<View style={styles.footer}>
<TextInput
style={styles.input}
placeholder="Write a message"
value={this.state.message}
onChangeText={message => this.setState({ message })}
autoFocus
blurOnSubmit={false}
returnKeyType="send"
onSubmitEditing={this.send}
underlineColorAndroid="transparent"
/>
<TouchableOpacity primary transparent onPress={this.send}>
<Text style={styles.btnText}>Send</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
And the Styles
const styles = StyleSheet.create({
container: {
flex: 1
},
footer: {
borderColor: Theme.palette.lightGray,
borderTopWidth: 1,
paddingLeft: Theme.spacing.small,
paddingRight: Theme.spacing.small,
flexDirection: "row",
alignItems: "center"
},
input: {
height: Theme.typography.regular.lineHeight + (Theme.spacing.base * 2),
flex: 1
},
btnText: {
color: Theme.palette.primary
}
});
I have tried the following plugin
using the enableOnAndroid prop
https://github.com/APSL/react-native-keyboard-aware-scroll-view
with no success.
I have posted here:
https://github.com/APSL/react-native-keyboard-aware-scroll-view/issues/305
and here:
https://github.com/expo/expo/issues/2172
Unfortunately this is a known issue
https://github.com/expo/expo/issues/2172
Depending on the complexity of your screen layout you could add a bottom margin or padding using Keyboard listeners provided by React Native.
import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';
class Example extends Component {
componentDidMount () {
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount () {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow () {
this.setState({
marginBottom: 400
})
}
_keyboardDidHide () {
this.setState({
marginBottom: 0
})
}
render() {
return (
<TextInput
style={{marginBottom: this.state.marginBottom}}
onSubmitEditing={Keyboard.dismiss}
/>
);
}
}

Enable paste and selection within TextInput - React Native

I am trying to implement copy and paste within my TextInput but cant seem to achieve it. I was expecting a tooltip when I long-pressed on my TextInput, however nothing happens.
I know about Clipboard and would know how to implement it, but I cant seem to get the paste option to pop to the user.
Any ideas how I can achieve this?
<TextInput
maxLength={29}
autoCapitalize={'characters'}
numberOfLines={1}
keyboardType={'default'}
underlineColorAndroid='transparent'
autoCorrect={false}
value={IBAN.printFormat(this.state.ibanInput)}
returnKeyType={'next'}
onChangeText={iban => this.verifyIban(iban)}
style={[{ borderWidth: 1, borderRadius: 2, height: '100%', width: '100%', textAlign: 'center', fontSize: width/24 },
]}
/>
Here is the answer if copy/paste does not work for TextInput - React Native
Step 1) In Contructor take testWidth property and assign value as '99%'.
e.g.
this.state = {testWidth: '99%' };
Step 2) In componentDidMount change testWidth value like '100%', do it inside of setTimeout.
e.g.
setTimeout(() => {
this.setState({ testWidth: '100%' })
}, 100)
Step 3) In style attribute of TextInput add dynamic width which we declare in Contractor, e.g
<TextInput style={{ width: this.state.testWidth }} />
Here is the full code: (Just copy and paste in App.js file).
import React, { Component } from 'react';
import { TextInput, View } from 'react-native';
export class App extends Component {
constructor(props) {
super(props);
this.state = { text: '', testWidth: '99%' };
}
componentDidMount() {
setTimeout(() => {
this.setState({ testWidth: '100%' })
}, 100)
}
render() {
return (
<View style={{ marginTop: 50 }}>
<TextInput
style={{ width: this.state.testWidth }}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
</View>
);
}
}
Good Luck
Have a look at this code!: https://github.com/facebook/react-native/issues/18926#issuecomment-490541013
<ScrollView
contentContainerStyle={Styles.contentContainerStyle}
keyboardShouldPersistTaps="handled"
removeClippedSubviews={false}>
<KeyboardAvoidingView>
<Text style={Styles.labelPageTitle}>
{'bla bla bla'}
</Text>
<Text>
{'bla bla bla'}
</Text>
<TextInput
onChangeText={text => this.setState({ title: text })}
style={Styles.textInput}
value={title}
/>
</KeyboardAvoidingView>
use RN-clipboard
const text = await Clipboard.getString()
setCopiedText(text)

How would I grow <TextInput> height upon text wrapping?

I'm trying to create a <TextInput> that can grow in height when the text wraps to the next line, similar to how Slack's message input grows with the text up to a point.
I have the multiline prop set, so it is wrapping but the docs don't seem to mention any event regarding wrapping, and the only thing I can think of is a really hacky strategy to character count to figure out when to increase height of the input. How would I accomplish this?
https://facebook.github.io/react-native/docs/textinput.html
Thanks to react-native doc: https://facebook.github.io/react-native/docs/textinput.html
You can do something like that:
class AutoExpandingTextInput extends React.Component {
state: any;
constructor(props) {
super(props);
this.state = {text: '', height: 0};
}
render() {
return (
<TextInput
{...this.props}
multiline={true}
onChange={(event) => {
this.setState({
text: event.nativeEvent.text,
height: event.nativeEvent.contentSize.height,
});
}}
style={[styles.default, {height: Math.max(35, this.state.height)}]}
value={this.state.text}
/>
);
}
}
0.46.1 or higher: (as explained by Nicolas de Chevigné)
class AutoExpandingTextInput extends React.Component {
constructor(props) {
super(props);
this.state = {text: '', height: 0};
}
render() {
return (
<TextInput
{...this.props}
multiline={true}
onChangeText={(text) => {
this.setState({ text })
}}
onContentSizeChange={(event) => {
this.setState({ height: event.nativeEvent.contentSize.height })
}}
style={[styles.default, {height: Math.max(35, this.state.height)}]}
value={this.state.text}
/>
);
}
}
Since React Native 0.46.1 :
contentSize property was removed from TextInput.onChange event
If you use this version, you can deal with onContentSizeChange prop
From the Jérémy answer, we have
class AutoExpandingTextInput extends React.Component {
constructor(props) {
super(props);
this.state = {
text: '',
height: 0
};
}
render() {
return (
<TextInput
{...this.props}
multiline={true}
onChangeText={(text) => {
this.setState({ text })
}}
onContentSizeChange={(event) => {
this.setState({ height: event.nativeEvent.contentSize.height })
}}
style={[styles.default, {height: Math.max(35, this.state.height)}]}
value={this.state.text}
/>
);
}
}
You should just set a maxHeight property in the style:
<TextInput multiline style={{maxHeight: 80}} />
Demo here: https://snack.expo.io/#yairopro/multiline-input-with-max-height
My answer is to use onContentSizeChange and numberOfLines props in TextInput, of course turn on multiline, this is my solution:
let numOfLinesCompany = 0;
<TextInput
...
multiline={true}
numberOfLines={numOfLinesCompany}
onContentSizeChange={(e) => {
numOfLinesCompany = e.nativeEvent.contentSize.height / 18;
}}
/>
18 is the height of text, propably depends on fontSize
Shoutout to Jérémy Magrin for his answer. This is his code but refactored to use functional components and hooks.
Note, you might need to use minHight instead of height in some RN versions.
const AutoExpandingTextInput = ({...props})=> {
const [text, setText] = useState('');
const [height, setHeight] = useState();
return (
<TextInput
{...props}
multiline={true}
onChangeText={text => {
setText(text);
}}
onContentSizeChange={event => {
setHeight(event.nativeEvent.contentSize.height);
}}
style={[styles.default, {height: height}]}
value={text}
/>
);
}
<TextInput multiline style={{maxHeight: ...}} />
In the hooks.
const [inputHeight, setInputHeight] = React.useState(40);
<TextInput
multiline
style={{ inputHeight }}
onContentSizeChange={(event) => {
setInputHeight(event.nativeEvent.contentSize.height);
}}
/>
What I have done is set View for the Input max height, for example:
messageBox: {
maxHeight: 110,
width: '80%',
borderRadius: 10,
padding: 10,
backgroundColor: Color.White},
and set the Input to multiline:
<View style={[styles.messageBox, styles.managerMsg]}>
<Input
allowFontScaling={false}
name="notes"
blurOnSubmit={false}
onChangeText={notes => console.log(notes)}
returnKeyType="go"
onSubmitEditing={() => Keyboard.dismiss()}
multiline
/>
</View>
This "Input" is just a simple custom component that receives all Props.
You might as well try something like this.
<TextInput style={[styles.inputs,{height: Math.max(35, this.state.height)}]}
placeholder="Write a message..."
multiline={true}
onChangeText={(msg) => this.setState({ text: msg })}
onSubmitEditing={Keyboard.dismiss}
onContentSizeChange = {() => this.scrollView.scrollToEnd({animated:true})}
/>
style.inputs
inputs: {
minHeight:40,
marginLeft: 16,
paddingTop: 10,
overflow:'hidden',
padding: 15,
paddingRight: 25,
borderBottomColor: '#000000',
flex: 1,
position: 'absolute',
width: '100%',
},
When the text grows beyond one line, a scroll view is created within the text input field and scrolls automatically to the bottom. This actually doesn't increase the text input height when the content grows, instead, a scroll view is created within the input field. Serves the purpose.
I'm posting my solution as others didn't work for me(the text input size grew behind the keyboard, and there were text-overflow issues).
Hence, for anyone who faced a similar problem as I did, this would hopefully work for you.
<View style={{flex:1}}>
<TextInput
multiline={true} />
</View>
You can also use onChangeText to set the TextInput height like so.
const textHeight = 19 //fontsize of the text
<TextInput
style={[styles.input,
{height:Math.max(40,inputHeight)}]}
onChangeText= {text => {
const height = text.split("\n").length
setInputHeight(height * textHeight)
}}
multiline
/>
Just use multiline={true} no need to set height. check the following
<SafeAreaView style={{flex:1, backgroundColor:"#F8F8F9"}}>
<ScrollView style={{flex:1}}>
{
this.state.data && <CommentListView data={this.state.data} onReplyClick={this.onReplyClick}/>
}
</ScrollView>
<View style={{bottom:Platform.OS=="ios" ? this.state.keyboardHeight : 0, flexDirection:"row", alignItems:"flex-end", padding:10}}>
<TextInput
multiline={true}
style={{flex:3, backgroundColor:"#EFEFEF", borderRadius:5, padding:10}}
value={this.state.comment}
onChangeText={(text)=> this.setState({comment:text})}
/>
<TouchableOpacity style={{flex:1}} onPress={()=> this.submit()}>
<Text style={{padding:13, color:"#fff", textAlign:"center", fontWeight:"bold", backgroundColor:"#00394D", borderWidth:1, borderColor:"#00FFEE", borderRadius:5, overflow: "hidden"}}>Post</Text>
</TouchableOpacity>
</View>
</SafeAreaView>