How do you get nativeID for react-native InputAccessoryView - react-native

I am following the documentation on InputAccessoryView here: https://facebook.github.io/react-native/blog/2018/03/22/building-input-accessory-view-for-react-native.html
with code:
export default class Debug extends Component {
constructor(props) {
super(props);
this.state = {text: 'Hello world from debug'};
}
render() {
const inputAccessoryViewID = "uniqueID";
const accesory = (
<InputAccessoryView nativeID={inputAccessoryViewID}>
<Button
onPress={() => this.setState({text: 'You didnt enter the magic word'})}
title="Reset Text"
/>
</InputAccessoryView>
)
return (
<View>
<ScrollView keyboardDismissMode="interactive">
<TextInput
style={{
padding: 10,
paddingTop: 50,
}}
inputAccessoryViewID={inputAccessoryViewID}
onChangeText={text => this.setState({text})}
value={this.state.text}
/>
</ScrollView>
{accesory}
</View>
);
}
}
But the docs do not explain where I can get this id uniqueID. Is it something I can find in xcode?

InputAccessoryView is expecting a unique id for nativeID property to match with a TextInput that has the same unique id set on inputAccessoryViewID property. This way it knows to activate on that input. This way you can have different InputAccessoryViews for different TextInputs.
nativeID
An ID which is used to associate this InputAccessoryView to specified
TextInput(s).
So that uniqueID is some string that is unique which you can set to anything yourself to match with the TextInput.

Related

Get user input from input field in react similar to getElementById in react native using props

I am doing a loan calculation app and i run into the trouble since i am new to react native and previously i have been manipulating the DOM using querySelector or getElementById functions. However this does not work in react, and i am using state to store the value from the user, but i just can't seem to get it right, What am i doing wrong?
I've inserted the calculation element that is later rendered in app.js. All elements are showing up with no error, but the problem is to get user input data and then be able to use that data and do calculations.
Here is my Class
class LanKalkylElement extends React.Component {
constructor(props) {
super(props);
this.state = {
loanAmount: 20000,
loanInterest: 2.5,
loanYear: 10,
};
}
changeAmount(loanAmount) {
this.setState(() => {
return {
loanAmount: parseFloat(loanAmount),
};
});
}
changeInterest(loanInterest) {
this.setState(() => {
return {
loanInterest: parseFloat(loanInterest),
};
});
}
changeYear(loanYear) {
this.setState(() => {
return {
loanYear: parseFloat(loanYear),
};
});
}
calcButton() {
Alert.alert(this.props.loanAmount);
}
buttonHomeFunc() {
this.props.navigation.navigate('Start');
}
render() {
const {loanAmount, loanInterest, loanYear} = this.state;
return(
<View style={styles.contentStyle}>
<Text style={styles.text}> Lånebelopp </Text>
<TextInput style={styles.numericInput}
onBlur={Keyboard.dismiss}
keyboardType={'numeric'}
value={loanAmount}
onValueChange={this.changeAmount.bind(this)} />
<Text style={styles.text}> Ränta </Text>
<TextInput style={styles.numericInput}
onBlur={Keyboard.dismiss}
keyboardType={'numeric'}
value={loanInterest}
onValueChange={this.changeInterest.bind(this)} />
<Text style={styles.text}> Antal år: {String(loanYear)}</Text>
<Slider step={1}
maximumValue={15}
value={loanYear}
onValueChange={this.changeYear.bind(this)} />
<Button title='Kalkylera' onPress={() => this.calcButton()}/>
<Text style={styles.textResult}>Total summa att återbetala:</Text>
<Text style={styles.textResult}>varav räntekostnad:</Text>
<Button title='Tillbaka' onPress={() => this.buttonHomeFunc()}/>
</View>
)
}
}
export default withNavigation(LanKalkylElement);
When a user changes a value in a text input, onValueChange is called. You have bound this prop to functions that modify the state for this component.
This means the value in the text input will always match the value in the state. Therefore, if you need to access the value in a text input you would simply retrieve it from the state, like this:
const loanAmount = this.state.loanAmount;
doSomethingWithLoanAmount(loanAmount);

