tableflip / react-native-select-multiple

☑️ A customiseable FlatList that allows you to select multiple rows
ISC License
191 stars 62 forks source link

version 2.0.0 not rendering list #31

Closed MnaveedS closed 5 years ago

MnaveedS commented 5 years ago

I am using RN version 0.58.5, and recently installed version 2.0.0 of this package, but cannot get the list rendered, I have followed the documentation, the previous version works fine, but the version 2.0.0 doesn't show anything. any suggestion on what i am doing wrong,

          <SelectMultiple
            items={this.state.sample}
            selectedItems={this.state.selectedItems}
            onSelectionsChange={this.onSelectionsChange}
          />

and the dataset is in the label,value type like so,

        sample: [
           { label: "Item 1", value: 1 },
           { label: "Item 2", value: 2 },
         ],
tuantvk commented 5 years ago

same issue I using RN 0.59.0 and recently installed version 2.0.0 of this package. It's not woking

alanshaw commented 5 years ago

Please send a PR to fix

MnaveedS commented 5 years ago

Added a Pull Request With a Fix https://github.com/tableflip/react-native-select-multiple/pull/32

The Problem was that the componentWillRecieveProps() was not executing, adding a componentDidMount() fixed it

ektasahu027 commented 5 years ago

Replace this below code with SelectMultiple.js file

import React, { Component } from "react"; import PropTypes from "prop-types"; import { View, ListView, Text, TouchableWithoutFeedback, Image } from "react-native"; import styles from "./SelectMultiple.styles"; import checkbox from "../images/icon-checkbox.png"; import checkboxChecked from "../images/icon-checkbox-checked.png"; import { mergeStyles } from "./style";

const itemType = PropTypes.oneOfType([ PropTypes.string, PropTypes.shape({ label: PropTypes.any, value: PropTypes.any }) ]);

const styleType = PropTypes.oneOfType([ PropTypes.object, PropTypes.number, PropTypes.array ]);

const sourceType = PropTypes.oneOfType([PropTypes.object, PropTypes.number]);

// A customiseable ListView that allows you to select multiple rows export default class SelectMultiple extends Component { static propTypes = { items: PropTypes.arrayOf(itemType).isRequired, selectedItems: PropTypes.arrayOf(itemType),

onSelectionsChange: PropTypes.func.isRequired,

checkboxSource: sourceType,
selectedCheckboxSource: sourceType,
renderLabel: PropTypes.func,
listViewProps: PropTypes.any,
style: styleType,
rowStyle: styleType,
checkboxStyle: styleType,
labelStyle: styleType,

selectedRowStyle: styleType,
selectedCheckboxStyle: styleType,
selectedLabelStyle: styleType

};

static defaultProps = { selectedItems: [], style: {}, rowStyle: {}, checkboxStyle: {}, checkboxCheckedStyle: {}, labelStyle: {}, checkboxSource: checkbox, selectedCheckboxSource: checkboxChecked, renderLabel: null };

constructor(props) { super(props);

const rows = this.getRowData(props);

const dataSource = new ListView.DataSource({
  rowHasChanged: (r1, r2) =>
    r1.value !== r2.value || r1.selected !== r2.selected
}).cloneWithRows(rows);

this.state = { dataSource };

}

componentWillReceiveProps(nextProps) { const rows = this.getRowData(nextProps); const dataSource = this.state.dataSource.cloneWithRows(rows); this.setState({ dataSource }); }

getRowData({ items, selectedItems }) { items = items.map(this.toLabelValueObject); selectedItems = (selectedItems || []).map(this.toLabelValueObject);

items.forEach(item => {
  item.selected = selectedItems.some(i => i.value === item.value);
});

return items;

}

onRowPress(row) { const { label, value } = row; let { selectedItems } = this.props;

selectedItems = (selectedItems || []).map(this.toLabelValueObject);

const index = selectedItems.findIndex(
  selectedItem => selectedItem.value === value
);

if (index > -1) {
  selectedItems = selectedItems.filter(
    selectedItem => selectedItem.value !== value
  );
} else {
  selectedItems = selectedItems.concat({ label, value });
}

this.props.onSelectionsChange(selectedItems, { label, value });

}

toLabelValueObject(obj) { if (Object.prototype.toString.call(obj) === "[object String]") { return { label: obj, value: obj }; } else { return { label: obj.label, value: obj.value }; } }

render() { const { dataSource } = this.state; const { style, listViewProps } = this.props; const { renderItemRow } = this; return ( <ListView style={style} dataSource={dataSource} renderRow={renderItemRow} {...(listViewProps || {})} /> ); }

renderLabel = (label, style, selected) => { if (this.props.renderLabel) { return this.props.renderLabel(label, style, selected); } return {label}; };

renderItemRow = row => { let { checkboxSource, rowStyle, labelStyle, checkboxStyle } = this.props;

const {
  selectedCheckboxSource,
  selectedRowStyle,
  selectedCheckboxStyle,
  selectedLabelStyle
} = this.props;

if (row.selected) {
  checkboxSource = selectedCheckboxSource;
  rowStyle = mergeStyles(styles.row, rowStyle, selectedRowStyle);
  checkboxStyle = mergeStyles(
    styles.checkbox,
    checkboxStyle,
    selectedCheckboxStyle
  );
  labelStyle = mergeStyles(styles.label, labelStyle, selectedLabelStyle);
} else {
  rowStyle = mergeStyles(styles.row, rowStyle);
  checkboxStyle = mergeStyles(styles.checkbox, checkboxStyle);
  labelStyle = mergeStyles(styles.label, labelStyle);
}

return (
  <TouchableWithoutFeedback onPress={() => this.onRowPress(row)}>
    <View style={rowStyle}>
      <Image style={checkboxStyle} source={checkboxSource} />
      {this.renderLabel(row.label, labelStyle, row.selected)}
    </View>
  </TouchableWithoutFeedback>
);

}; }