React-native-collapsible: Touchable Components in header prevent Accordion from opening/closing

Created on 8 Dec 2017  路  6Comments  路  Source: oblador/react-native-collapsible

i am using accordion component in my app

i am using '+' icon in header of accordion opposite side to heading of headertext ...
i want when the user tap on accordion then the '+' will convert to '-'.
unable to find any method ..
PS: lets suppose i have 4 accordion list when the click on first list then the icon sign will only change for first list ,rest of the same sign ..

here is my code;

import React,{Component} from 'react';
import { View,Text,StyleSheet,Platform } from 'react-native';
import {Icon,Button} from 'native-base';
import {Actions} from 'react-native-router-flux';

import Accordion from 'react-native-collapsible/Accordion';
import GradientButton from './GradientButton';

if(Platform.OS === 'ios'){
    var font = 'OpenSans'
    var font1 = 'OpenSans-Semibold'
  }
  else{
    var font = 'OpenSans-Regular'
    var font1 = 'OpenSans-Semibold'
  }
const SECTIONS = [
    {
      title: 'Discrepancy',
      content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum...',
    },
    {
      title: 'Discrepancy',
      content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum...',
    },
    {
        title: 'Discrepancy',
        content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum..',
    },
    {
        title: 'Discrepancy',
        content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum...',
    },
    {
        title: 'Discrepancy',
        content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum...',
    },
    {
        title: 'Discrepancy',
        content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum...',
    },
    {
        title: 'Discrepancy',
        content: 'Lorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum...',
    }

  ];

class DashboardAccordion extends Component {
    constructor(props){
        super(props);
        this.state={
            expand:true
        };
    }

    _renderHeader(section) {
        return (
          <View style={styles.header}>
            <Text style={styles.headerText}>{section.title}</Text>
            <Text>{this.state.expand && <Icon name="add" style={styles.iconStyle} />}
            </Text>
          </View>
        );
      }

