React Native Dynamic Checkbox Inside Dynamic checkbox - checkbox

I have a app developed in React native and I need make a dinamic checkbox list inside other dynamic checkbox list, the first list works fine, but when i try to make the other dynamic checkbox list inside, this not show totally.
this is the code:
<View style ={styles.inside2}>
{
this.state.categorias.map((categoria) => {
return(
<View key={categoria.id}>
<CheckBox
title={categoria.nombre}
iconRight
checkedColor='red'
uncheckedColor='red'
checked={this.state.checkCategorias[categoria.id-1]}
containerStyle ={{backgroundColor: '#f7f7f7', borderColor: '#f7f7f7' }}
textStyle = {{fontSize: 12, color: '#787878' }}
checkedIcon = 'dot-circle-o'
uncheckedIcon = 'circle-o'
onPress = {(checked) => this.cambioCheckCat(categoria.id)}
/>
{
this.state.checkCategorias[categoria.id-1] ?
<View
style ={{backgroundColor: 'lightgray', width: '100%', height: '100%'}}
key ={categoria.id+'t'} >
<Text style = {styles.titulo2}>
Seleccione una o varias sub-categorias de {categoria.nombre}
</Text>
<View style={styles.separador} />
{
this.state.subcategorias.map((subcategoria) => {
if(subcategoria.id_categoria == categoria.id){
return(
<CheckBox
key={subcategoria.id+'s'}
title={subcategoria.nombre}
iconRight
checkedColor='red'
uncheckedColor='red'
checked={this.state.checkSubCategorias[i]}
containerStyle ={{backgroundColor: '#f7f7f7', borderColor: '#f7f7f7' }}
textStyle = {{fontSize: 12, color: '#787878' }}
checkedIcon = 'dot-circle-o'
uncheckedIcon = 'circle-o'
onPress = {(checked) => this.cambioCheckSub(subcategoria.id)}
/>
)
}
})
}
</View> : null
}
</View>
)
})
}
</View>
This show fine until the line "Selecciona una o varias categorias...", after i have a .map but this part simply not show.
EDIT:
Sorry I see my error, I have a get the data bad from the database, but the code works fine so I left this here in case somebody need make a dynamic into other dynamic.

Sorry I see my error, I have a get the data bad from the database, the code works fine, I left this here in case somebody need make a dynamic into other dynamic.

Related

react native custom picker set style not working

I developing a react native project.
I use react-native-custom-picker but when I try gives a Custom Picker style it's not working. my code like this below
//.. in CustomPicker.js
<CustomPicker
placeholder={labelDefault}
options={options}
getLabel={item => item.label}
optionTemplate={this.renderOption}
selectedValue={this.props.selectedValue}
onValueChange={this.onValueChangeCustomPicker}
textStyle={{color:colors.dark_black,fontSize:25}}--> Here is not work
/>
renderOption() function like this
renderOption(settings) {
const { item, getLabel } = settings
return (
<View style={styles.optionContainer}>
<View style={styles.innerContainer}>
<Text style={{ color: colors.dark_black, alignSelf: 'flex-start', fontSize: 24 }} key={item.key}>{item.label}</Text>
</View>
</View>
)
}
I know Picker style only support IOS.
What's my fault? Any idea!
can you try this code?
I don't know how you organized "options," but you can't work because you don't have any place to take the factors for "colors."
renderOptions:
const options = [
...
color: "black",
]
...
renderOption(settings) {
const { item, getLabel } = settings
return (
<View style={styles.optionContainer}>
<View style={styles.innerContainer}>
<Text style={{ color: item.color, alignSelf: 'flex-start', fontSize: 25 }} key={item.key}>{item.label}</Text>
</View>
</View>
)
}
<CustomPicker
placeholder={labelDefault}
options={options}
getLabel={item => item.label}
optionTemplate={this.renderOption}
selectedValue={this.props.selectedValue}
onValueChange={this.onValueChangeCustomPicker}
/>
I checked source code and documentation if I wanna give style placeholder I should use props for field template like this.
<CustomPicker
fieldTemplateProps={{textStyle:{color:"red",fontSize:22}}}
placeholder={'Please select your favorite item...'}
options={options}
getLabel={item => item.label}
optionTemplate={this.renderOption}
headerTemplate={this.renderHeader}
onValueChange={value => {
Alert.alert('Selected Item', value ? JSON.stringify(value) : 'No item were selected!')
}}
/>
it's worked in my project
more detail

react native search and scroll to hit

