Adding item click event in react native Grid View - reactjs

Please find my code below and help me for adding item click listener for the items in the grid view. Please find the link which I followed library link.
And I need to display the name in an alert when the user clicks on each item in the gridlist. Styles are not included in the code
Thanks in Advance
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableWithoutFeedback
} from 'react-native';
import GridLayout from 'react-native-layout-grid';
class HomeScreen extends Component {
renderGridItem = (props) => (
<View style={styles.item} >
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</View>
);
render() {
const items = [];
for (let x = 1; x <= 30; x++) {
items.push({
name: `Grid ${x}`
});
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Grid Layout
</Text>
<View style={styles.flex}>
<GridLayout
items={items}
itemsPerRow={2}
renderItem={this.renderGridItem}>
</GridLayout>
</View>
</View>
);
}
}
export default HomeScreen;

Instead of using <View> in your renderGridItem, you could use one of the touchables component (react native doc).
For example with <TouchableOpacity >:
renderGridItem = (props) => (
<TouchableOpacity style={styles.item} onPress={() => this.showAlert(props.name)}>
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</TouchableOpacity>
);
showAlert = (name) => {
Alert.alert(
'Alert Title',
`The user name is: ${name}`,
[
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
}

Why don't you wrap renderGridItem in a TouchableWithoutFeedback?
renderGridItem = (props) => (
<TouchableWithoutFeedback onPress={()=> Alert.alert(props.name)}>
<View style={styles.item} >
<View style={styles.flex} />
<Text style={styles.name} >
{props.name}
</Text>
</View>
<TouchableWithoutFeedback />
);
Also you will need to import Alert from react-native.

Related

Navigation from menu item

I'm trying to get a menu item to navigate to another page but for some reason it wont let me do it. I'm a little confused as to how you go about it and any help is welcome!
Import here:
import { NavigationScreenProp } from "react-navigation";
Here is more code:
interface NotificationDropdownProps {
navigation: NavigationScreenProp<any, any>;
}
Here is where function is called:
function renderNotification(notification: INotification) {
return (
<MenuOption
onSelect={() => {
if (notification.type == INotificationType.SYSTEM) {
this.testFunction();
}
}}
>
<View style={[styles.notificationContainer]}>
<View style={styles.iconArea}>
<View style={[styles.iconCircle]}>
<Icon
name={this.getIconType(notification.type)}
color={this.notificationColor(notification.type)}
size={26}
/>
</View>
</View>
<View>
<Text>{notification.text}</Text>
<Text>
{this.getDate(new Date(notification.dateCreated))}
</Text>
</View>
</View>
</MenuOption>
);
}
Test Function:
testFunction(){
this.props.navigation.navigate('NextPage')
};
Error:
undefined is not an object(evaluating'_this2.props.naviagtion.navigate)
Where the function is called:
<View>
<Text>
Notifications
</Text>
{this.props.notifications.length > 0 ? (
<FlatList
contentContainerStyle={{ borderRadius: 10 }}
data={this.props.notifications.slice(0, 5)}
renderItem={({ item }) => this.renderNotification(item)}
keyExtractor={this.keyExtractor}
/>
) : (
<Text>No Notifications!</Text>
)}
</View>;
try with an arrow function to avoid using the context of the function.
testFunction = () => {
this.props.navigation.navigate('NextPage')
};

Filtering simple Flatlist

I want to filter this simple flatlist through a search bar. How do I code it so that whatever I write something on the input text it filters the flatlist? Could you help me completing it?
import React from 'react';
import { StyleSheet, Text, View, SafeAreaView, TextInput, TouchableOpacity, LayoutAnimation, Image, FlatList, ScrollView } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import {ListItem, SearchBar} from 'react-native-elements';
export default class HomeScreen extends React.Component{
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>Home</Text>
</View>
<View style={styles.container1}>
<Icon name={"ios-search"} style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "white"
selectionColor="black"
keyboardType="default"
/>
</View>
<View style={styles.flatlist}>
<FlatList
data = {[
{key:'Tiago'},
{key:'Ricardo'},
{key:'Beatriz'},
{key:'Miguel'},
{key:'Simão'},
{key:'David'}
]}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
</View>
);
}
}
You should have a state value for searchtext and filter the array based on that. the component should be as below.
export default class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
searchText: '',
};
}
render() {
//Data can be coming from props or any other source as well
const data = [
{ key: 'Tiago' },
{ key: 'Ricardo' },
{ key: 'Beatriz' },
{ key: 'Miguel' },
{ key: 'Simão' },
{ key: 'David' },
];
const filteredData = this.state.searchText
? data.filter(x =>
x.key.toLowerCase().includes(this.state.searchText.toLowerCase())
)
: data;
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerTitle}>Home</Text>
</View>
<View style={styles.container1}>
<Icon name={'ios-search'} style={styles.icon} />
<TextInput
style={styles.inputBox}
underlineColorAndroid="rgba(0,0,0,0)"
placeholderTextColor="white"
selectionColor="black"
keyboardType="default"
onChangeText={text => this.setState({ searchText: text })}
value={this.state.searchText}
/>
</View>
<View style={styles.flatlist}>
<FlatList
data={filteredData}
renderItem={({ item }) => (
<Text style={styles.item}>{item.key}</Text>
)}
/>
</View>
</View>
);
}
}
Please provide flatlist data from the state so you can control it while searching. Assuming if you want to bring those results at the top that matches your search text, you can do something like the below code. Firstly add onChangeText prop to the textinput and handle the input like this.
filterItems = (search_text) => {
var items = [...this.state.data];
var filtered = [];
if (search_text.length > 0) {
filtered = items.sort(
(a, b) => b.includes(search_text) - a.includes(search_text),
);
this.setState({data: filtered});
} else {
filtered = items.sort((a, b) => b - a);
this.setState({data: filtered});
}
};