How to update value inside object from inputText

Sorry guys i'am still learning react native and i want update value of each qty(quantity) item from input, so i have this state,
this.state={
selectedObject={
otherAttributes:'',
items:[
{name:'a',qty:''},
{name:'b',qty:''},
],
},
}
then i have this function to render the TextInput,
renderPage(){
return this.state.selectedObject.items.map(item ,i)=>
<View style={{margin:15}}>
<Text>Name: {item.name}</Text>
<TextInput style={styles.input} keyboardType='numeric' maxLength={10}
value={?}
onChangeText={?}
}}/>
</View>
)
}
and i dont know what to do inside the value and onchangeText,
This is what i tried, in the TextInput
renderPage(){
const itemqty = this.state.selectedObject.items;
return itemqty.map((item,i)=>
<View style={{margin:15}}>
<Text>Name: {item.name}</Text>
<TextInput style={styles.input} keyboardType='numeric'
value={itemqty[i].qty}
onChangeText={(qty)=>{
this.setState({items[i].qty: qty});
}}/>
</View>
)
}
after trying this i'am aware that value can't have '[i]' aswell as in the setState. Because i was trying so that the value qty will go to the respected items qty as well when setState it.
So what i expect is i can change the value of the quantity of the items from the input that are available in this case there are 2, but later on it can be 3,4,5,6 items with qty in each one and set it to the respected state.
Thank you
You have to pass the modified state properties to setState.
PS: I had to update in order to reflect Junius L. comment about not changing component state.
renderPage(){
const itemqty = this.state.selectedObject.items;
return itemqty.map((item,i)=>
<View style={{margin:15}}>
<Text>Name: {item.name}</Text>
<TextInput style={styles.input} keyboardType='numeric'
value={item.qty}
onChangeText={(qty)=>{
let newSelectedObject = {...this.state.selectedObject};
newSelectedObject.items = [...newSelectedObject.items];
newSelectedObject.items[i] = {...newSelectedObject.items[i], qty};
this.setState({selectedObject: newSelectedObject});
}}/>
</View>
)
}
Also, selectedObject is a state property. So the correct is
this.state={
selectedObject:{
otherAttributes:'',
items:[
{name:'a',qty:''},
{name:'b',qty:''},
],
},
}
Try to avoid state mutation, by not updating the array directly.
hanldeChange = (value, index) => {
const items = [
...this.state.selectedObject.items.slice(0, index),
Object.assign({}, this.state.selectedObject.items[index], { qty: value }),
...this.state.selectedObject.items.slice(index + 1),
];
this.setState(prevState => ({
selectedObject: {
...prevState.selectedObject,
items: items,
},
}));
};
In your input do
<TextInput
style={styles.input}
keyboardType="numeric"
value={this.state.selectedObject.items[i].qty}
onChangeText={qty => this.hanldeChange(qty, i)}
/>

how to remove underline in react native material text field

I'm using react native text field component how can i remove bottom underline in textfield
this is my code
i followed this link: https://github.com/n4kz/react-native-material-textfield
constructor(props) {
super(props);
this.state = {
userName:'',
password:''
}
}
componentWillMount() {
}
componentDidMount(){
}
render() {
//let { userName } = this.state;
let { password } = this.state;
return (
<View style={{flex:1,justifyContent:'center'}}>
<View style={{flex:0.2,justifyContent:'center',flexDirection:'row'}}>
<View style={{flex:12}}></View>
<View style={{flex:76,borderWidth:1,borderColor:'black',borderRadius:5,marginBottom:13.7}}>
<TextField style={{ color: 'black',borderColor:'transparent'}}
label='Phone number'
textColor={'black'}
value={this.state.userName}
labelHeight={40}
labelPadding={8}
padding={10}
Bottom padding= {10}
Top padding={4}
//width={50}
//borderColor={'black'}
// textFocusColor={'orange'}
//underlineColorAndroid='transparent'
baseColor={"black"}
labelHeight={32}
blurOnSubmit={true}
//characterRestriction={10}
onChangeText={(data) => this.setState({ userName: data })}
/>
</View>
)
}
You can try underlineColorAndroid='rgba(0,0,0,0)'
Hope it helps
Other TextInput properties will also work
Ref: https://github.com/n4kz/react-native-material-textfield
React native material text field component (<TextField />) can also use all of the properties from text input component (<TextInput />). So, you can remove the underline border using underlineColorAndroid props. Set this prop to be transparent.
<TextField underlineColorAndroid="transparent" />
Try this: lineWidth={0} if you want to hide the default underline and if you want to hide the line after which appears after click try this: activeLineWidth={0}.
Fine, after using this library I end up with this solution:
You can use one of the props of react-native-material-textfield activeLineWidth with 0 as an argument.
underlineColor="transparent"

