Styling a part of an array in JSX - javascript

I have an array,
const arr = [
{ age: 1, name: 'Raphael' },
{ age: 3, name: 'Inyang' },
{ age: 6, name: 'Ifiok' },
{ age: 8, name: 'Ekpedeme' }
];
I need ages above 5 to have an opacity of 0.5, while the rest will have an opacity of 1
function changeOpacityOfArray(letter) {
if (arr.age >= 5 ) {
letter.style.opacity= '0.5';
}
}
changeOpacityOfArray(arr);
The above doesn't work in JSX,
it says cannot style an undefined element
Then in the HTML body, note the opacity in the styling
<ul style={{listStyleType: 'none'}}>
{arr.map(function(item){
return (<li><div style={{display: 'flex', justifyContent: 'flex-start', width: 'auto', fontSize: 'calc(4px + 2vmin)', opacity: 1, justifyContent: 'flex-start' }}><p>{item.name}: {item.age}</p></div></li>)
}
)}
</ul>

Why don't you move the age check into the style prop?
{arr.map(function (item) {
return (
<li>
<div
style={{
display: "flex",
justifyContent: "flex-start",
width: "auto",
fontSize: "calc(4px + 2vmin)",
opacity: item.age > 5 ? 0.5 : 1,
justifyContent: "flex-start",
}}
>
<p>
{item.name}: {item.age}
</p>
</div>
</li>
);
})}
Also you have a typo in the opacity prop, you have to write it in lowercase

When styling the div you can check the item's age and set the opacity accordingly.
const arr = [
{ age: 1, name: 'Raphael' },
{ age: 3, name: 'Inyang' },
{ age: 6, name: 'Ifiok' },
{ age: 8, name: 'Ekpedeme' },
];
<ul style={{ listStyleType: 'none' }}>
{arr.map(function (item) {
return (
<li>
<div
style={{
display: 'flex',
justifyContent: 'flex-start',
width: 'auto',
fontSize: 'calc(4px + 2vmin)',
opacity: item.age > 5 ? 0.5 : 1,
justifyContent: 'flex-start',
}}>
<p>
{item.name}: {item.age}
</p>
</div>
</li>
);
})}
</ul>;

Related

how can I create custom keyboard for pin code input in react native without any libraries

