brohymn
brohymn

Reputation: 460

Retrieve row value selected in a Table as an array and send the results to another function on React

How can I console log selected values displayed on a Table component, then store my selection and pass it to a second function?

I have a table showing up data from my API, the table has checkboxes on each one of its rows. I'm using the < Table /> Material UI component for React.

According to documentation the the onRowSelection (similar to onClick) prop should give me an array of the selected rows (only the indices), for example If I select the first row the console will print [0] and if I selected the first and the fifth , the console will print [0,4]

Now, the data that is feeding the table is coming from my state which is data coming from my API pretty much this.state.dataTable = response.data (see code at the end)

so it looks like it's looping thru this.state.dataTable and is not considering the event being fired. what am I doing wrong?

on my function that goes inside onRowSelection I did:

   handleRowSelection (i) {

       for (let x = 0, len = i.length; x < len; x++) {
         i = this.state.dataTable[x];
         console.log(i);
       }
   }

Which I first thought it was giving the right value. when I click the first checkbox (row) it gave the value of the first row element, but when I clicked the 6th checkbox it's giving the value of the second row element, 7th checkbox = third element and so on.

I've also tried this

handleRowSelection (row) {

    const selectedRows = []
    this.state.dataTable.forEach((row, i) => {
    row = row.indexOf(i) > -1

    selectedRows.push(row)
}
    console.log(selectedRows)

Which gives me an interesting value such as: [false, false, false, true, false, false, true]

Needless to say, the true values represent the checkboxes I've selected

CODE (skip til the begining of the Class)

    import ...
    import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, 
    TableRowColumn} from "material-ui/Table";

    const REAL_URL = `//xx.xx.xx.xx/getData/`;

    const markers = [
      {
        key: "Q123456789",
        position: [37.786464, -122.411047],
        children: "My first popup"
      },
      {
        key: "P234567890",
        position: [40.689192, -74.044563],
        children: "My second popup"
      }
    ];


    const MyPopupMarker = ({ children, position, index, handleToggle }) => (
      <Marker onClick={() => handleToggle(index)} position={position}>
        <Popup>
          <span>{children}</span>
        </Popup>
      </Marker>
    );

    const MarkerList = ({ markers, handleToggle }) => {
      const items = markers.map(({ key, ...props }, i) => (
        <MyPopupMarker key={key} {...props} index={i} handleToggle={handleToggle} />
      ));
      return <div>{items}</div>;
    };

      // var holdArray = []

    class Mapper extends Component {
      constructor(props) {
        super(props);

        this.handleToggle = this.handleToggle.bind(this);
        this.handleRowSelection = this.handleRowSelection.bind(this);
        this.handleClose = this.handleClose.bind(this);
        this.handleDeploy = this.handleDeploy.bind(this);

        this.state = {
          lat: 29.761993,
          lng: -95.366302,
          zoom: 4,
          open: false,
          places: [],
          selectedMarker: null,
          selectable: true,
          multiSelectable: true,
          enableSelectAll: true,
          dataTable: [],
          selectedRows: []
        };
      }

      componentDidMount() {
        this.setState({
          places: markers
        });
      }

      handleToggle(index) {
        const self = this;
        const selectedMarker = this.state.places[index];

        this.setState({
          open: !this.state.open,
          selectedMarker: selectedMarker
        });

        const LAST_URL = REAL_URL + this.state.selectedMarker.key;

        axios
          .get(LAST_URL)
          .then(response => {
            self.setState({
              dataTable: response.data
            });

            console.log(response.data);
          })
          .catch(function(error) {
            console.log(error);
          });
      }

      handleRowSelection (i) {

          for (let x = 0, len = i.length; x < len; x++) {
            i = this.state.dataTable[x];
            console.log(i);
          }
      }


      handleDeploy () {

        let resultObject = {
          "devices": this.state.selectedMarker.key,
          // "app": this.handleRowSelection()
        }
        // console.log(resultObject)

      }

  render() {
    const center = [this.state.lat, this.state.lng];
    const selectedMarker = this.state.selectedMarker;

    let availableRows = this.state.dataTable.map((row, k)=>{
      return (
        <TableRow key={k} selected={row.selected}>
          <TableRowColumn>{row}</TableRowColumn>
          <TableRowColumn>Unknown</TableRowColumn>
        </TableRow>
      )
    });


    return (
      <div>
        <Map center={center}
          zoom={this.state.zoom}
          minZoom={3}
          style={styles.map}>

          <TileLayer
            url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
            attribution="&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
          />

          <MarkerList markers={markers} handleToggle={this.handleToggle} />
        </Map>

        <Drawer
          width={500}
          openSecondary={true}
          docked={false}
          open={this.state.open}
          onRequestChange={open => this.setState({ open })}
          containerStyle={styles.whitebox}
        >
          {
            selectedMarker ? (
            <div>
              <Card style={styles.appMedia}>
                <CardTitle
                  titleStyle={styles.drawTitle}
                  subtitleStyle={styles.drawTitle}
                  title={selectedMarker.key}
                  subtitle="Common Field Equipment"
                />
              </Card>

              <Table
                selectable={this.state.selectable}
                multiSelectable={this.state.enableSelectAll}
                onRowSelection={(selectedApps) => this.handleRowSelection(selectedApps, this.props)}
              >

                <TableHeader
                  enableSelectAll={this.state.enableSelectAll}
                  displaySelectAll={false}
                >

                  <TableRow>
                    <TableHeaderColumn>Applications</TableHeaderColumn>
                    <TableHeaderColumn>Status</TableHeaderColumn>
                  </TableRow>

                </TableHeader>


                <TableBody
                  deselectOnClickaway={this.state.clickAway}
                  showRowHover={true}
                >
                  {availableRows}

                </TableBody>

              </Table>

              <RaisedButton
                label="START SELECTED"
                onClick={this.handleDeploy}
                style={styles.buttonStl}
                labelPosition="before"
                backgroundColor="#363636"
                labelStyle={styles.labelStl}
                icon={<BeenHere />}
              />

              <RaisedButton
                label="STOP SELECTED"
                style={styles.buttonStl}
                labelPosition="before"
                backgroundColor="#FF0000"
                labelStyle={styles.labelStl}
                icon={<Cancel />}
              />
            </div>
          ) : null
        }
        </Drawer>
      </div>
    );
  }
}
export default Mapper;

link to component http://www.material-ui.com/#/components/table

Upvotes: 1

Views: 9783

Answers (1)

Rick Jolly
Rick Jolly

Reputation: 3009

In your 2 handleRowSelection examples, you are either redefining a variable or not using the passed in variable. This should work:

handleRowSelection (indexes) {
    const selectedRows = indexes.map(x => this.state.dataTable[x]);
}

Edit: Looks like if all rows are selected, then onRowSelection will return the string "all" so that will need to be handled:

handleRowSelection (indexes) {
    const {dataTable} = this.state;
    const selectedRows = (indexes === 'all')
        ? [...dataTable] // copy of the dataTable
        : indexes.map(x => dataTable[x]);
}  

Edit

Showing the relevant code for checking the checkboxes:

constructor(props) {
    // ...
    this.state = {
        // ...
        dataTable: [],
        selectedIndexes: []
    }
}

handleRowSelection (indexes) {
    this.setState({selectedIndexes: indexes});
}  

render() {
    //...
    let availableRows = this.state.dataTable.map((row, k) => {
      return (
        <TableRow key={k} selected={this.state.selectedIndexes.indexOf(k) !== -1}>
          <TableRowColumn>{row}</TableRowColumn>
          <TableRowColumn>Unknown</TableRowColumn>
        </TableRow>
      )
    });
    //...
}

Upvotes: 1

Related Questions