how to display item selected from searchable dropdown in react native? - react-native

I want year to be displayed on selection from dropdown list.
In this, selected item is being shown as alert I want to set text to the search box.
Here is the code:
import React, { useState, useEffect } from "react";
import {
StyleSheet,
SafeAreaView,
Text,
View,
TextInput,
Image,
Button,
FlatList,
TouchableOpacity,
} from "react-native";
import SearchableDropdown from "react-native-searchable-dropdown";
const years = [
{ id: 1, name: "2021" },
{ id: 2, name: "2020" },
{ id: 3, name: "2019" },
{ id: 4, name: "2018" },
{ id: 5, name: "2017" },
{ id: 6, name: "2016" },
{ id: 7, name: "2015" },
];
export default function Year() {
console.log("App Executed");
return (
<SafeAreaView>
<Text style={styles.headingText}>Select Year</Text>
<SearchableDropdown
onTextChange={(text) => console.log(text)}
// On text change listner on the searchable input
onItemSelect={(year) => alert(JSON.stringify(year))}
// onItemSelect called after the selection from the dropdown
containerStyle={{ padding: 5 }}
// suggestion container style
textInputStyle={{
// inserted text style
padding: 12,
borderWidth: 1,
borderColor: "#ccc",
backgroundColor: "#FAF7F6",
}}
itemStyle={{
// single dropdown item style
padding: 10,
marginTop: 2,
backgroundColor: "#FAF9F8",
borderColor: "#bbb",
borderWidth: 1,
}}
itemTextStyle={{
// text style of a single dropdown item
color: "#222",
}}
itemsContainerStyle={{
// items container style you can pass maxHeight
// to restrict the items dropdown hieght
maxHeight: "50%",
}}
items={years}
// mapping of item array
defaultIndex={"eg:2021"}
// default selected item index
placeholder="eg:2021"
// place holder for the search input
resetValue={false}
// reset textInput Value with true and false state
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
padding: 10,
},
titleText: {
padding: 8,
fontSize: 16,
textAlign: "center",
fontWeight: "bold",
},
headingText: {
padding: 10,
},
});

I was unable to use state
here is the solution
const years = [
{ id: 1, name: "2021" },
{ id: 2, name: "2020" },
{ id: 3, name: "2019" },
{ id: 4, name: "2018" },
{ id: 5, name: "2017" },
{ id: 6, name: "2016" },
{ id: 7, name: "2015" },
];
export default function Year() {
const [selectedItems, setSelectedItems] = useState();
console.log("App Executed");
return (
<SafeAreaView>
<SearchableDropdown
onTextChange={(text) => console.log(text)}
// On text change listner on the searchable input
selectedItems={selectedItems}
onItemSelect={(year) => setSelectedItems(year)}
// onItemSelect called after the selection from the dropdown
containerStyle={{ padding: 5 }}
// suggestion container style
textInputStyle={{
// inserted text style
padding: 12,
borderWidth: 1,
borderColor: "#ccc",
backgroundColor: "#FAF7F6",
}}
itemStyle={{
// single dropdown item style
padding: 10,
marginTop: 2,
backgroundColor: "#FAF9F8",
borderColor: "#bbb",
borderWidth: 1,
}}
itemTextStyle={{
// text style of a single dropdown item
color: "#222",
}}
itemsContainerStyle={{
// items container style you can pass maxHeight
// to restrict the items dropdown hieght
maxHeight: "50%",
}}
items={years}
// mapping of item array
defaultIndex={"eg:2021"}
// default selected item index
placeholder="eg:2021"
// place holder for the search input
resetValue={false}
// reset textInput Value with true and false state
/>
</SafeAreaView>
);
}

I SLOVED THAT BY THIS TRICK WAY:
const getTypeNameById_func = async id => {
const dataa = await accountsType.find(item => {
if (item.ID == id)
return item.NAME;
});
setTextSearchable(dataa.NAME);
};
AND IN SEARCHABLE DROPDOWN :
<SearchableDropdown
items={filterData}
placeholder={String(**textSearchable**)}
resetValue={false}
underlineColorAndroid="transparent"
onTextChange={text => console.log(text)}
onItemSelect={item => {
getTypeNameById_func(item.id);
setAccountType(item.id);
}}
defaultIndex={1}
/>

u can use useState variable and pass that variable in placeholder like:-
placeholder={variableName}

Related

Adding data to FlatList clears the whole list