I have created this code but it isn't working, I have created four input fields for pin code when users press the numeric it should move to the input field and turn that fields in the mask, like in * part so I am trying to add that one but something I am missing also I am not getting the four digits pin code when console the function please help me out.
import React, { Component, useLayoutEffect, useState } from "react";
import {
StyleSheet,
Text,
View,
ImageBackground,
SafeAreaView,
Image,
TouchableOpacity,
TouchableOpacityBase,
TextInput,
} from "react-native";
import Theme from "../../utils/Theme";
import OTPInputView from "#twotalltotems/react-native-otp-input";
const hRem = AppStore.screenHeight / 812;
const wRem = AppStore.screenWidth / 375;
class PinAuthentication extends Component {
constructor(props) {
super(props);
this.state = {
passcode: ["", "", "", ""],
};
}
onPressNumber = (num) => {
const tempcode = this.state.passcode;
for (let i = 0; i < tempcode.length; i++) {
if (tempcode[i] == "") {
tempcode[i] = num;
break;
} else {
continue;
}
}
this.setState({ passcode: tempcode });
};
onPressCancel = (num) => {
const tempcode = this.state.passcode;
for (let i = tempcode.length; i >= 0; i--) {
if (tempcode[i] != "") {
tempcode[i] = "";
break;
} else {
continue;
}
}
this.setState({ passcode: tempcode });
};
render() {
let numbers = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 7 },
{ id: 8 },
{ id: 9 },
{
id: 10,
},
{ id: 0 },
{
id: 11,
},
];
return (
<>
<ImageBackground
style={styles.container}
source={require("../../assets/Images/SliderImages/Background02sc.png")}
/>
<View style={styles.headerStyle}>
<TouchableOpacity>
<Image
style={styles.backButton}
source={require("../../assets/Images/SliderImages/Icon/BackButton.png")}
/>
</TouchableOpacity>
<View>
<Text style={styles.pinText}>Set new PIN</Text>
</View>
</View>
<View></View>
<View></View>
<View>
<Text style={styles.pinConfirmationText}>Enter new PIN</Text>
</View>
{/* <View style={{ alignItems: "center" }}>
<OTPInputView
style={{ width: "80%", height: 200 }}
pinCount={4}
// code={this.state.code} //You can supply this prop or not. The component will be used as a controlled / uncontrolled component respectively.
// onCodeChanged = {code => { this.setState({code})}}
autoFocusOnLoad
codeInputFieldStyle={styles.underlineStyleBase}
codeInputHighlightStyle={styles.underlineStyleHighLighted}
onCodeFilled={(code) => {
console.log(`Code is ${code}, you are good to go!`);
}}
secureTextEntry={true}
// keyboardType={false}
/>
</View> */}
<View style={styles.codeContainer}>
{this.state.passcode.map((x) => {
let codes = x != "" ? styles.inputBox1 : styles.inputBox;
return (
<View style={codes}>{/* <Text style={codes}></Text> */}</View>
);
})}
</View>
<View style={{ alignItems: "center", justifyContent: "center" }}>
<View style={styles.numberContainer}>
{numbers.map((num, numb) => {
return (
<>
{num.id == 10 ? (
<TouchableOpacity
key={num.id}
onPress={() => this.onPressCancel()}
style={styles.number}
>
<Image
style={styles.img}
source={require("../../assets/Images/SliderImages/Icon/icons_cancel_last_digit.png")}
/>
</TouchableOpacity>
) : num.id == 11 ? (
<TouchableOpacity
key={num.id}
onPress={() => this.onPressCancel()}
style={styles.number}
>
<Image
style={styles.img}
source={require("../../assets/Images/SliderImages/Icon/icons_check.png")}
/>
</TouchableOpacity>
) : (
<TouchableOpacity
key={num.id}
onPress={() => this.onPressNumber(num.id)}
style={styles.number}
>
<Text style={styles.numberText}>{num.id}</Text>
</TouchableOpacity>
)}
</>
);
})}
</View>
</View>
</>
);
}
}
export default PinAuthentication;
const styles = StyleSheet.create({
container: {
flex: 1,
position: "absolute",
top: 0,
right: 0,
left: 0,
bottom: 0,
backgroundColor: "#021831",
},
headerStyle: {
flexDirection: "row",
marginTop: hRem * 56,
marginHorizontal: wRem * 24,
alignItems: "center",
},
backButton: {
width: wRem * 12,
height: hRem * 21,
},
pinText: {
color: "white",
textAlign: "center",
alignSelf: "center",
marginLeft: wRem * 101,
fontSize: hRem * 18,
...Theme.encodeSansMed1,
lineHeight: hRem * 16,
},
pinConfirmationText: {
textAlign: "center",
marginTop: hRem * 44,
color: "white",
...Theme.encodeSansMed3,
lineHeight: hRem * 19.07,
},
borderStyleBase: {
width: 30,
height: 45,
},
borderStyleHighLighted: {
borderColor: "#707070",
},
underlineStyleBase: {
width: wRem * 62,
height: 45,
borderWidth: 0,
borderBottomWidth: 1,
},
underlineStyleHighLighted: {
borderColor: "#FFFFFF",
},
number: {
width: wRem * 77,
height: hRem * 77,
borderRadius: wRem * 77,
backgroundColor: "#000000",
justifyContent: "center",
alignItems: "center",
marginHorizontal: wRem * 12,
marginVertical: hRem * 9,
},
numberContainer: {
flexDirection: "row",
flexWrap: "wrap",
marginTop: hRem * 95,
alignItems: "center",
justifyContent: "center",
shadowColor: Theme.shadow_Button,
shadowOffset: {
width: 1,
height: 1,
},
shadowOpacity: 1.5,
shadowRadius: 5,
elevation: 3,
},
numberText: {
...Theme.encodeSansMed4,
// lineHeight: hRem * 16,
position: "absolute",
textAlign: "center",
color: Theme.white_color,
},
codeContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginHorizontal: wRem * 49,
marginTop: hRem * 50,
},
code: {
width: wRem * 62,
height: hRem * 2,
borderColor: "#FFFFFF",
borderWidth: 1,
borderRadius: 13,
},
inputBox: {
width: wRem * 62,
borderBottomWidth: 1,
borderWidth: 1,
// height: 13,
// width: 13,
borderColor: "#FFFFFF",
// alignItems: "center",
// justifyContent: "space-between",
// backgroundColor: "white",
// borderRadius: 13,
},
inputBox1: {
width: wRem * 62,
borderBottomWidth: 1,
borderWidth: 1,
// height: 13,
// width: 13,
borderColor: "#FFFFFF",
// alignItems: "center",
// justifyContent: "space-between",
// backgroundColor: "white",
// borderRadius: 13,
},
inputText: {
color: "white",
...Theme.encodeSansMed3,
paddingBottom: hRem * 21,
backgroundColor: "green",
width: 20,
},
inputText1: {
color: "white",
...Theme.encodeSansMed3,
paddingBottom: hRem * 21,
},
img: {
width: wRem * 30,
height: hRem * 22,
},
});
I have created this code but it isn't working, I have created four input fields for pin code when users press the numeric it should move to the input field and turn that fields in the mask, like in * part so I am trying to add that one but something I am missing also I am not getting the four digits pin code when console the function