How to show Modal in React Native using Functional Component imported from another file

I am showing a view Login.js and in that view on button click, I need to render modal, that I have separated and written in another file named Countries.js.
On Login.js file I have imported Countries.js and on button click, I am doing this:
show_modal = () => {
<Countries/>
}
but nothing is happening. I am a noob I just started React Native kindly help me.
Countries.js code:
import React, { Component, useState } from "react";
import {
Alert,
Modal,
Text,
TouchableHighlight,
View
} from "react-native";
const Countries = () => {
console.log('called');
const [modalVisible, setModalVisible] = useState(true);
return (
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: "#2196F3" }}
onPress={() => {
setModalVisible(!modalVisible);
}}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
<TouchableHighlight
style={styles.openButton}
onPress={() => {
setModalVisible(true);
}}
>
<Text style={styles.textStyle}>Show Modal</Text>
</TouchableHighlight>
</View>)
};
export default Countries;
Login.js
import React, { Component, useState } from "react";
import {Modal, View, Text, TouchableHighlight} from 'react-native';
import CountryModal from 'path to outsource country modal file';
const login = (props)=>{
const [modalVisible, setModalVisible] = useState(true);
return(
<View>
<TouchableHighlight
style={styles.openButton}
onPress={() => {
setModalVisible(true);
}}
>
<Text style={styles.textStyle}>Show Modal</Text>
</TouchableHighlight>
<CountryModal isVisible={modalVisible} setModalVisiblity = {()=>{setModalVisible(preState=> preState = !preState)}}>
</View>
)
}
export default login;
Country Modal file
import React from react;
import {Modal} from 'react-native';
const Country = (props)=>{
return (
<Modal
animationType="slide"
transparent={true}
visible={isVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: "#2196F3" }}
onPress={() => {props.setModalVisiblity
}}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
)
}
Hope you got your answer.
Change this
show_modal = ()=> {
<Countries/>
}
to this
show_modal = ()=> {
return <Countries/>; // add return keyword
}
the above function will return undefined if return id not explicitly defined
You need to have this modal directly with other components.
Example code
export default function Login() {
const [modalVisible, setModalVisible] = useState(false);
return (
<View>
<Button title="Toggle Modal" onPress={() => setModalVisible(!modalVisible)}
// other login page code
<Countries visible={visible} /> // or any other modal, add direclty to the screen you need to show the modal at
</View>
)
}

Searching doesn't change backgroundcolor

