Related
I am trying to implement text change and edit ends in TextInput using react-native but it's not quite working.
See the Screenshot Here
Currently, when changing the price by touch input, the price is not affected when click off.
Here are my files
CartItem.js:
import React from "react";
import {
View,
TextInput,
Image,
TouchableOpacity,
StyleSheet,
Platform,
Alert,
} from "react-native";
//Colors
import Colors from "../../../utils/Colors";
//NumberFormat
import NumberFormat from "../../../components/UI/NumberFormat";
//Icon
import { MaterialCommunityIcons } from "#expo/vector-icons";
import CustomText from "../../../components/UI/CustomText";
//PropTypes check
import PropTypes from "prop-types";
export class CartItem extends React.PureComponent {
render() {
const { item, onAdd, onDes, onRemove } = this.props;
const AddItemHandler = async () => {
await onAdd();
};
const sum = +item.item.price * +item.quantity;
const checkDesQuantity = async () => {
if (item.quantity == 1) {
Alert.alert(
"Clear cart",
"Are you sure you want to remove the product from the cart?",
[
{
text: "Cancel",
},
{
text: "Yes",
onPress: onRemove,
},
]
);
} else {
await onDes();
}
};
return (
<View style={styles.container}>
<View style={styles.left}>
<Image
style={{
width: "100%",
height: 90,
resizeMode: "stretch",
borderRadius: 5,
}}
source={{ uri: item.item.thumb }}
/>
</View>
<View style={styles.right}>
<View
style={{ flexDirection: "row", justifyContent: "space-between" }}
>
<CustomText style={styles.title}>{item.item.filename}</CustomText>
<View>
<TouchableOpacity onPress={onRemove}>
<MaterialCommunityIcons name='close' size={20} color='#000' />
</TouchableOpacity>
</View>
</View>
<CustomText style={{ color: Colors.grey, fontSize: 12 }}>
Provided by Brinique Livestock LTD
</CustomText>
<NumberFormat price={sum.toString()} />
<View style={styles.box}>
<TouchableOpacity onPress={checkDesQuantity} style={styles.boxMin}>
<MaterialCommunityIcons name='minus' size={16} />
</TouchableOpacity>
Code that I would like to be fixed starts here.
<View>
<TextInput
keyboardType='numeric'
onEndEditing={AddItemHandler}
style={styles.boxText}>{item.quantity}</TextInput>
</View>
Code that I would like to be fixed ends here.
<TouchableOpacity
onPress={AddItemHandler}
style={styles.boxMin}>
<MaterialCommunityIcons name='plus' size={16} />
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
CartItem.propTypes = {
item: PropTypes.object.isRequired,
onAdd: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onDes: PropTypes.func.isRequired,
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginHorizontal: 10,
height: 110,
borderBottomWidth: 1,
borderBottomColor: Colors.light_grey,
flexDirection: "row",
paddingVertical: 10,
alignItems: "center",
backgroundColor: "#fff",
paddingHorizontal: 10,
borderRadius: 5,
marginTop: 5,
},
left: {
width: "35%",
height: "100%",
alignItems: "center",
},
right: {
width: "65%",
paddingLeft: 15,
height: 90,
// overflow: "hidden",
},
title: {
fontSize: 14,
},
box: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
height: Platform.OS === "ios" ? 30 : 25,
backgroundColor: Colors.grey,
width: 130,
borderRadius: 5,
paddingHorizontal: 15,
marginTop: 5,
},
boxMin: {
width: "30%",
alignItems: "center",
},
boxText: {
fontSize: 16,
backgroundColor: Colors.white,
padding: 5,
},
});
Use onBlur instead of onEndEditing.
How should the input end triggered?
After a time?
When user hits enter?
When user taps anywhere to close software keyboard?
Instead of
onEndEditing={AddItemHandler}
Use:
onBlur={(e) => {AddItemHandler(e.nativeEvent.text)}}
And ensure that AddItemHandler can handle the value in e.nativeEvent.text.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Image } from 'react-native';
import check from './assets/icons/covid.png'
import pill from './assets/icons/pill.png'
export default function App() {
return (
<View style={styles.container}>
<View style={styles.containerone}>
<TouchableOpacity style={{borderRadius: 100, height: 150, width: 150, backgroundColor: '#fff', marginTop: 80}}>
<Image source={pill} style={styles.pillButton}/>
<Image source={check} style={styles.checkButton}/>
</TouchableOpacity>
</View>
<View style={styles.containertwo}>
<Text style={{color:'#982fc2', fontWeight:'bold', fontSize:20}}>Text b</Text>
<Text style={{color:'#982fc2', fontWeight:'bold', fontSize:20}}>Text a</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#982fc2'
},
containerone: {
flex: 1,
alignItems: 'center'
},
containertwo: {
flex: 1,
backgroundColor: '#fff',
borderTopRightRadius: 60,
borderTopLeftRadius: 60,
padding: 40
},
button: {
backgroundColor: '#fff',
borderRadius: 100,
height: 150,
width: 150,
marginTop: 100,
alignItems:'center',
justifyContent: 'center'
},
checkButton: {
height: 130,
width: 130,
display:'none'
},
pillButton: {
height: 130,
width: 130,
display: 'flex',
marginTop: 10
}
});
I have a simple question, how can I change the style of two buttons in press the first:
I created one style for each button, the first button is visible, and the second is hidden, so, I want to, when I press the first button, I change it style to display: 'none', and in the second, to display:'flex', can you guys help me?
Ciao, you colud use state to alternate Image visibility avoding to use css. Something like:
export default function App() {
const[alternateImage, setAlternateImage] = useState(true);
const changeImage = () => {
setAlternateImage(alternateImage => !alternateImage);
}
return (
<View style={styles.container}>
<View style={styles.containerone}>
<TouchableOpacity style={{borderRadius: 100, height: 150, width: 150, backgroundColor: '#fff', marginTop: 80}} onPress={changeImage}>
{alternateImage && <Image source={pill} style={styles.pillButton}/>}
{!alternateImage && <Image source={check} style={styles.checkButton}/>}
</TouchableOpacity>
</View>
<View style={styles.containertwo}>
<Text style={{color:'#982fc2', fontWeight:'bold', fontSize:20}}>Text b</Text>
<Text style={{color:'#982fc2', fontWeight:'bold', fontSize:20}}>Text a</Text>
</View>
</View>
);
}
and you could remove display: 'none' from Image css.
import React, {useState} from "react";
import {StyleSheet, Text, View, StatusBar, Dimensions, TextInput, Platform, ScrollView,TouchableOpacity, Button } from 'react-native';
import { AppLoading } from "expo";
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
const { height, width } = Dimensions.get("window");
import Display from "./display";
import Modal from "react-native-modal";
const Stack = createStackNavigator();
function HomeScreen({ navigation }) {
return(
<View style={styles0.container}>
<StatusBar barStyle= "light-content" />
<Text style={styles0.title}>Junior Facebook</Text>
<View style={styles0.mainwhite}>
<View style={styles0.first}>
<TextInput
style={styles0.input1}
placeholder = "Enter your email"
/>
<TextInput
style={styles0.input1}
placeholder = "Enter your password"
/>
</View>
<View style={styles0.second}>
<TouchableOpacity
style={styles0.button}
onPress={()=>navigation.navigate("Newsfeed")}
>
<Text>SignUp</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text>Log In</Text>
</TouchableOpacity>
</View>
</View>
</View>
)
}
function Member({navigation}) {
return (
<View style={{alignItems: "center", backgroundColor: "lightgreen", flex: 1}}>
<Text>Junior Facebook</Text>
<TextInput placeholder="Email" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<TextInput placeholder="Password" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<TextInput placeholder="Confirm Password" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<TextInput placeholder="Name" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<TextInput placeholder="Gender" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<TextInput placeholder="Location" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<TextInput placeholder="Alma Mater" style={{width: 200, height: 60, borderStyle: "solid", borderWidth: 2}}/>
<Button style={{width: 100, height: 30}}title="Meeting"
onPress={()=>navigation.navigate("Meeting")}
>Meeting</Button>
</View>
);
}
export default class App extends React.Component{
render(){
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Member" component={Member} />
<Stack.Screen name="Newsfeed" component={Newsfeed} />
</Stack.Navigator>
</NavigationContainer>
)
}
}
const styles0 = StyleSheet.create({
container:{
flex:1,
backgroundColor : "#FFD6ED",
alignItems : "center"
},
title: {
color: "white",
marginTop : 100,
fontSize : 30,
fontWeight: "bold"
},
mainwhite:{
backgroundColor : "white",
width : width -65,
marginTop : 50,
borderRadius: 20
},
input1:{
borderStyle: "solid",
borderWidth: 2,
width: 300,
height: 50,
padding: 10,
marginVertical: 25,
},
input2:{},
first:{
marginVertical: 40,
alignItems : "center"
},
second: {
alignItems : "center",
marginVertical: 20,
},
button : {
marginBottom : 30
}
})
class Newsfeed extends React.Component{
render(){
return(
<View style={styles1.container}>
<StatusBar barStyle= "light-content" />
<View style={styles1.title}>
<Text style={styles1.title}>Junior Facebook</Text>
</View>
<View style={styles1.first}>
<TouchableOpacity style={styles1.profile}>
<Text>프로필</Text>
</TouchableOpacity>
<View style={styles1.allinput}>
<TouchableOpacity>
<TextInput
style={styles1.input}
placeholder = "글 입력"
/>
</TouchableOpacity>
<View style={styles1.button}>
<TouchableOpacity >
<Text style={styles1.picturebutton}>사진</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles1.pushbutton}>입력</Text>
</TouchableOpacity>
</View>
</View>
</View>
<View style={styles1.second}>
<ScrollView>
<Display/>
</ScrollView>
</View>
</View>
)
}
}
const styles1 = StyleSheet.create({
container:{
flex:1,
backgroundColor : "#FFD6ED",
alignItems:"center",
},
title: {
color: "white",
marginTop : 5,
fontSize : 18,
fontWeight: "bold",
marginBottom : 5,
alignItems:"center",
},
first :{
flex:1,
flexDirection : "row",
borderBottomWidth : StyleSheet.hairlineWidth,
marginLeft: 40
},
second:{
flex:3,
},
profile:{
backgroundColor : "white",
borderStyle: "solid",
borderWidth: 2,
width: 90,
height : 110,
marginTop : 3
},
allinput: {
flexDirection : "column",
alignItems:'flex-end',
borderBottomColor: "black",
padding : 3,
},
input:{
borderStyle: "solid",
borderWidth: 2,
width: 200,
height: 110,
padding: 10,
marginLeft : 5,
backgroundColor : "white",
},
button:{
flexDirection : "row"
},
picturebutton:{
fontSize: 24,
width: 60,
height:40,
borderStyle: "solid",
borderWidth: 1,
backgroundColor : "white",
marginVertical : 10,
marginHorizontal : 0
},
pushbutton:{
fontSize: 24,
width: 60,
height:40,
borderStyle: "solid",
borderWidth: 1,
marginLeft : 5,
backgroundColor : "white",
marginVertical : 10
}
})
and my Display component is as follows
import React from "react";
import {View, Text, TextInput, Button, StyleSheet, ScrollView, TouchableOpacity} from "react-native";
export default class Display extends React.Component{
render(){
const {text} = this.props;
return (
<View style={styles.pushtext}>
<Text>일단 한개</Text>
</View>
)
}
}
const styles = StyleSheet.create({
pushtext: {
backgroundColor : "white",
width: 300,
height: 50,
marginTop: 30
}
})
When I click the "Enter" TouchableOpacity, a popup should appear. And I should be able to type in an image link in the popup. And when I type in image link in there and click the "enter" text, an image from that link should appear below. How can I do so?
Please help me out here
Thank you so much!
According to your requirements, I made below sample
import React, { Component } from 'react';
import { View, StyleSheet, Button, Modal, TextInput, Image, } from 'react-native';
export default class App extends Component {
state = {
modalVisible: false,
link: '',
};
setModalVisible = () => {
this.setState({ modalVisible: !this.state.modalVisible });
};
onChangeText = text => {
this.setState({
link: text,
});
};
render() {
return (
<View style={styles.container}>
<Button title='Enter' onPress={this.setModalVisible} />
{
this.state.modalVisible &&
<Modal
visible={this.state.modalVisible}
transparent={true}
animationType="slide"
onRequestClose={this.setModalVisible}>
<View style={styles.modelStyle}>
<View style={styles.modelWrapperStyle}>
<TextInput
style={styles.inputStyle}
onChangeText={this.onChangeText}
value={this.state.link}
/>
<Button title='Enter' onPress={this.setModalVisible} />
</View>
</View>
</Modal>
}
{
!this.state.modalVisible && !!this.state.link &&
<Image
source={{ uri: this.state.link }}
style={{ width: 200, height: 200 }}
/>
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modelStyle: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
modelWrapperStyle: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
backgroundColor: '#ffffff',
padding: 10,
width: '90%',
},
inputStyle: {
height: 40,
width: '80%',
borderColor: 'gray',
borderWidth: 1,
}
});
Hope this helps you. Feel free for doubts.
I have another problem with a button. I have to position it inside a ListView under the last item.
Here are the classes I used:
Notes.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
} from 'react-native';
export default class Note extends Component {
render() {
return (
<View key={this.props.keyval} style={styles.note}>
<Text style={styles.noteText}>{this.props.val.date}</Text>
<Text style={styles.noteText}>{this.props.val.note}</Text>
<TouchableOpacity onPress={this.props.deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}>Del</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
note: {
position: 'relative',
padding: 20,
paddingRight: 100,
borderBottomWidth:2,
borderBottomColor: '#ededed'
},
noteText: {
paddingLeft: 20,
borderLeftWidth: 10,
borderLeftColor: '#0000FF'
},
noteDelete: {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2980b9',
padding: 10,
top: 10,
bottom: 10,
right: 10
},
noteDeleteText: {
color: 'white'
}
});
This is the component that I use every time when I want to create a note.
Main.js:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
ScrollView,
TouchableOpacity,
AsyncStorage,
} from 'react-native';
import Note from './Note';
export default class Main extends Component {
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: '',
};
this.getSavedNotes(this.state.noteArray);
}
render() {
let notes = this.state.noteArray.map((val, key)=>{
return <Note key={key} keyval={key} val={val}
deleteMethod={()=>this.deleteNote(key)}/>
});
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>- NOTER -</Text>
</View>
<ScrollView style={styles.scrollContainer}>
{notes}
<TouchableOpacity onPress={ this.addNote.bind(this) } style={styles.addButton}>
<Text style={styles.addButtonText}>+</Text>
</TouchableOpacity>
</ScrollView>
<View style={styles.footer}>
<TextInput
style={styles.textInput}
placeholder='Write your note here'
onChangeText={(noteText)=> this.setState({noteText})}
value={this.state.noteText}
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
</View>
);
}
addNote(){
if(this.state.noteText){
var d = new Date();
this.state.noteArray.push({
'date':d.getFullYear()+
"/"+(d.getMonth()+1) +
"/"+ d.getDate(),
'note': this.state.noteText
});
this.setState({ noteArray: this.state.noteArray });
this.setState({noteText:''});
AsyncStorage.setItem('arr', JSON.stringify(this.state.noteArray));
alert(this.state.noteArray);
}
}
deleteNote(key){
this.state.noteArray.splice(key, 1);
this.setState({noteArray: this.state.noteArray});
}
getSavedNotes = async (noteArray) =>{
try{
let data = await AsyncStorage.getItem('arr');
if(JSON.parse(data))
{
this.state.noteArray = JSON.parse(data);v
}
}catch(error){
alert(error);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
backgroundColor: '#1A237E',
alignItems: 'center',
justifyContent:'center',
borderBottomWidth: 10,
borderBottomColor: '#ddd'
},
headerText: {
color: 'white',
fontSize: 18,
padding: 26
},
scrollContainer: {
flex: 1,
marginBottom: 100
},
footer: {
position: 'absolute',
bottom: 0,
backgroundColor: '#000000',
left: 0,
right: 70,
zIndex: 10
},
textInput: {
alignSelf: 'stretch',
color: '#fff',
padding: 20,
backgroundColor: '#252525',
borderTopWidth:2,
borderTopColor: '#ededed'
},
addButton: {
position: 'absolute',
zIndex: 11,
right: 0,
bottom: 0,
backgroundColor: '#1A237E',
width: 70,
height: 68,
// borderRadius: 35,
alignItems: 'center',
justifyContent: 'center',
elevation: 8
},
addButtonText: {
color: '#fff',
fontSize: 24
}
});
Here is where I save the notes and display them inside the ListView. After the insertion, the button should appear under the new added note.
Finally the App.js:
import React, { Component } from 'react';
import Main from './app/components/Main.js';
export default class App extends Component {
render() {
return (
<Main/>
);
}
}
Here I just display the Main.js component.
I made it! Here are the changes I made in Main.js file:
<ScrollView style={styles.scrollViewContainer}>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<TouchableOpacity onPress={ this.addNote.bind(this) } style={styles.addButton}>
<Text style={styles.addButtonText}>+</Text>
</TouchableOpacity>
</ScrollView>
And here is the designSheet:
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
backgroundColor: '#1A237E',
alignItems: 'center',
justifyContent:'center',
borderBottomWidth: 10,
borderBottomColor: '#ddd',
},
headerText: {
color: 'white',
fontSize: 18,
padding: 26
},
scrollContainer: {
flex: 1,
},
footer: {
position: 'absolute',
bottom: 0,
height: 70,
backgroundColor: '#000000',
left: 0,
right:0,
zIndex: 10,
},
textInput: {
alignSelf: 'stretch',
color: '#fff',
padding: 20,
backgroundColor: '#252525',
borderTopWidth:2,
borderTopColor: '#ededed',
marginRight: 70,
},
addButton: {
position: 'relative',
zIndex: 11,
left: 0,
top: 0,
backgroundColor: '#1A237E',
width: 70,
height: 70,
alignItems: 'center',
justifyContent: 'center',
elevation: 8
},
addButtonText: {
color: '#fff',
fontSize: 60
},
scrollViewContainer: {
flex: 1,
marginBottom: 70,
}
});
I hope this help others aswell
I am trying to save the noteText inside a text, but it's becoming a problem. I would like to make an object with the same attributes: name, date, note and to display only the name and date. Also, I would like, when I create a Noteto map it in an array. Like so
let notes = this.state.noteArray.map((val, key)=>{
return <Note key={key} keyval={key} val={val}
deleteMethod={()=>this.deleteNote(key)} openNote={()=>this.openNote(key)}/>
});
And here is how I add an item:
this.props.navigation.state.params.noteArray.push({
'noteNumber':'Note '+ this.props.navigation.state.params.noteArray[key],
'date':d.getFullYear()+
"/"+(d.getMonth()+1) +
"/"+ d.getDate(),
'note': this.state.noteText
});
Here is the class note:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
TouchableWithoutFeedback,
} from 'react-native';
export default class Note extends Component {
render() {
return (
<TouchableWithoutFeedback key={this.props.keyval} onPress={this.props.openNote}>
<View style={styles.note}>
<Text style={styles.noteDate}>{this.props.val.noteNumber}</Text>
<Text style={styles.noteDate}>{this.props.val.date}</Text>
<Text style={styles.noteText}>{this.props.val.note}</Text>
<TouchableOpacity onPress={this.props.deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}>Del</Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
);
}
}
const styles = StyleSheet.create({
note: {
position: 'relative',
padding: 20,
backgroundColor:'#fff',
paddingRight: 100,
borderLeftWidth:1,
borderLeftColor: '#000',
borderRightWidth:1,
borderRightColor: '#000',
borderBottomWidth:1,
borderBottomColor: '#000'
},
noteDate:{
paddingLeft: 20,
borderLeftWidth: 10,
borderLeftColor: '#0000FF'
},
noteText: {
paddingLeft: 20,
borderLeftWidth: 10,
borderLeftColor: '#0000FF',
opacity: 0,
},
noteDelete: {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2980b9',
padding: 10,
top: 10,
bottom: 10,
right: 10
},
noteDeleteText: {
color: 'white'
},
});
Here is the example I worked on:
import React, { Component } from "react";
class Counter extends Component {
state = { counter: this.props.startsWith };
...
}
In stead of Counter, I used Note itself.