Two buttons based on click, function will be called - react-native

I want to create a design which I have attached, there are two buttons, when I click on unlimited credit the colour of the button should become red and limited should be white and when I click on limited the limited button should be red and unlimited colour should be white as shown in the image and also when I click on button it should call functions, the function will have some design part and there will be two functions one for unlimited and other for limited based on the button click it should call that function, please let me know how can I execute this.

Final Output:
Full code:
const ButtonContainer = () => {
const [btnOne, setBtnOne] = useState(false);
const [btnTwo, setBtnTwo] = useState(false);
const clickStyle = { backgroundColor: '#F5D9D0', borderColor: '#F3805E' }
return (
<View style={styles.buttonContainer}>
<TouchableOpacity
onPress={() => {
setBtnOne(true);
setBtnTwo(false);
}}
style={[
styles.button,
btnOne ? clickStyle : null,
]}>
<Text>Unlimited Credit</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
setBtnOne(false);
setBtnTwo(true);
}}
style={[
styles.button,
btnTwo ? clickStyle : null,
]}>
<Text>Limited Credit</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-evenly',
},
button: {
borderColor: 'grey',
borderWidth: 2,
padding: 10,
borderRadius: 20,
},
});
Live working example: Expo Snack

here's a snack I created: https://snack.expo.io/#yoobit0616/two-buttons
import React, { useState } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Button } from 'react-native-elements';
import Constants from 'expo-constants';
export default function App() {
const [disabledButton, setDisabledButton] = useState(true);
return (
<View style={styles.container}>
<View style={styles.buttonView}>
<Button
style={styles.button}
onPress={() => setDisabledButton(!disabledButton)}
buttonStyle={
disabledButton
? { backgroundColor: 'white' }
: { backgroundColor: 'red' }
}
titleStyle={{ color: 'black' }}
title="Unlimited Credit"></Button>
<Button
style={styles.button}
onPress={() => setDisabledButton(!disabledButton)}
buttonStyle={
!disabledButton
? { backgroundColor: 'white' }
: { backgroundColor: 'red' }
}
titleStyle={{ color: 'black' }}
title="Limited Credit"></Button>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
buttonView: {
flexDirection: 'row',
justifyContent: 'center',
},
button: {
height: 40,
width: 150,
marginLeft: 20,
borderRadius: 5,
borderWidth: 1,
},
});

Related

How to put 2 boxes in the same row and then put 2 more underneath? and so on