I am trying to make a background color to change on my flatist whenever I press the search bar to make an input. When testing by making searchBarFocused:true an error pops up saying Undefined is not an object (evaluating 'this.state').
Here is the full code of the SearchScreen.js:
import React from 'react';
import { ScrollView, StyleSheet, TextInput, Text, View, FlatList, Keyboard, Image, TouchableOpacity, TouchableWithoutFeedback} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import * as Animatable from 'react-native-animatable';
const listItems = ['Meo Sudoeste', 'Vodafone Paredes de Coura', 'Super Bock Super Rock', 'NOS Primavera Sound', 'Rock in Rio', 'EDP Cool Jazz']
function SearchScreen({navigation}) {
state={
searchBarFocused: true
}
return (
<View style={styles.screen}>
<Animatable.View animation='slideInLeft' duration={500} style={styles.container}>
<Icon name='ios-search' style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</Animatable.View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
//I took this part off because it is irrelevant
</ScrollView>
<FlatList
style={{backgroundColor:this.state.searchBarFocused?'rgba(0,0,0,0.3)':'white'}}
data = {listItems}
renderItem={({item}) => <Text style = {{ padding:20, fontSize:20}}>{item}</Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
}
SearchScreen.navigationOptions = {
title: 'Procurar',
};
const styles = StyleSheet.create({
//Took this part off, its irrelevant
export default SearchScreen;
Why am I getting this error and can I correct it? Please help me
You're using functional component in your codebase, so you should use React Hooks to handle states.
import React, {useState} from 'react'
function SearchScreen({navigation}) {
const [searchBarFocused, setSearchBarFocused] = useState(false)
return (
<View style={styles.screen}>
<Animatable.View animation='slideInLeft' duration={500} style={styles.container}>
<Icon name='ios-search' style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</Animatable.View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
//I took this part off because it is irrelevant
</ScrollView>
<FlatList
style={{backgroundColor:searchBarFocused?'rgba(0,0,0,0.3)':'white'}}
data = {listItems}
renderItem={({item}) => <Text style = {{ padding:20, fontSize:20}}>{item}</Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
}
Otherwise, if you want to use Class components, then you can use class members as states.
class SearchScreen extends React.Component {
state={
searchBarFocused: true
}
return (
<View style={styles.screen}>
<Animatable.View animation='slideInLeft' duration={500} style={styles.container}>
<Icon name='ios-search' style={styles.icon}/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Procura aqui"
placeholderTextColor = "black"
selectionColor="black"
keyboardType="default"/>
</Animatable.View>
<View style={styles.teste}>
<Text style={styles.festivais}>Recomendados</Text>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.festivais_lista}>
//I took this part off because it is irrelevant
</ScrollView>
<FlatList
style={{backgroundColor:this.state.searchBarFocused?'rgba(0,0,0,0.3)':'white'}}
data = {listItems}
renderItem={({item}) => <Text style = {{ padding:20, fontSize:20}}>{item}</Text>}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
}
to use this.state you should have a class based component or use Hook instead for your functional component

How can i add images to the react-native-layout-grid? There are no props mentioned specifically in the Github repository

I am using the react-native-layout-grid package for displaying a grid layout. I want to add images in the grid layout instead of text/string. How can i do it?
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
} from 'react-native';
import GridLayout from 'react-native-layout-grid';
export default class App extends Component<{}> {
renderGridItem = (item) => (
<View style={styles.item}>
<View style={styles.flex} />
<Text style={styles.name}>
{item.name}
</Text>
</View>
);
render() {
const items = [];
for (let x = 1; x <= 30; x++) {
items.push({
name: `Grid ${x}`
});
}
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Grid Layout
</Text>
<View style={styles.flex}>
<GridLayout
items={items}
itemsPerRow={3}
renderItem={this.renderGridItem}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
///styles///
});
I need to add images instead of string texts being passed into props.Is there any way to do so? Thanks in advance.
In renderGridItem add the images
Eg:---
renderGridItem = (item) => (
<View style={styles.item}>
<View style={styles.flex} />
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
<Text style={styles.name}>
{item.name}
</Text>
</View>
);
working eg: https://snack.expo.io/#msbot01/petrified-tortillas

Resources