I need some help implementing a search and scroll to hit in react native. Did a lot of searches and ended up in some dead ends (found some refs examples I couldn't get to work).
Tried building this snippet as a kick-off:
https://snack.expo.io/#norfeldt/searching-and-scroll-to
import React, { Component } from 'react';
import { Text, View, ScrollView, TextInput, StyleSheet } from 'react-native';
export default class App extends Component {
state = {
text: '41'
}
render() {
return (
<View style={styles.container}>
<TextInput
style={{height: 60, borderColor: 'gray', borderWidth: 1, borderRadius: 10, margin: 5, padding:30, color: 'black', }}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
<ScrollView >
{[...Array(100)].map((_, i) => {return <Text style={styles.paragraph} key={i}>{i}</Text>})}
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 10,
backgroundColor: '#ecf0f1',
},
paragraph: {
margin: 10,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});
Any help getting started would be appreciated.
My guess would be:
You could start by binding a ref of your <ScrollView/>.
// ScrollView Ref.
<ScrollView ref={(ref) => this['ScrollView'] = ref}>
...
</ScrollView>
And each of your <Text/> components (by index).
// Text Refs.
<Text ref={(ref) => this[i] = ref} style={styles.paragraph} key={i}>{i}</Text>
You could then set a submit() function.
Said function could find the ref equal to this.state.text using a try catch statement for graceful failure in edge cases.
If found; target x and y offset could be retrieved using measure()
scrollTo() could then be called to scroll to the target component.
// Scroll To Query.
submit = () => {
try {
const { text } = this.state // Text.
const target = this[text] // Target.
// Locate Target.
target.measure((framex, framey, width, height, x, y) => {
// Scroll To Target.
this.ScrollView.scrollTo({x, y, animated: true})
})
} catch (error) {
return console.log(error)
}
}
First of all, I highly recommend you to use FlatList instead of ScrollView. There are a few reasons for this:
FlatList has much more optimized performance in comparison with ScrollView (in scroll view all items are rendered at once, regardless of the fact if they are visible on screen or not)
Moreover, the handling scrolling and rendered items is much simpler in FlatList, you do not need to know anything about x, y axis and pixels, you just work with indexes.
in order to have a comprehensive comparison between these two methods you may look at:
http://matthewsessions.com/2017/05/15/optimizing-list-render-performance.html
Now back to your question, as I said I suggest you to use FlatList, then everything will be as simple as a piece of a cake.
You can find modified example of your expo in:
https://snack.expo.io/HkMZS1SGz
The changes that you need to make in your code, include:
Instead of ScrollView use, FlatList, so change this:
<FlatList
ref={ref => {this.flatListRef = ref;}}
data={new Array(100).fill(0).map((item, index) => index)}
renderItem={({ item }) => (
<Text style={styles.paragraph}>
{item}
</Text>
)}
/>
If you are not already familiar with FlatList, you need to know, the data is added in data prop as an array (I added an array of 100 numbers), and the way it is rendered is given to FlatList as renderItemprop (I added the text with the same styling as you did).
Moreover, note that you do not need to pass ref to <Text>, because FlatList already knows about items that it contains. You just need to add a ref to the FlatList itself:
ref={ref => {this.flatListRef = ref;}}
Now when ever you want to make and scrolling, you can simple call scrollToIndex method of the FlatList, for example write a method called scrollHandler:
// Scroll to Query
scrollHandler = (itemIndex)=>{
this.flatListRef.scrollToIndex({animated: true, index: itemIndex});
}
just pay attention that,flatListRef is the name of the ref assigned to the FlatList.
now, when you want to perform scroll action, you can simply call this method. Forexample, modify your text input to:
<TextInput
style={{height: 60, borderColor: 'gray', borderWidth: 1,
borderRadius: 10, margin: 5, padding:30, color: 'black', }}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
onSubmitEditing={()=>this.scrollHandler(this.state.text)}
/>
Steps
Remember every item's position with onLayout.
scrollTo() position when text input, and only if item found.
Code
const styles = StyleSheet.create({
textinput: {
borderBottomColor: 'purple',
textAlign: 'center',
borderBottomWidth: 2,
height: 40,
marginTop: 20,
},
text: {
textAlign: 'center',
fontSize: 16,
margin: 10,
}
});
export class App extends Component {
data = [];
datapos = {};
scrollref = null;
constructor(props) {
super(props);
/// make 100s example data
for (var i =0; i<100; ++i)
this.data.push(i);
this.state = {
inputvalue: '0'
}
}
render() {
return (
<View style={{flex: 1}}>
<TextInput style={styles.textinput}
value={this.state.inputvalue}
onChangeText={(text) => {
this.setState({inputvalue: text});
let y = this.datapos[+text];
y !== undefined && this.scrollref.scrollTo({ y, animated: true });
}}
/>
<ScrollView
ref={(ref) => this.scrollref = ref}
>
{
this.data.map( (data) => (
<Text style={styles.text}
key={data}
onLayout={(layout) => this.datapos[data] = layout.nativeEvent.layout.y}
>{data}</Text>
))
}
</ScrollView>
</View>
)
}
}
Result:

Checked - Unchecked doesn't working in ListView - React Native

friend I Will integrated checked - unchecked in listView. So that When user click on checked then store the data in Array and unchecked then i will remove the data. Its working fine, But the UI Will not updated after checked - unchecked.
<List containerStyle={{marginTop : 0 , borderBottomWidth : 0 , borderBottomColor : 'black', borderTopWidth : 0}}>
<FlatList
data={this.state.list}
renderItem={({ item }) => (
<ListItem containerStyle={{height: 80, backgroundColor : 'transparent', borderBottomWidth : 0, borderTopWidth : 0}}
title={
<View style={styles.titleView}>
<Text style={styles.ratingText}>{item.iWorkerID.vFirstName}</Text>
</View>
}
rightIcon={
<TouchableOpacity onPress = {() => this.selectedWorker(item)} style={{width: 30, height: 30 , marginTop : 10, marginRight : 30}}>
<Image style = {{width: 30, height: 30}} source={this.state.selectedList.includes(item) ? require("./Images/uncheckd.png") : require("./Images/checked.png")}/>
{/* {this.state.selectedList.includes(item) && <Image style = {{width: 30, height: 30}} source={require("./Images/uncheckd.png")}/>}
{!this.state.selectedList.includes(item) && <Image style = {{width: 30, height: 30}} source={require("./Images/checked.png")}/>} */}
</TouchableOpacity>
}
avatar={<Avatar
rounded
medium
containerStyle={{marginLeft: 30}}
source={{uri: Globle.IMAGE_URL+item.vProfileImage}}
activeOpacity={0.7}
/>}
/>
)}
/>
</List>
And on the check/uncheck button, I will add/remove object from array,
selectedWorker = (data) =>{
console.log('data is ', data);
if (!this.state.selectedList.includes(data)) {
// this.setState({ selectedList : [...this.state.selectedList , data]})
this.state.selectedList.push(data);
} else {
var index = this.state.selectedList.indexOf(data);
if (index > -1) {
this.state.selectedList.splice(index, 1);
}
}
this.setState({list : this.state.list})
console.log('selected list' , this.state.selectedList);
}
Main Issue : Want to update image checked/unchecked according to selectedList array, How can i Update item in listView.
What to do inside selectedWorker method.
GIF :
you are using Flatelist inside List, Both are a component to listing items. you can use List or Flatelist, not both.
I hope it will help you..
I try to make Demo similar to that you want.
constructor(props) {
super(props)
this.state = {
list: [
{
id: 1,
name: "Harpal Singh Jadeja",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
},
{
id: 2,
name: "Kirit Mode",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
},
{
id: 3,
name: "Rajiv Patil",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
},
{
id: 4,
name: "Chetan Doctor",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
}]
};
};
renderListItem = (index, item) => {
return (
<View style={styles.notification_listContainer}>
<Image source={{uri: item.avtar, cache: 'force-cache'}}
style={circleStyle}/>
<View style={{flex: 1, paddingLeft: 10, justifyContent: 'center'}}>
<Label roboto_medium
align='left'
color={Color.TEXT_PRIMARY}
numberOfLines={1}>
{item.name}
</Label>
<Label roboto_medium
small
align='left'
color={Color.TEXT_SECONDARY}
mt={8}>
Programmer
</Label>
</View>
<View style={{justifyContent: 'center'}}>
<TouchableHighlight
style={{
backgroundColor: item.isSelected ? Color.BLACK : Color.TEXT_SECONDARY,
alignItems: 'center',
justifyContent: 'center',
height: 40,
width: 40,
borderRadius: 20
}}
onPress={this.onSelectWorker.bind(this, index, item)} underlayColor={Color.BLACK}>
<Icon name='done'
size={20}
color={Color.WHITE}/>
</TouchableHighlight>
</View>
</View>
);
};
onSelectWorker = (index, item) => {
console.log("Selected index : ", index);
let tempList = this.state.list;
tempList[index].isSelected = tempList[index].isSelected ? false : true
this.setState({
list: tempList
});
};
render() {
return (
<View style={styles.notification_Container}>
<FlatList
data={this.state.list}
renderItem={
({index, item}) => this.renderListItem(index, item)
}
keyExtractor={item => item.id}
extraData={this.state}
/>
</View>
)
}
You need to add a key to your ListItem which is based on a unique id of the item, so that React can distinguish between the items rendered.
When you use index of an array as a key, React will optimize and not render properly. What happens in such a scenario can be explained with an example.
Suppose React renders an array of 10 items and renders 10 components. Suppose the 5th item is then removed. On the next render React will receive an array of 9 items and so React will render 9 components. This will show up as the 10th component getting removed, instead of the 5th, because React has no way of differentiating between the items based on index.
Therefore always use a unique identifier as a key for components that are rendered from an array of items.

Update child components based on parent state

I'm new to react, I'm running into what I'm pretty sure is a common problem with a common solution but, because I'm new to the idea of React, I have no idea how to solve it.
Using the following as an example, how can I get my children to re-render whenever the TouchableWithoutFeedback callbacks are called? (Don't tell me to use a different component, this idea can be applied to lots of parent-child relationships - when something happens on a parent, re-render the children).
<TouchableWithoutFeedback
onPressIn={() => { /* what do I do here */ }}
onPressOut={() => { /* what do I do here */ }}
>
<View
style={{
backgroundColor: /* if touchable is highlighted black, otherwise white */
}}
>
<Text
style={{
color: /* if selected, then white, otherwise, black */
}}
>
Some Text
</Text>
</View>
</TouchableWithoutFeedback>
It seems a bit verbose to have to write custom components (so I can just call setState() every time I need this kind of functionality, do I really have to?)
Your onPressIn() and onPressOut() methods should update the state of your component. When a component's state is changed, the render() method is called and the component is re-rendered. If the component's children's properties have changed due to the update in state, then they will be re-rendered as well.
In your specific case you should do the following:
Add a state to your component. Somewhere in the component definition add state = { pressed: false }
Update the state with your onPress methods and use the state when setting the properties of your component's children:
<TouchableWithoutFeedback
onPressIn={() => { this.setState({pressed: true}) }}
onPressOut={() => { this.setState({pressed: false}) }}
>
<View
style={{
backgroundColor: (this.state.pressed) ? 'black' : 'white'
}}
>
<Text
style={{
color: (this.state.pressed) ? 'white' : 'black'
}}
>
Some Text
</Text>
</View>
</TouchableWithoutFeedback>
The above was tested in React Native 0.48 on an Android device.
As a rough example you would update the state on those callbacks and pass it as prop to your children components in the render method.
For example :
this.state = { isHighlighted: false }; // inside the parent component constructor
render() {
const { isHighlighted } = this.state;
return (
<div>
<FirstChild style={{ backgroundColor: isHighlighted ? 'black' : 'white' }}>
<SecondChild style={{ color: isHighlighted ? 'white' : 'black' }}>Some text</SecondChild>
</FirstChild>
</div>
);
}
and the callbacks would be :
onPressIn={() => { this.setState({ isHighlighted: true }) }}
onPressOut={() => { this.setState({ isHighlighted: false }) }}
If you would want to have style through nested components you would have to :
a) keep passing them as props
b) hold your state in a store (https://github.com/reactjs/redux)
In your constructor :
this.state={pressedIn:false,onPressOut:false}
Then
<TouchableWithoutFeedback
onPressIn={() => { this.setState({pressedIn:true,pressedOut:false}}
onPressOut={() => { {this.setState({pressedOut:true,pressedIn:false}}
>
<View
style={{
backgroundColor: this.state.pressedIn? "someColor":"SomeOtherColor"
}}
>
<Text
style={{
color: this.state.onPressOut? "someColor":"SomeOtherColor"
}}
>
Some Text
</Text>
</View>
</TouchableWithoutFeedback>

React Native move navigator text

Hey In react native I'm using and Everything works well so far but the title and the back button text don't line up. (The login is higher then register) Any ideas how I could set this up?
render() {
const titleConfig = {
title: 'login',
tintColor: "white",
}
return(
<View style={styles.bb}>
<NavigationBar
title={titleConfig}
tintColor="black" />
</View>
)
}
You can pass in a react element to title prop with styling to make it align as per your requirements. For e.g:
render() {
const title = <View style={styles.navTitle}>
<Text style={styles.navTitleText}>Login</Text>
</View>;
return (
<View style={styles.bb}>
<NavigationBar
title={title}
tintColor="black"
/>
</View>
);
}
var styles = StyleSheet.create({
navTitleText: {
color: "white",
fontSize: 19,
marginBottom: 4,
}
});
Here's the complete guide about the API https://github.com/react-native-fellowship/react-native-navbar#api

Resources