Can't get TextInput value in react native - react-native

Hi friends I hope you are doing very well ^^
I am struggling to get a TextInput value when a user enters it in a simple basic form I've created, here is the field :
<TextInput placeholder='latitude' name='lat'/>
<Button style={styles.signIn}
title="Show my entered text"
onPress={() => {
alert(this.state.lat)}}
/>
I tried so many methods to get the value of this field but unfortunately none works.. I am new to react native so I really don't know how can this be done properly (is there any variable I need to define) because in javascript I used to get it only by the GetElementById quite simple right XD
I tried creating a variable exactly bellow the imports like this :
value={this.state.lat}
So I can get the above textInput actual value entered by the user but it isn't working at all and my alert function is not returning anything (I actually don't know if alert() is a react native integrated function or I need to define it from scratch :/), please help I am really lost I tried many solutions on the web but nothing resolves my problem. Thanks in advance

Try this sample code
class Example extends React.Component {
state = { lat: "" };
render() {
return (
<View>
<TextInput
placeholder="latitude"
name="lat"
value={this.state.lat}
onChangeText={(text) => this.setState({ lat: text })}
/>
<Button
style={styles.signIn}
title="Show my entered text"
onPress={() => {
alert(this.state.lat);
}}
/>
</View>
);
}
}

Related

Using react-native-dialog, how to get Dialog.Input content?

<Dialog.Container visible={this.state.dialogSendEmailVisible}>
<Dialog.Title>Password Recovery</Dialog.Title>
<Dialog.Input label="Email"></Dialog.Input>
<Dialog.Button label="OK" onPress={this.handleSendEmail} />
</Dialog.Container>
I have this simple dialog, this is being used for password recovery purposes. I am not a FE developer, and I am not finding how can I pass the value typed on Email field to handleSendEmail function. Github and npm pages do not have any example.
Github page: https://github.com/mmazzarolo/react-native-dialog
PS: This can be a very react native basic feature, but I am not findindg a way...
Assuming that the Dialog Inputs/Button extend React Native's own - then you can call:
onSubmitEditing and onChangeText
From the docs:
onSubmitEditing
Callback that is called when the text input's submit button is
pressed. Invalid if multiline={true} is specified.
TYPE REQUIRED
function No
And
onChangeText
Callback that is called when the text input's text changes. Changed
text is passed as an argument to the callback handler.
TYPE REQUIRED
function No
It means something like below:
<Dialog.Input label="Email"
onChangeText={email => this.setState({email})}
value={this.state.email}
onSubmitEditing={
(event) => this.doSomethingWithSubmit(event)
}
>
</Dialog.Input>
UPDATE
So I have tested this, and it works as below - side note - I'm using Typescript so just remove the types ( : string) etc:
In Render
return (
<View>
<View>
<Button onPress={this.showDialog}>
<Text>Show Dialog</Text>
</Button>
<Dialog.Container visible={true}>
<Dialog.Title>Password Recovery</Dialog.Title>
<Dialog.Input label="Email" onChangeText={(email : string) => this.handleEmail(email)}
></Dialog.Input>
<Dialog.Button label="OK" onPress={this.handleSendEmail} />
</Dialog.Container>
</View>
</View>
)
handleEmail:
private handleEmail = (email : string) => {
console.log("email");
console.log(email);
}
Result:
Further
As a side note of this project, I noticed when I used Live reload - that the Dialog was never re-rendered rather, rendered on top of the old Dialog. I would take this into consideration. Perhaps it was my environment, but everything else worked fine.

react-native-keyboard-spacer how to use onToggle

I'm using react-native-keyboard-spacer.
I want to implement the feature of automatically popping up the keyboard.
The documentation says onToggle method is called when when keyboard toggles. Two parameters passed through, keyboardState (boolean, true if keyboard shown) and keyboardSpace (height occupied by keyboard)
Can anyone show me an example of how to accomplish this?
onToggle() is only called after the keyboard is toggled. To achieve the functionality you desire, just use the built in method in TextInput to focus an input when a component finishes mounting:
componentDidMount() {
this._myTextInput.focus();
}
render() {
return (
<TextInput
style={{height: 40}}
ref={component => this._myTextInput = component}
/>
);
}
onToggle get's called when the keyboard is either shown or hidden. If you want to pop up the keyboard without the user clicking anything, then you would need to focus() on a textInput.
handleOnToggle(keyboardState, keyboardSpace) {
// Do whatever you want with keyboardState
}
render() {
return <View>
<KeyboardSpacer onToggle={this.handleOnToggle} />
</View>
}

if...else condition in React Native