React js chat when scrolling up load old messages

I am developing a chat, as can be seen from the image.
When the chat opens, the chat scrolls down to show the latest messages.
What I would like to do, that when user scrolls up and gets to the last message (i.e. the oldest one in the chat), the oldMessage function is called which makes an http call passing the current page to try to retrieve the previous messages to the last displayed at the top.
I don't know if I've made myself clear.
Can you give me a hand?
Link: codesandbox
import React, { useState, useRef, useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import {
Card,
Typography,
Icon,
useTheme,
TextField,
IconButton,
Avatar,
Paper
} from "#material-ui/core";
import Moment from "react-moment";
import clsx from "clsx";
import moment from "moment/moment";
const message = [
{
id: 1,
createdAt: "",
message: "Hi, James!",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 2,
createdAt: "",
message: "Hi, Vesper!",
senderId: {
_id: 1,
name: "James",
surname: "Bond"
}
},
{
id: 3,
createdAt: "",
message: "Quickly come to the meeting room 1B, we have a big server issue",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 4,
createdAt: "",
message: "I’m having breakfast right now, can’t you wait for 10 minutes?",
senderId: {
_id: 1,
name: "James",
surname: "Bond"
}
},
{
id: 5,
createdAt: "",
message: "I’m having breakfast right now, can’t you wait for 10 minutes?",
senderId: {
_id: 1,
name: "James",
surname: "Bond"
}
},
{
id: 6,
createdAt: "",
message: "We are losing money! Quick!",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 7,
createdAt: "",
message:
"It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.",
senderId: {
_id: 1,
name: "James",
surname: "Bond"
}
},
{
id: 8,
createdAt: "",
message: "You are the worst!",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 9,
createdAt: "",
message: "We are losing money! Quick!",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 10,
createdAt: "",
message: "You are the worst!",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 11,
createdAt: "",
message: "We are losing money! Quick!",
senderId: {
_id: 2,
name: "Vesper",
surname: "Lynd"
}
},
{
id: 12,
createdAt: "",
message:
"It’s not my money, you know. I will eat my breakfast and then I will come to the meeting room.",
senderId: {
_id: 1,
name: "James",
surname: "Bond"
}
}
];
const useStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
messageRow: {
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "flex-end",
padding: "0 16px 4px 16px",
flex: "0 0 auto",
"&.contact": {
"& $bubble": {
backgroundColor: theme.palette.background.paper,
color: theme.palette.getContrastText(theme.palette.background.paper),
borderTopLeftRadius: 5,
borderBottomLeftRadius: 5,
borderTopRightRadius: 20,
borderBottomRightRadius: 20,
marginLeft: 28,
"& $time": {
marginLeft: 12
}
},
"&.first-of-group": {
"& $bubble": {
borderTopLeftRadius: 20
}
},
"&.last-of-group": {
"& $bubble": {
borderBottomLeftRadius: 20
}
}
},
"&.me": {
paddingLeft: 40,
"& $avatar": {
order: 2,
margin: "0 0 0 16px"
},
"& $bubble": {
marginLeft: "auto",
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
borderTopLeftRadius: 20,
borderBottomLeftRadius: 20,
borderTopRightRadius: 5,
borderBottomRightRadius: 5,
"& $time": {
justifyContent: "flex-end",
right: 0,
marginRight: 12
}
},
"&.first-of-group": {
"& $bubble": {
borderTopRightRadius: 20
}
},
"&.last-of-group": {
"& $bubble": {
borderBottomRightRadius: 20
}
}
},
"&.contact + .me, &.me + .contact": {
paddingTop: 20,
marginTop: 20
},
"&.first-of-group": {
"& $bubble": {
borderTopLeftRadius: 20,
paddingTop: 13
}
},
"&.last-of-group": {
"& $bubble": {
borderBottomLeftRadius: 20,
paddingBottom: 13,
"& $time": {
display: "flex"
}
}
}
},
avatar: {
position: "absolute",
left: 0,
margin: 0
},
bubble: {
position: "relative",
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: 12,
maxWidth: "100%",
boxShadow: theme.shadows[1]
},
message: {
whiteSpace: "pre-wrap",
lineHeight: 1.2
},
time: {
position: "absolute",
display: "none",
width: "100%",
fontSize: 11,
marginTop: 8,
top: "100%",
left: 0,
whiteSpace: "nowrap"
},
bottom: {
// background: theme.palette.background.default,
// borderTop: '1px solid rgba(0, 0, 0, 0.13)'
},
inputWrapper: {
borderRadius: 24
}
}));
export default function App() {
const classes = useStyles();
const [state, setState] = useState({
userMyInfo: {
id: 1,
name: "James",
surname: "Bond"
},
chat: message,
msgState: "",
pag: 0
});
const { userMyInfo, chat, msgState } = state;
const sendMessage = () => {};
const oldMessage = () => {
//http request
fetch("")
.then((response) => response.json())
.then((message) => {
setState(...(prev) => ({ ...prev, chat: [...message, ...prev.chat] }));
})
.catch((error) => {
console.error(error);
});
};
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
};
useEffect(scrollToBottom, []);
const shouldShowContactAvatar = (item, i) => {
return (
(chat[i + 1] && chat[i].senderId._id !== chat[i + 1].senderId._id) ||
!chat[i + 1]
);
};
const isFirstMessageOfGroup = (item, i) => {
return (
i === 0 || (chat[i - 1] && chat[i - 1].senderId._id !== item.senderId._id)
);
};
const isLastMessageOfGroup = (item, i) => {
return (
i === chat.length - 1 ||
(chat[i + 1] && chat[i + 1].senderId._id !== item.senderId._id)
);
};
return (
<Paper
elevation={3}
className={clsx(classes.root, "flex flex-col relative pb-64")}
>
<Card elevation={1} className="flex flex-col h-512 rounded-8">
<div
className="flex flex-shrink-0 items-center justify-between px-24 h-64"
style={{
background: "#607d8b"
//color: theme.palette.getContrastText('#607d8b')
}}
>
<Typography className="text-center text-16 font-400">Chat</Typography>
</div>
<div style={{ flex: 1, overflowY: "auto" }}>
{state.chat.length === 0 ? (
<div style={{ textAlign: "center" }}>
Al momento non ci sono messaggi
</div>
) : (
state.chat.map((item, key) => (
<div
key={key}
className={clsx(
classes.messageRow,
{ me: item.senderId._id === userMyInfo.id },
{ contact: item.senderId._id !== userMyInfo.id },
{ "first-of-group": isFirstMessageOfGroup(item, key) },
{ "last-of-group": isLastMessageOfGroup(item, key) }
)}
>
{item.senderId._id !== userMyInfo.id &&
shouldShowContactAvatar(item, key) && (
<Avatar className={classes.avatar}>
{item.senderId.name[0]} {item.senderId.surname[0]}
</Avatar>
)}
<div className={classes.bubble}>
<div className={classes.message}>{item.message}</div>
<Typography className={classes.time} color="textSecondary">
{moment(item.time).format("MMMM Do YYYY, h:mm:ss a")}
</Typography>
</div>
</div>
))
)}
<div ref={messagesEndRef} />
</div>
<div style={{ padding: 5, display: "flex", flexDirection: "row" }}>
<TextField
required
id="outlined-required"
label="Message"
//inputRef={textInput}
placeholder="Message"
//onChange={handleChange}
variant="outlined"
fullWidth
/>
<IconButton onClick={() => sendMessage()} disabled={msgState === ""}>
<Icon>send</Icon>
</IconButton>
</div>
</Card>
</Paper>
);
}
You need to add an event handler for scrolling and check you are at the top of the container
const handleScroll = e => {
let element = e.target;
if (element.scrollTop===0) {
//fetch messages
}
}
<div style={{ flex: 1, overflowY: "auto"}} onScroll={ handleScroll}>
Two things you can do is
Monitor for scroll event on an element using onScroll from react
<ScrollableComponent onScroll={this.handleScroll} />
use the windows scroll event handler and detect when user is at top of page
useEffect(() => {
window.addEventListener('scroll', this.handleScroll);
return () => window.removeEventListener('scroll', this.handleScroll);
}
const handleScroll = (event) => {
// code here
}

React Native FlatList not scrolling within flexbox UI

I have spent hours trying to understand why my flat list refuses to scroll. I have see many solutions about adding "flexGrow: 1" to the contentContainerStyle prop of the list, sadly that doesnt solve for me here. I have tried many variations of using flex/flexGrow: 1 in the style prop too, but still no scrolling. I attach what my code for this page looks like:
import React, { Component } from "react";
import { Dimensions, FlatList, View, StyleSheet, TouchableOpacity } from "react-native";
import { Button, Block, Text } from "galio-framework";
import Theme from "../../constants/Theme";
import { StatusBar } from "expo-status-bar";
import MapView, { PROVIDER_GOOGLE } from "react-native-maps";
import SvgCarIcon from "../../components/SvgCarIcon";
import DashIcons from "../../components/DashIcons";
export default class MakePayment extends Component {
constructor(props) {
super(props);
this.state = {
source: {
latitude: 0,
longitude: 0,
latitudeDelta: 0.005,
longitudeDelta: 0.005
},
rideOptions: [
{
title: "Ride A",
passengers: 4,
arrivalTime: "10:00 - 10:07 arrival",
price: "5.00",
isSelected: false
},
{
title: "Ride B",
passengers: 7,
arrivalTime: "10:00 - 10:07 arrival",
price: "7.50",
isSelected: false
},
{
title: "Ride C",
passengers: 6,
arrivalTime: "12:00 - 13:30 arrival",
price: "3.50",
isSelected: false
}
]
};
}
toggleOption = (INDEX) => {
let updatedRideOptions = this.state.rideOptions.slice().map((item, index) => {
INDEX === index ? item["isSelected"] = !item["isSelected"] : item["isSelected"] = false
return item;
})
this.setState({rideOptions: updatedRideOptions}, () => console.log(this.state.rideOptions));
}
componentDidMount() {
let { lat, lng } = this.props.route.params.source.geometry.location;
this.setState({
source: {
...this.state.source,
latitude: lat,
longitude: lng
}
}, () => console.log(this.state.source));
}
render() {
return (
<View style={styles.container}>
<StatusBar hidden/>
<MapView
provider={PROVIDER_GOOGLE}
showsCompass={true}
showsUserLocation={true}
style={styles.map}
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}}
region={this.state.source}
/>
<View style={styles.menuContainer}>
<Text style={styles.header}>Time To Pick A Dash!</Text>
<FlatList
contentContainerStyle={{
width: "90%",
flexGrow: 1,
alignItems: "center",
borderColor: "red",
borderStyle: "solid",
borderWidth: 2
}}
scrollEnabled={true}
keyExtractor={((item, index) => String(index))}
data={this.state.rideOptions}
renderItem={({ item , index}) => {
return (
<TouchableOpacity
activeOpacity={0.9}
style={[styles.dashRideBox, item.isSelected && styles.btnSelected]}
onPress={() => this.toggleOption(index)}
>
<SvgCarIcon color={item.isSelected ? Theme.COLOURS.WHITE : Theme.COLOURS.SECONDARY}/>
<Block style={{ paddingRight: 25 }}>
<Text size={18} color={item.isSelected ? Theme.COLOURS.WHITE : Theme.COLOURS.SECONDARY}>{item.title}
<Text small style={item.isSelected && styles.textSelected}>{item.passengers}</Text>
</Text>
<Text size={14} style={item.isSelected ? styles.textSelected : styles.subText}>{item.arrivalTime}</Text>
</Block>
<Text color={item.isSelected ? Theme.COLOURS.WHITE : Theme.COLOURS.SECONDARY} size={24}>{item.price}</Text>
</TouchableOpacity>
);
}}
/>
</View>
<Block style={styles.paymentContainer}>
<Block style={{
flex: 0.4, flexDirection: "row", alignItems: "center"
}}>
<Block style={styles.card}>
<DashIcons name={"visa"} size={40}/>
<Text size={14} color={Theme.COLOURS.SUB_TEXT} bold>VISA ***** 4700</Text>
<TouchableOpacity
style={{
flex: 1,
alignItems: "center"
}}
onPress={() => console.log("Card drop down opened...")}
>
<DashIcons name={"dropdown-arrow"} size={14} color={"grey"}/>
</TouchableOpacity>
</Block>
<Button style={styles.recent}>
<DashIcons name={"clock"} size={22}/>
</Button>
</Block>
<Button style={styles.confirmBtn} color={"#F2F2F2"}>
<Text size={24} color={Theme.COLOURS.SECONDARY}>Confirm your dash</Text>
</Button>
</Block>
</View>
);
}
}
const { width: WIDTH } = Dimensions.get("window"); //Max Width of phone screen
const { height: HEIGHT } = Dimensions.get("window");
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
fontFamily: "Roboto",
backgroundColor: Theme.COLOURS.WHITE
},
menuContainer: {
flex: 0.3,
justifyContent: "space-between",
alignItems: "center",
width: "100%",
paddingHorizontal: 10,
elevation: 1
},
dashRideBox: {
flexGrow: 0.475,
backgroundColor: Theme.COLOURS.WHITE,
width: "100%",
paddingHorizontal: 5,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
borderRadius: 10,
elevation: 3,
shadowRadius: 10
},
map: {
flex: 0.45,
width: WIDTH
},
paymentContainer: {
marginTop: 10,
flex: 0.25,
paddingHorizontal: 10,
justifyContent: "center",
alignItems: "center",
borderStyle: "solid",
borderWidth: 2,
borderColor: "rgba(0,0,0,0.1)"
},
header: {
fontWeight: "bold",
fontSize: 18,
color: Theme.COLOURS.SUB_HEADER,
paddingVertical: 10
},
subText: {
color: Theme.COLOURS.SUB_TEXT
},
card: {
flex: 0.7,
height: 45,
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
borderRadius: 30,
backgroundColor: Theme.COLOURS.WHITE,
elevation: 5,
paddingLeft: 10
},
recent: {
flex: 0.3,
borderRadius: 30,
backgroundColor: Theme.COLOURS.WHITE,
elevation: 5,
},
confirmBtn: {
flex: 0.6,
width: 343,
borderRadius: 30,
elevation: 3
},
btnSelected: {
backgroundColor: Theme.COLOURS.BUTTON
},
textSelected: {
color: Theme.COLOURS.WHITE
}
})
Any advice as to why the list doesn't scroll?
Link to expo snack to see current state: Expo Snack