I am trying to put the elements of a 2 since what is a data .map and I can not put a divider DIV with a flexDirection: "row", I need to make a wrap and they are accommodated but doing it is not working correctly.
<View
style={styles.container_cards}
>
{
data.map((elements, index) => {
return(
<CardTwoRows elements={elements}/>
)
})
}
</View>
const styles = StyleSheet.create({
container_cards: {
width: "100%",
height: "100%",
marginTop: verticalScale(14),
flexWrap: "wrap",
},
})
My CardTwoRows, it basically contains this
<View style={styles.container}>
.........
</View>
const styles = StyleSheet.create({
container: {
width: "49%",
height: verticalScale(220),
borderRadius: scale(6),
marginRight: "2%",
},
})
This is a sample of how it looks, I need to show 2 then a space between the lines and 2 cards again
You can use a flatlist like this.
A working demo as well as the code below
import * as React from 'react';
import { Text, View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
const list = [0, 1, 2, 3, 4, 5, 6, 7];
export default function App() {
return (
<View style={styles.container}>
<FlatList
data={list}
numColumns={2}
keyExtractor={(item)=> item}
renderItem={({ item }) => (
<View style={styles.card}>
<Text style={styles.text}>{item}</Text>
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
card: {
height: 100,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#212121',
margin: 5,
borderRadius: 10,
},
text: {
fontSize: 40,
fontWeight: '600',
color: 'white',
},
});

Navigating among three screens

I am about to making an app with React Native and I have three screens with deferent styles (themes). I want to navigate among these three screens, So I am passing data from my main screen (App.js) as parent to the other three as child (screen1, screen2, screen3). I used a modal which has three button in it and i want whenever I pressed one of them, the screen change to the pressed one. This is my App.js file
import React, { useState, useEffect } from "react";
import { StyleSheet, View } from "react-native";
import Screen1 from "./screens/CalcScreen";
import Screen2 from "./screens/Screen1";
import Screen3 from "./screens/Screen2";
export default function App() {
const [whiteScreen, setWhiteScreen] = useState(false);
const [darkScreen, setDarkScreen] = useState(false);
const [pinkScreen, setPinkScreen] = useState(false);
const whiteScreenHandler = () => {
setWhiteScreen(true);
setDarkScreen(false);
setPinkScreen(false);
};
const darkScreenHandler = () => {
setDarkScreen(true);
setWhiteScreen(false);
setPinkScreen(false);
};
const pinkScreenHander = () => {
setPinkScreen(true);
setWhiteScreen(false);
setDarkScreen(false);
};
let content = <screen1 setDarkScreen={darkScreenHandler} />;
let content2 = <Screen2 setWhiteScreen={whiteScreenHandler} />;
let content3 = <Screen3 setPinkScreen={pinkScreenHander} />;
if (darkScreen) {
content = content;
} else if (whiteScreen) {
content = content2;
} else if (pinkScreen) {
content = content3;
}
return <View style={styles.container}>{content}</View>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#374351",
},
});
And this is one of my screens and my modals in my screens, the other two screens are same in coding but not in styles and I used this modal in each three screens,(does it right to use in three screens?) anyway whenever I'm pressing modal's button to change the screens i got props.screen handler() is not a function. What is wrong in my code?
import React, { useState } from "react";
import {
StyleSheet,
Text,
ScrollView,
View,
TouchableOpacity,
Alert,
Animated,
Modal,
Pressable,
} from "react-native";
const Screen1 = (props) => {
return (
<View style={styles.screen}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={styles.button}></View>
<Text style={styles.modalText}>Themes</Text>
<TouchableOpacity
style={styles.darkTheme}
onPress={() => {
props.setDarkScreen();
}}
>
<Text>Dark</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.whiteTheme}
onPress={() => {
props.setWhiteScreen();
}}
>
<Text>White</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.pinkTheme}
onPress={() => {
props.setPinkScreen();
}}
>
<Text>Pink</Text>
</TouchableOpacity>
<Pressable
style={[styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>X</Text>
</Pressable>
</View>
</View>
</Modal>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.openText}>{">"}</Text>
</Pressable>
</View>
)
}
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafcff",
},
centeredView: {
// flex: 1,
marginStart: 15,
justifyContent: "center",
alignItems: "center",
// marginTop: 70,
},
modalView: {
marginTop: 200,
backgroundColor: "rgba(255,255,255,0.5)",
borderRadius: 20,
padding: 20,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.5,
shadowRadius: 4,
elevation: 5,
},
button: {
borderRadius: 15,
padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
buttonOpen: {
backgroundColor: "rgba(1,143,132,0.6)",
position: "absolute",
marginTop: 45,
marginStart: -25,
elevation: 2,
height: 70,
width: 40,
},
buttonClose: {
backgroundColor: "rgba(1,1,1,1)",
height: 40,
width: 40,
borderRadius: 50,
// padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
textStyle: {
color: "white",
// fontWeight: "bold",
textAlign: "center",
},
modalText: {
marginBottom: 10,
textAlign: "center",
},
openText: {
fontSize: 25,
fontWeight: "bold",
color: "white",
textAlign: "right",
},
});
export default Screen1;
You can easily doing that by using "React Native Navigation". Here is the documentation:
https://reactnavigation.org/docs/getting-started. I also recommend you that you might want to create your screens into different files to make your code cleaner.

I am trying to implement text change and edit ends in TextInput using react-native but it's not quite working. Can any one help me?

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.

Long texts getting cropped in Text components React-Native