i am new to react native. In my application i am stuck with if..else condition in which i am displaying views based on a condition. Here is the code.
if ({ this.state.isSignUp }) {
<Text> Sign Up </Text>
} else {
<Text> Forgot Password </Text>
}
In my login page i have links for Forgot password and Sign Up pages for which i am showing a Modal page based on isSignUp bool value. I am jus trying to display a text in the Modal page based on the condition, but i am stuck with the below error. Can anyone tell me if i am doing this in the right way. Any help is appreciated. Thank you.
For conditional rendering i would recommend to create a new function. Inside a function you can use if/else like normal. e.g
renderConditionalText() {
if (this.state.isSignUp) {
return <Text> Sign Up </Text>;
}
return <Text> Forgot Password </Text>;
}
Try something like this.
let text;
if (this.state.isSignUp) {
text = <Text> Sign Up </Text>
} else {
text = <Text> Forgot Password </Text>
}
return text;
There is no need to a function in JSX to use conditions.
You can use Inline If with Logical && Operator
It also called ternary operator. For further info please see
Example from React Doc;
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
--
It can also be used for larger expressions although it is less obvious what’s going on:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}

Opening context menu on long press in React Native

I'd like to have a context menu triggered on long press different places using React Native.
I.e. in a dialer like the default dailer. You can long-click on any contact and get a 'copy number' menu. And also you can long-click on the name of the person once you've opened their 'contact card'.
The straight-forward way needs a lot of copy-pasted boilerplate, both components and handlers.
Is there a better pattern for doing this?
All Touchable components (TouchableWithoutFeedback, TouchableOpacity etc.) has a property called onLongPress. You can use this prop to listen for long presses and then show the context menu.
To eliminate code mess and doing lots of copy paste you can separate your context menu as a different component and call it when the long press happen. You can also use an ActionSheet library to show the desired options. React native has a native API for iOS called ActionSheetIOS. If you get a little bit more experience in react and react-native you can create a better logic for this but I'm going to try to give you an example below.
// file/that/contains/globally/used/functions.js
const openContextMenu = (event, user, callback) => {
ActionSheetIOS.showActionSheetWithOptions({
options: ['Copy Username', 'Call User', 'Add to favorites', 'Cancel'],
cancelButtonIndex: [3],
title: 'Hey',
message : 'What do you want to do now?'
}, (buttonIndexThatSelected) => {
// Do something with result
if(callback && typeof callback === 'function') callback();
});
};
export openContextMenu;
import { openContextMenu } from './file/that/contains/globally/used/functions';
export default class UserCard extends React.Component {
render() {
const { userObject } = this.props;
return(
<TouchableWithoutFeedback onLongPress={(event) => openContextMenu(event, userObject, () => console.log('Done')}>
<TouchableWithoutFeedback onLongPress={(event) => openContextMenu(event, userObject, () => console.log('Done'))}>
<Text>{userObject.name}</Text>
<Image source={{uri: userObject.profilePic }} />
</TouchableWithoutFeedback>
</TouchableWithoutFeedback>
);
}
}
Similarly as the previous answer combine onLongPress with imperative control for popup menu - something like
<TouchableWithoutFeedback onLongPress={()=>this.menu.open()}>
<View style={styles.card}>
<Text>My first contact name</Text>
<Menu ref={c => (this.menu = c)}>
<MenuTrigger text="..." />
<MenuOptions>
// ...
</MenuOptions>
</Menu>
</View>
</TouchableWithoutFeedback>
When it comes to a lot of boilerplate - in React you can do your own components that you can reuse everywhere thus reducing boilerplate (and copy&paste)
See full example on https://snack.expo.io/rJ5LBM-TZ

How can I delete a single item from a list in React Native?

So that's what my render list looks like:
renderEvent(){
return this.props.eventList.map(listedEvent=>
<CardSection key={listedEvent._id}>
<EventListItem>
{listedEvent.eventName}
</EventListItem>
<DeleteButton
onClick={this.deleteEvent(listedEvent._id)}
key={listedEvent._id}
/>
</CardSection>
);
}
and here the rendering of the whole list
render(){
if (this.props.eventList !== undefined) {
return(
<Card>
{this.renderEvent()}
</Card>
)
}else{
return(
<View>
<Spinner/>
</View>
)
}
}
}
So far so good, the list and the delete button appear correctly, yet when I try to delete one line, it addresses all. I created my event handler which for now, only logs the passed id.
deleteEvent(eventID){
console.log(eventID)
}
Yet when called, it logs all the _ids on the list. What am I doing wrong? How can I make sure I'm passing one single id of the list item I'm clicking on?
Thank you!
Problem is that you are rather than passing a deleteEvent function to onClick prop you are executing it. This causes to deleteEvent fire for each item while rendering.
You can sort this out by changing this,
onPress={this.deleteEvent(listedEvent._id)}
to this
onPress={() => this.deleteEvent(listedEvent._id)}
This will also assure that deleteEvent is bind with this.