KeyboardAvoidingView - pushing up content

I am trying to use KeyboardAvoidingView (also tried a few alternatives) but it either shows the keyboard over the input field or adds a huge amount of padding between the keyboard and the input field. When I stripe the page of any other content it fairs a bit better and only adds a bit of padding between the input field and the keyboard.
Demo of the issue:
http://i.imgur.com/qoYgJpC.gifv
<KeyboardAvoidingView behavior={'position'}>
{this.state.story.image_key ?
<View style={{flex: 1}}>
<Image style={styles.storyBackgroundImage} source={{uri: this.state.story.image_url}} />
<VibrancyView
style={styles.absolute}
blurType="light"
blurAmount={25}
/>
<Image style={styles.storyImage} source={{uri: this.state.story.image_url}} />
</View>
: null
}
<View style={styles.storyContainer}>
<Text style={styles.storyTitle}>{this.state.story.title}</Text>
<Text style={styles.chapterHeader} onPress={() => navigate('User', { id: this.state.story.author.id, name: this.state.story.author.name })}>Chapter 1 by {this.state.story.author.name}</Text>
<Text style={styles.storyText}>{this.state.story.content}</Text>
{this.state.story.chapters.map(function(chapter, i) {
return <ChapterComponent chapter={chapter} key={i} navigation={() => navigate('User', { id: chapter.author.id, name: chapter.author.name })}></ChapterComponent>
})}
<WritingComponent></WritingComponent>
</View>
</KeyboardAvoidingView>
WritingComponent
import React from 'react';
import {
AppRegistry,
TextInput
} from 'react-native';
export default class WritingComponent extends React.Component {
constructor(props) {
super(props);
this.state = { text: '' };
}
render() {
return (
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
multiline={true}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
)
}
}
AppRegistry.registerComponent('WritingComponent', () => WritingComponent);
Link to code
I think the problem is the scroll view, <ScrollView style={{flex: 1}}> should be contained within your KeyboardAvoidingView Since you want this scrolling container also be resized when keyboard comes up...
set keyboardVerticalOffset="80" along with keyboardAvoidingView.
Increase/decrease 80 according to the width of your component

React Native clear text multiple TextInput boxes

I found example code on a facebook React Native page which shows how to use setNativeProp to clear text on a click but I can't see how to do it with multiple text boxes. Here is the code:
var App = React.createClass({
clearText() {
this._textInput.setNativeProps({text: ''});
},
render() {
return (
<View style={styles.container}>
<TextInput ref={component => this._textInput = component}
style={styles.textInput} />
<TouchableOpacity onPress={this.clearText}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
});
The ref seems to be fixed in the function so will always target the same TextInput box. How can I alter the function to target any TextInput box I indicate?
This should work. Notice that the ref on the TextInput needs to be the one you call from the clearText functino.
var App = React.createClass({
clearText(fieldName) {
this.refs[fieldName].setNativeProps({text: ''});
},
render() {
return (
<View style={styles.container}>
<TextInput ref={'textInput1'} style={styles.textInput} />
<TouchableOpacity onPress={() => this.clearText('textInput1')}>
<Text>Clear text</Text>
</TouchableOpacity>
<TextInput ref={'textInput2'} style={styles.textInput} />
<TouchableOpacity onPress={() => this.clearText('textInput2')}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
});
Updated my answer to clear different fields.
You can also use something like this to clear the text of TextInput.
clearText(fieldName) {
this.refs[fieldName].clear(0);
},