How do I center the text within the lightblue flexbox?

import React, { Component } from 'react';
import { View, Text, FlatList, TouchableOpacity, Dimensions, StyleSheet } from 'react-native';
const data = [
{id: 'Music', value: 'Music'},
{id: 'Events', value: 'Events'},
{id: 'About Us', value: 'About Us'},
{id: 'Benefits', value: 'Benefits'},
{id: 'Account', value: 'Account'},
{id: 'Social Media', value: 'Social Media'},
{id: 'FAQ', value: 'FAQ'},
{id: 'Settings', value: 'Settings'}
];
const numColumns = 2;
const size = Dimensions.get('window').width/numColumns;
export const Grid = () => {
return (
<FlatList
style={{ marginTop: 20 }}
data={data}
renderItem={({item}) => (
<TouchableOpacity style={styles.itemContainer}>
<Text style={styles.item}>{item.value}</Text>
</TouchableOpacity>
)}
keyExtractor={item => item.id}
numColumns={numColumns} />
);
}
const styles = StyleSheet.create({
itemContainer: {
width: size,
height: size
},
item: {
flex: 1,
margin: 15,
fontSize: 25,
fontWeight: 'bold',
color: 'white',
backgroundColor: 'lightblue'
}
});
I want to be able to center text in both axes
I tried using justifyContent: "center" in the child and parent views but it doesn't work.
textAlign: "center" is able to align the text horizontally.
try like this.
export const Grid = () => {
return (
<FlatList
style={{ marginTop: 20 }}
data={data}
renderItem={({item}) => (
<TouchableOpacity style={styles.itemContainer}>
<View style={styles.item}>
<Text style={styles.itemText}>{item.value}</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={item => item.id}
numColumns={numColumns} />
);
}
const styles = StyleSheet.create({
itemContainer: {
width: size,
height: size
},
item: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 15,
backgroundColor: 'lightblue'
},
itemText: {
fontSize: 25,
textAlign: 'center',
fontWeight: 'bold',
color: 'white',
}
});
Please attach a screenshot, asking questions about designing in react native. Coming to the answer you can try this.
item:{
alignSelf: 'center',
flex: 1,
margin: 15,
fontSize: 25,
fontWeight: 'bold',
color: 'white',
backgroundColor: 'lightblue'
},
itemContainer: {
width: size,
height: size,
justifyContent: 'center',
alignItems: 'center'
},
Your itemContainer class is missing the display: flex property. This is needed to use flexbox properties on the flex items.

Increment and Decrement quantity in ListView using react-native

I am running sample project. I want to display the increment and decrement values. In my project increment and decrement values are not displayed. How to change the values in text.
Here is my code:
constructor(props){
super(props);
this.state={
increment:0,
decrement:1
}
}
incrementFunc(){
var countIncrement = this.state.increment
this.setState({
increment : countIncrement + 1
},()=>{
alert(this.state.increment)
})
}
decrementFunc(){
var countDecrement = this.state.increment
this.setState({
decrement : countDecrement- 1,
},()=>{
alert(this.state.decrement)
})
}
<View style={styles.arrowsView}>
<TouchableOpacity onPress ={this.incrementFunc.bind(this)}>
<Image style={styles.arrowStyle} source={require('#images/up-arrow.png')} />
</TouchableOpacity>
</View>
<View style={styles.numberView}>
<Text style={{fontSize:15, color:'black'}}>{this.state.increment}
</Text>
</View>
<View style={styles.arrowsView}>
<TouchableOpacity onPress ={this.decrementFunc.bind(this)}>
<Image style={styles.arrowStyle} source={require('#images/down-arrow.png')} />
</TouchableOpacity>
</View>
here is my screenshot:
Please give any suggestion. Thank You
Here is the solution which i had made in my project , what i did
Firstly ->created an another component which will help us to have a quantity input functionality inside list element
Secondly ->This component needs to be called by the parent component inside list renderRow to make this component visible in all the rows.
and put this QuantityInput component class inside the same file where you want to use it...
Thirdly -> Run yours application and have a look like this...
Have a look to the file attached...
/*Use this component in yours parent view inside list to have a Quantity Input inside list , I have used native base as well if some thing gets miss please have native base in yours project...*/
{<QuantityInput item={this.state.data[rowID]} viewAddToCart={false} />}
/* QuantityInput */
class QuantityInput extends React.Component {
userProductQty = Array.apply(null, Array(this.props.item.length)).map(Number.prototype.valueOf, 1);
itemPosition = -1;
constructor(props) {
super(props);
this.state = {
viewAddToCart: this.props.viewAddToCart,
item: this.props.item,
style: { flex: 1 },
styleTextInput: { backgroundColor: '#ffffff' },
styleButton: { backgroundColor: '#000000' },
styleImage: { width: 12, height: 12 },
editable: true,
stepsize: 1,
initialValue: 1,
min: 1,
max: 100
}
}
upBtnPressed = (dataSource, fieldName) => {
if (dataSource.userQty < this.state.max) {
let value = (parseInt(dataSource.userQty) + parseInt(this.state.stepsize)).toString();
dataSource.userQty = value;
this.setState({
item: dataSource
});
}
}
downBtnPressed = (dataSource, fieldName, props) => {
if (dataSource.userQty < this.state.min) {
let value = (parseInt(dataSource.userQty) - parseInt(this.state.stepsize)).toString();
dataSource.userQty = value;
this.setState({
item: dataSource
});
}
}
onChangeText = (text, item, fieldName, itemPosition) => {
if (!isNaN(text)) {
item.userQty = text.toString();
this.setState({
item: item
});
} else {
item.userQty = 0;
this.setState({
item: item
});
}
}
render() {
return (
this.state.viewAddToCart ?
/* Add to cart */
<View style={[{ flexDirection: 'row' }]}>
<Left style={{ flex: 0 }}>
<Button rounded danger
title="Add"
color="white"
style={[{ width: 70 }, { height: 30 }, { justifyContent: 'center' }]}
onPress={() => { this.props.onAddToCart(this.state.item); this.setState({ viewAddToCart: false }) }}
>
<Text style={[{ color: 'white' }]}>{string.addToCart}</Text>
</Button>
{/*</TouchableOpacity>*/}
</Left>
</View>
:
/* Quantity Text */
<View style={{ flexDirection: 'row' }}>
<View style={stylesQuantityText.verticle}>
<TouchableOpacity style={[styles.button, styles.transparentBkg, { backgroundColor: '#d9534f' }, { paddingLeft: 10 }, { borderTopLeftRadius: 5 }, { borderBottomLeftRadius: 5 }, { justifyContent: 'center' }, { alignItems: 'center' }]} onPress={() => { this.downBtnPressed(this.state.item, this.state.item.productId); }} >
<Text style={[{ width: 20 }, { height: 26 }, { fontSize: 21 }, { alignSelf: 'center' }, { paddingBottom: 10 }, { fontWeight: 'bold' }]}>-</Text>
{/*<Icon name={"remove"} />*/}
</TouchableOpacity>
<TextInput
style={[stylesQuantityText.textinput, this.state.styleTextInput]}
editable={this.state.editable}
keyboardType={'numeric'}
text={this.state.item.userQty.toString()}
value={this.state.item.userQty.toString()}
ref={"Qty" + this.state.item.productId}
key={"Qty" + this.state.item.productId}
onChangeText={(text) => { this.onChangeText(text, this.state.item, this.state.item.productId); this.props.onAddToCart(this.state.item); }} />
<TouchableOpacity style={[styles.button, styles.transparentBkg, { backgroundColor: '#d9534f' }, { paddingLeft: 10 }, { borderTopRightRadius: 5 }, { borderBottomRightRadius: 5 }]} onPress={() => { this.upBtnPressed(this.state.item, this.state.item.productId); this.props.onAddToCart(this.props.item); }}>
{/*<Icon name={"add"}
size={27} />*/}
<Text style={[{ width: 20 }, { height: 26 }, { fontSize: 19 }, { alignSelf: 'center' }]}>+</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const stylesQuantityText = StyleSheet.create({
wrapper: {
flex: 1,
backgroundColor: '#eeeeee'
},
verticle: {
flexDirection: 'row',
paddingLeft: 0,
paddingRight: 0,
},
horizontal: {
flexDirection: 'row'
},
textinput: {
backgroundColor: '#eeeeee',
textAlign: 'center',
width: 30,
borderColor: 'black',
borderWidth: 1,
height: 26
},
button: {
backgroundColor: '#dedede',
padding: 5
},
image: {
width: 18,
height: 18
},
buttonText: {
alignSelf: 'center'
}
});
]1

Categories