      _renderContent(section) {
        return (
          <View style={styles.content}>
          <View style={{flexDirection:'row',justifyContent:'flex-start',padding:5}}>
            <View style={{flexDirection:'row'}}>
            <Text onPress={Actions.parts} style={[styles.contentHeadingText,{marginLeft:5}]}>WO#:</Text>
            <Text style={styles.contentText}> 714-PM-AC</Text>   
            </View>
            <View style={{flexDirection:'row'}}>
            <Text style={styles.contentHeadingText}>Assign:</Text>
            <Text style={styles.contentText}> Robert len</Text>   
            </View>
            <View style={{flexDirection:'row'}}>
            <Text style={styles.contentHeadingText}>Status:</Text>
            <Text style={styles.contentText}> Active</Text>   
            </View>
          </View>
          <View style={{borderBottomColor: 'rgba(208,208,249,0.2)',borderBottomWidth:1,marginTop:5}} />
          <View style={{flexDirection:'row',justifyContent:'flex-start',padding:5}}>
          <View style={{flexDirection:'row'}}>
            <Text style={[styles.contentHeadingText,{marginLeft:5}]}>Date of Creation:</Text>
            <Text style={styles.contentText}> 10-12-2017</Text>   
            </View>
            <View style={{flexDirection:'row'}}>
            <Text style={styles.contentHeadingText}>Due Date:</Text>
            <Text style={styles.contentText}> 15-12-2017</Text>   
            </View>
          </View>
          <View style={{backgroundColor:'#1e4b6e'}}>
          <View style={{flexDirection:'row',padding:5,marginLeft:15,marginRight:15,marginBottom:5,marginTop:5}}>
            <GradientButton h={25} w={'26%'} name="Complete"/>
            <GradientButton h={25} w={'45%'} name="Quick Complete"/>
            <GradientButton h={25} w={'26%'} name="Edit" action={Actions.addwork}/>   
        </View>
        </View>
          </View>
        );
      }
    render(){
        return(
            <View style={styles.mainContainer}>
                <Accordion
                sections={SECTIONS}
                renderHeader={this._renderHeader.bind(this)}
                renderContent={this._renderContent.bind(this)}
                />
                <View style={{flexDirection:'row',justifyContent:'space-between',marginTop:5}}>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Open Corrective"/>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Open Other"/>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Aging Corrective"/>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Aging All"/>
                </View>
                <View style={{flexDirection:'row',justifyContent:'space-between',marginTop:2}}>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Open PMs"/>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Aging PMs"/>
                    <GradientButton h={35} w={'24.55%'} action={Actions.workOrder} name="Pending Work Orders"/>
                    <GradientButton h={35} w={'24.55%'} name="News"/>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    mainContainer:{
        marginTop:15,
        marginLeft:20,
        marginRight:20
    },
    header: {   
      backgroundColor: '#346792',
      paddingLeft: 10,
      paddingRight:10,
      marginTop:2,
      flexDirection:'row',
      justifyContent:'space-between',
      alignItems:'center',
      height:35
    },
    headerText: {
      fontSize: 12,
    //   fontWeight: '400',
      color:'#fff' ,
      fontFamily:font1
    },
    iconStyle:{
        fontSize: 16,
        color:'#fff'    
    },
    content: {
      backgroundColor: '#254967'
    },
    contentHeadingText:{
        fontSize: 11,
        color:'#4482b5',
        marginLeft:15,
        fontFamily:font1
        // marginTop:5
    },
    contentText:{
        color:'#fff',
        fontSize: 11,
        fontFamily:font
        // marginTop:5
    },
    btnContainer:{
        justifyContent:'center',
          backgroundColor:'#f0f0f0',
          width:'26%',
          height:25
      },
      btn:{
          color:'#000',
          fontWeight:'700',
          fontSize:12
      },
      btnContainer1:{
        justifyContent:'center',
          backgroundColor:'#f0f0f0',
          width:'24.55%',
          height:35,
          borderRadius:0
      },
      btn1:{
          color:'#000',
          fontWeight:'700',
          textAlign:'center',
          fontSize:12

      }
  });

export default DashboardAccordion;
bug

Most helpful comment

This is unrelated to the bug, but a solution to how to change icons based on whether section is collapsed or expanded. It's actually very easy to do with the built in method _renderHeader, just use the isActive variable:

_renderHeader(section, index, isActive) {
  return (
    <View style={styles.header}>
      <Text style={styles.headerText}>{section.title}</Text>
      {!isActive && <Image style={YOUR STYLE} source={YOUR SOURCE "+"} />}
      {isActive && <Image style={YOUR STYLE} source={YOUR SOURCE "-"} />}
    </View>
  );
}

All 6 comments

I also tried to change the icons but I think it will need a quite lot of time as the header layout is already rendered first. You can find the opened header index from onchange() but you have to set the layout inside renderHeader function again & again to show the changed icons. Try out:

https://moduscreate.com/blog/expanding-and-collapsing-elements-using-animations-in-react-native/

where you can add custom icons

I'm experiencing the same issue.
I was thinking about having a touchable component in the renderHeader function, with onPress changing the icon. But if I do that the accordion opening isn't triggering.

@prashantvv
could you perhaps explain with more details how to accomplish this?
It's funny that you suggest this specific link, I was actually using it prior, but you can't accomplish accordion effect with it (opening one category doesn't close the other ones).

Okay I can confirm this behavior, it's definitely a bug

This is unrelated to the bug, but a solution to how to change icons based on whether section is collapsed or expanded. It's actually very easy to do with the built in method _renderHeader, just use the isActive variable:

_renderHeader(section, index, isActive) {
  return (
    <View style={styles.header}>
      <Text style={styles.headerText}>{section.title}</Text>
      {!isActive && <Image style={YOUR STYLE} source={YOUR SOURCE "+"} />}
      {isActive && <Image style={YOUR STYLE} source={YOUR SOURCE "-"} />}
    </View>
  );
}

hey @Dror-Bar you make my day ,,
thank u so much (y)

thank bro. @Dror-Bar

Was this page helpful?
0 / 5 - 0 ratings