I am new to react-native. I have a flatlist, that takes data from "state". This works. Then, I added a new function in order to add new data to the flatlist (additionally to the existing data).
As soon as I click on the "delete" button ( don't mind the name) the data of the flatlist is being deleted completely. I want the output to be like
Object 1
Object 2
Object 3 (has been added after button click)
What am I doing wrong? Can you please explain me the reason?
EDIT: I get this warning, but no error.
VirtualizedList: missing keys for items, make sure to specify a key or
id property on each item or provide a custom keyExtractor.,
import React, { Component } from "react";
import { Text, View, StyleSheet, Button, FlatList } from "react-native";
class App extends Component {
state = {
counter: 0,
initialElements: [
{ id: "0", text: "Object 1" },
{ id: "1", text: "Object 2" },
],
};
render() {
const currentCounter = this.state.counter;
const exampleState = this.state.initialElements;
const addElement = () => {
let newArray = [...exampleState, { id: "2", text: "Object 3" }];
this.setState({
initialElements: [newArray],
});
};
return (
<View style={styles.container}>
<View style={styles.counter}>
<Text style={styles.textStyle}>{currentCounter}</Text>
</View>
<View style={styles.deleteButton}>
<Button
title="Hello"
onPress={() =>
this.setState({
counter: currentCounter + 1,
})
}
></Button>
<View style={styles.space}></View>
<Button title="Delete" onPress={addElement}></Button>{" "}
{/* as soon as I click here, the content of the list is being deleted */}
</View>
<FlatList
style={styles.listStyle}
key={(item) => item.id}
data={exampleState}
renderItem={(item) => <Text>{item.item.text}</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#fff",
justifyContent: "center",
flex: 1,
flexDirection: "column",
alignItems: "center",
},
counter: {
flexDirection: "row",
justifyContent: "center",
},
deleteButton: {
flexDirection: "row",
margin: 5,
marginTop: 100,
},
space: {
width: 5,
height: 5,
},
textStyle: {
margin: 80,
fontSize: 100,
},
listStyle: {
flexDirection: "column",
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
});
export default App;
I fixed it by changing the addElement to function to:
const addElement = () => {
var newArray = [...exampleState, {id : 2, text : "Object 3"}];
this.setState( {
initialElements: newArray
});
}
So, basically I changed
initialElements: [newArray]
to
initialElements: newArray
because newArray is already an Array, so no need to wrap it again.

How to break line of multiple Text List Items when they exceeds it container size?

I am developing a react native app. In the app, I have a iterator mapping multiples types that are show inside a View. Each of these types have an specific color, so that is why I have an each tag for each type.
I have made a simplified example what I want and what is happening.
I want when the Text List Items exceeds its container, that they break to a new line. I tried many ways but don't discover how to do it.
The example: https://snack.expo.dev/#anschau/multiple-text-problem-not-breaking-line
The code:
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const LabelTypes = [
{
styleType: "styleType1",
label: "Extensive Type 1",
},
{
styleType: "styleType2",
label: "Another Extensive Type 2",
},
{
styleType: "styleType3",
label: "Type 3",
},
{
styleType: "styleType4",
label: "Type 4",
},
{
styleType: "styleType5",
label: "Type 5",
},
{
styleType: "styleType6",
label: "Type 6",
},
];
const App = () => {
return (
<View style={[styles.container, {
flexDirection: "row"
}]}>
{
LabelTypes.map((item, index) => (
<>
{ index > 0 && <Text> - </Text>}
<Text style={[styles.label, styles[item.styleType] ]}>{item.label}</Text>
</>
))
}
</View>
);
};
const styles = StyleSheet.create({
container: {
maxWidth: "100%",
marginTop: 50,
marginLeft: 20,
marginRight: 20,
borderWidth: 1,
borderColor: "gray"
},
label: {
color: "black",
},
styleType1: {
color: "blue"
},
styleType2: {
color: "red"
},
styleType3: {
color: "green"
},
styleType4: {
color: "orange"
},
styleType5: {
color: "coral"
},
styleType6: {
color: "pink"
},
});
export default App;
Add to your container's (NOT individual labels') style:
flexWrap: 'wrap'
This will simply let items fill the container's width and fall into a new line when it doesn't fit.

Current Location issue in react-native-google-places-autocomplete

I am using react-native-google-places-autocomplete to get places suggestions based on user's current location. And it is working fine but the only issue I am facing is that whenever the 'Current Location' button is clicked, it sets the input field with value 'Current Location' and then shows the location results in the form of the list below it.
I don't want it to set currentLocationLabel value in the input field.
Here's my Code:
import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
navigator.geolocation = require('#react-native-community/geolocation');
const LocationAutocompleteScreen = props => {
return (
<GooglePlacesAutocomplete
placeholder='Search Location...'
minLength={3}
autoFocus={true}
returnKeyType={'search'}
listViewDisplayed='auto'
fetchDetails={true}
onPress={(data, details = null) => {
const locParam = {
description: data.description,
placeId: data.place_id,
location: details.geometry.location
}
props.navigation.navigate('LocationSearch', {locParam} )
}}
getDefaultValue={() => {
return '' // text input default value
}}
query={{
key: 'API_KEY',
language: 'en',
components: 'country:in',
}}
styles={{
textInputContainer: {
backgroundColor: '#fff',
borderTopWidth: 0,
borderBottomWidth: 0,
marginTop: 16,
marginHorizontal: 16
},
textInput: {
marginLeft: 0,
marginRight: 0,
padding: 8,
minHeight: 30,
color: '#000000',
fontSize: 16,
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {
paddingHorizontal: 8
},
description: {
fontWeight: '700',
letterSpacing: 0.5,
color: '#5d5d5d'
}
}}
currentLocation={true}
currentLocationLabel='Current Location'
nearbyPlacesAPI='GoogleReverseGeocoding' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
//renderDescription={row => row.description || row.formatted_address || row.name}
// GoogleReverseGeocodingQuery={{
// // available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
// }}
// GooglePlacesSearchQuery={{
// // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
// rankby: 'distance',
// types: 'food'
// }}
//filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
/>
);
}
export default LocationAutocompleteScreen;

React Native - Search an array off Object using react hooks

I have an array off Object inside a variable named data.
The array looks like this:
const data = [
{
"id": "0.804802585702977",
"value": "Bar",
},
{
"id": "0.9359341974615858",
"value": "Mar",
},
{
"id": "0.4182922963461958",
"value": "Naba",
},
{
"id": "0.6132336648416628",
"value": "Socerr",
},
{
"id": "0.060587558948085984",
"value": "Mall",
},
]
I want to create a search bar to search all the value inside that array and if the search text is equal to the value inside that array the user will be able to see that value?
Please help?
You need to use filter function to search/Sort data from Array. Please check following it may solve you problem.
import React, { useState } from "react";
import { Text, TextInput, View, StyleSheet } from "react-native";
import Constants from "expo-constants";
// You can import from local files
import AssetExample from "./components/AssetExample";
// or any pure javascript modules available in npm
import { Card } from "react-native-paper";
const data = [
{
id: "0.804802585702977",
value: "Bar",
},
{
id: "0.9359341974615858",
value: "Mar",
},
{
id: "0.4182922963461958",
value: "Naba",
},
{
id: "0.6132336648416628",
value: "Socerr",
},
{
id: "0.060587558948085984",
value: "Mall",
},
];
export default function App() {
let [filteredData, setFilteredData] = useState(data);
function _searchFilterFunction(searchText, data) {
let newData = [];
if (searchText) {
newData = data.filter(function(item) {
const itemData = item.value.toUpperCase();
const textData = searchText.toUpperCase();
return itemData.includes(textData);
});
setFilteredData([...newData]);
} else {
setFilteredData([...data]);
}
}
return (
<View style={styles.container}>
<Text style={styles.paragraph}>Search Here.</Text>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
placeholder="Search"
placeholderTextColor="#9a73ef"
autoCapitalize="none"
onChangeText={(value) => {
_searchFilterFunction(value, data);
}}
/>
{filteredData.map((item, index) => {
return <Text style={styles.paragraph}>{item.value}</Text>;
})}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: "#ecf0f1",
padding: 8,
},
input: {
margin: 15,
height: 40,
paddingLeft: 10,
borderRadius: 2,
borderColor: "#7a42f4",
borderWidth: 1,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: "bold",
textAlign: "center",
},
});

Exporting an array to feed data to separate component

I have dataset, which looks like this:
var items = [
{
id: 1,
name: 'foo',
email: 'foo'
},
{
id: 2,
name: 'foo',
email: 'foo'
},
{
id: 3,
name: 'foo',
email: 'foo'
},
];
module.exports = items;
I'm feeding this data to searchable dropdown, so the data will be visible within the dropdown
The dropdown component, looks like this:
<SearchableDropdown
onItemSelect={(item) => {
const items = this.state.selectedItems;
items.push(item)
this.setState({ selectedItems: items });
}}
containerStyle={{ padding: 5 }}
onRemoveItem={(item, index) => {
const items = this.state.selectedItems.filter((sitem) => sitem.id !== item.id);
this.setState({ selectedItems: items });
}}
itemStyle={{
padding: 10,
marginTop: 2,
backgroundColor: '#ddd',
borderColor: '#bbb',
borderWidth: 1,
borderRadius: 5,
}}
itemTextStyle={{ color: '#222' }}
itemsContainerStyle={{ maxHeight: 140 }}
items={items}
defaultIndex={null}
resetValue={false}
textInputProps={
{
placeholder: "Choose priority level",
underlineColorAndroid: "transparent",
style: {
padding: 12,
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 5,
},
onTextChange: text => console.log(text)
}
}
listProps={
{
nestedScrollEnabled: false,
}
}
/>
</Fragment>
And I imported the dataset with the following import:
import items from '../components/items';
However I'm getting that element type is invalid excepted a string but got object, I've tried previous threads from stackoverflow however nothing seems to solve my problem. Perhaps I'm missing something small that my eyes can't pick up? Any help appreciated.
First, you have to export the array as variable like
items.js
export const items = [
...
...
]
import it into your component.js like as
import {items} from '../path/to/items';
Just for confirmation log it inside your render method
console.log('Array Items', item);
Hope this will help you.