I have a functional component Comment, which dynamically receives data to show in a socialmedia like application. If a long text is given as a comment, the height of the card is increased accordinly but the last line is cropped by a half. I tried with many solutions I found in other posts, like textBreakStrategy={'simple'} or flexWrap: 'wrap' in the container, but nothing is solving this issue.
As additional information, a lot of Comments are being rendered in a container ScrollView, and the ScrollView is inside a View with flex: 1. I dont think there's any problem with the container.
To give a better idea, here's a picture of a Comment with a long text getting cropped in the last line:
Here is the component's code:
import React, { useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import AntDesign from 'react-native-vector-icons/AntDesign';
import { formatDistanceToNow } from 'date-fns'
import { es } from 'date-fns/esm/locale'
const Comment = props => {
const amITheCreator = (comment, user) => {
if (comment && user) {
return comment.creator_id === user.id;
}
return false;
};
const user = props.user;
const comment = props.item;
const date = new Date(comment.createdAt);
const relativeDate = formatDistanceToNow(date, { addSuffix: true, locale: es });
const itsMine = amITheCreator(comment, user);
const [liked, setLiked] = useState(comment.liked);
const [likes, setLikes] = useState(comment.likes);
const toggleLike = () => {
if (liked) {
setLikes(likes - 1);
} else {
setLikes(likes + 1);
}
setLiked(!liked);
};
const onLike = () => {
toggleLike();
props.onLike(comment.id);
};
return (
<View style={{ ...styles.container, backgroundColor: itsMine ? '#0095ff' : 'white' }}>
<View style={styles.header}>
<Text style={{ ...styles.owner, color: itsMine ? 'white' : '#222b45' }}>{comment.name}</Text>
<Text style={{ ...styles.date, color: itsMine ? 'white' : '#8f9bb3' }}>{relativeDate}</Text>
</View>
<View style={styles.contentContainer}>
<Text style={{ ...styles.content, color: itsMine ? 'white' : '#222b45' }}>{comment.content}</Text>
</View>
<View style={styles.header}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<AntDesign name={'heart'} color={itsMine ? 'white' : '#8f9bb3'} size={14} />
<Text style={{ ...styles.likes, color: itsMine ? 'white' : '#8f9bb3' }}> {likes ? likes : '0'} Me gusta</Text>
</View>
<TouchableOpacity onPress={onLike}>
{liked ?
<AntDesign name={'heart'} color={'#ff2d55'} size={20} />
:
<AntDesign name={'hearto'} color={itsMine ? 'white' : '#8f9bb3'} size={20} />
}
</TouchableOpacity>
</View>
</View >
);
};
const styles = StyleSheet.create({
container: {
marginHorizontal: 15,
marginBottom: 15,
borderRadius: 7,
padding: 10,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
},
owner: {
fontWeight: 'bold',
},
date: {
fontSize: 12,
color: 'white',
},
contentContainer: {
padding: 5,
flexWrap: 'wrap',
},
content: {
fontSize: 16,
alignSelf: 'stretch',
width: '100%',
padding: 5,
},
likes: {
color: 'white',
fontSize: 15,
fontWeight: 'bold',
},
});
export default Comment;

React Native My delete button does not work

My code seems to be good but I do not understand why it is just doing nothing when I hit the "X" look at the code below please and help me out!
import React, { useState } from 'react';enter code here
import { StyleSheet, FlatList, Text, View, Image, TextInput, Button, Keyboard, TouchableOpacity, CheckBox } from 'react-native';
import Interactable from 'react-native-interactable';
export default function App() {
const [enteredGoal, setEnteredGoal] = useState('');
const [courseGoals, setCourseGoals] = useState([]);
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
const addGoalHandler = () => {
if (enteredGoal.length > 0) {
setCourseGoals(currentGoals => [...currentGoals, enteredGoal])
} else {
alert("You have to write something!")
}
}
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
courseGoals.splice(idx, 1)
setCourseGoals(courseGoals)
}
return (
<View style={styles.container}>
<View style={styles.topPart}></View>
<View style={styles.navBar}>
<Image source={require('./assets/baseline_menu_black_18dp.png/')} />
<Text style={styles.heading}> Grocery List </Text>
</View>
<View style={styles.body}>
<TextInput
style={styles.textInput}
placeholder='Groceries'
maxLength={20}
onBlur={Keyboard.dismiss}
value={enteredGoal}
onChangeText={goalInputHandler}
/>
<View style={styles.inputContainer}>
<TouchableOpacity style={styles.saveButton}>
<Button title="ADD" onPress={addGoalHandler} color="#FFFFFF" style={styles.saveButtonText} />
</TouchableOpacity>
</View>
<View style={styles.container}>
<FlatList
data={courseGoals}
renderItem={(itemData, idx) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete} onPress={() => deleteItem(idx)}>X</Text>
</View>
)}
/>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
topPart: {
height: '3%',
backgroundColor: '#5498A7',
},
navBar: {
height: '10%',
backgroundColor: '#5498A7',
elevation: 3,
paddingHorizontal: 15,
flexDirection: 'row',
alignItems: 'center',
},
body: {
backgroundColor: '#edebe9',
height: '100%',
flex: 1
},
heading: {
fontWeight: "bold",
justifyContent: 'center',
paddingLeft: '13%',
fontSize: 25,
color: '#d6d4d3'
},
textInput: {
borderColor: '#CCCCCC',
borderTopWidth: 1,
borderBottomWidth: 1,
height: 50,
fontSize: 25,
paddingLeft: 20,
paddingRight: 20
},
saveButton: {
borderWidth: 1,
borderColor: '#5498A7',
backgroundColor: '#5498A7',
padding: 15,
margin: 5,
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 20,
textAlign: 'center'
},
groceryItem: {
borderWidth: 1,
borderColor: 'black',
backgroundColor: '#6A686B',
padding: 15,
margin: 5,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
groceryItemText: {
color: '#d6d4d3',
},
groceryItemDelete: {
color: 'red',
fontWeight: 'bold',
fontSize: 20
}
});
I am just a beginner and am trying to figure out how to make this work better, if you have an idea please say how to fix it I would really appreciate it. This is a project I am doing just to get started with the learning process but this has been taking a bit longer than expected. Thank you!
I guess you have to change deleteItem function as following.
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
clonedGoals.splice(idx, 1)
setCourseGoals(clonedGoals)
}
You have to replace courseGoals with clonedGoals
You can use ES2015 to achieve it in fewer lines, update your delete function like this:
const deleteItem = element => {
const clonedGoals = courseGoals.filter((item) => item !== element);
setCourseGoals(clonedGoals);
}
also update your onPress instead of passing index pass the item itself like this
onPress={() => deleteItem(itemData.item)}