0

I am working on React Table. I am basically a beginner in React. I have a dashboard page where I display a React Table of 8 columns. I have a customize button which will open a popup page, this popup page has 8 check boxes allows me to show/hide those React columns. Initially all the check boxes in this popup page is set to true. When I uncheck a column that particular column get disabled.

There are images in the end to see what I am trying to do.

I will be using this logic for show hide columns (this question was asked by me two days back) - How to show and hide some columns on React Table?

The React Table data is like this

const columns = [
 {
    Header: 'Column 1',
    accessor: 'firstName',
  },
  {
    Header: 'Column 2',
    accessor: 'firstName',
  },
  {
    Header: 'Column 3',
    accessor: 'firstName',
  },
  {
    Header: 'Column 4',
    accessor: 'firstName',
  },
  {
    Header: 'Column 5',
    accessor: 'firstName',
  },
  {
    Header: 'Column 6',
    accessor: 'firstName',
  },
  {
    Header: 'Column 7',
    accessor: 'firstName'
  },
  {
    Header: 'Column 8',
    accessor: 'firstName',
  }
];

The start of the dashboard page

class Dashboard extends Component {
  constructor(props) {
    super(props);
    this.state = {
          filterState: {},
          searchText: '',
          isFilterOpen: false,
          isCustomizedOpen: false,
          isFiltered: false,
          isSearched: false,
          searchedTableData: [],
          filteredTableData: [],
        };
         this.handleCustClickinv = this.handleCustClickinv.bind(this);
    }

This is my code in the render function of my dashboard page for showing the customize button (this is written in parent dashboard page)

{this.state.isCustomizedOpen && <CustomizedView
          filterState={this.state.filterState}
          applyFilter={(values, clear) => { this.applyFilters(values, clear); }}
        />}

This is the code for the customize button (this is written in parent dashboard page)

<div className="custom-div-dashboard" onClick={() => { this.handleCustClickinv(); }}>
            <div className='customize-view-dashboard'>Customized View </div>
          </div>

This is function to handle the click on customize button (this is written in parent dashboard page)

handleFilterClickinv() {
    if(this.state.isCustomizedOpen) {
      this.setState({ isCustomizedOpen: false });
    }
    const currentState = this.state.isFilterOpen;
    this.setState({ isFilterOpen: !currentState });
  }

This is my entire popup page which will have 8 check boxes

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { ActionCreators } from '../../../actions';
import './enqCustomizedView.scss';
import ButtonComponent from '../../shared/button/ButtonComponent';
import { CheckBox } from '../../shared/chkbox/CheckBox';

class CustomizedView extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [
        { id: 1, value: 'Column 1', isChecked: true },
        { id: 2, value: 'Column 2', isChecked: true },
        { id: 3, value: 'Column 3', isChecked: true },
        { id: 4, value: 'Column 4', isChecked: true },
        { id: 5, value: 'Column 5', isChecked: true },
        { id: 6, value: 'Column 6', isChecked: true },
        { id: 7, value: 'Column 7', isChecked: true },
        { id: 8, value: 'Column 8', isChecked: true },
      ]
    };
      this.handleCheckChildElement = this.handleCheckChildElement.bind(this);
  }

  handleClick() {
    this.setState({ isChecked: !this.state.isChecked });
  }

  handleCheckChildElement(event) {
    //let items = this.state.items;
    let { items } = this.state;
    items.forEach(items = () => {
      if(items.value === event.target.value) {
        items.isChecked = event.target.checked;
      }
    });
    this.setState({ items });
    const column1checked = items[0].isChecked;
    console.log('column1checked ' + column1checked);
    const column2checked = items[1].isChecked;
    console.log('column2checked ' + column2checked);
    const column3checked = items[2].isChecked;
    console.log('column3checked ' + column3checked);
    const column4checked = items[3].isChecked;
    console.log('column4checked ' + column4checked);
    const column5checked = items[4].isChecked;
    console.log('column5checked ' + column5checked);
    const column6checked = items[5].isChecked;
    console.log('column6checked ' + column6checked);
    const column7checked = items[6].isChecked;
    console.log('column7checked ' + column7checked);
    const column8checked = items[7].isChecked;
    console.log('column8checked ' + column8checked);
  }

  render() {
    return (
      <div className='popup-page-custom' >
        <div className='bottomBar'>
          <ButtonComponent
            text='Apply'
            className='activeButton filterMargin'
            width='100'
            display='inline-block'
            onClick={() => { this.props.applyFilter(this.state, false); }}
          />
          <ButtonComponent
            text='Clear Filter'
            className='greyedButton clear-filter'
            width='100'
            display='block'
            marginTop='60'
            onClick={() => { this.props.applyFilter(this.state, true); }}
          />
        </div>
        <div>
          <div className='data-points-text'>
            <span> Columns </span>
          </div>
          <div className="App">
            <ul>
              {
                this.state.items.map((item, i) => {
                  return (<div key={i} ><CheckBox handleCheckChildElement={this.handleCheckChildElement} {...item} /></div>);
                })
              }
            </ul>
          </div>
        </div>
      </div>
    );
  }
}

CustomizedView.propTypes = {
  applyFilter: PropTypes.func.isRequired
};

CustomizedView.defaultProps = {
};

function mapStateToProps(state) {
  return {
    auth: state.auth
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(ActionCreators, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(CustomizedView);

And ultimately this is my checkbox page

import React from 'react';
import PropTypes from 'prop-types';

export const CheckBox = (props) => {
  // super(props);
  return (
    <li>
      <input key={props.id} onClick={props.handleCheckChildElement} type="checkbox" checked={props.isChecked} value={props.value} /> {props.value}
    </li>
  );
};

CheckBox.propTypes = {
  id: PropTypes.string,
  handleCheckChildElement: PropTypes.func,
  isChecked: PropTypes.bool,
  value: PropTypes.string,
};

CheckBox.defaultProps = {
  id: '',
  handleCheckChildElement: null,
  isChecked: null,
  value: '',
};

export default CheckBox;

This is a very basic (ugly) style of my dashboard page and popup page

Basic Page demo -dashboard and popup page

This is the error I am getting on Chrome when unchecking the checkboxes

Error in Chrome when unchecking check box

Error in Chrome when unchecking check box - Page source

Edit 1 - As per Alireza Yadegari's suggestion, I made a 1 line change. But I am still getting 2 errors.

After Alireza's suggestion I made a change and got 2 errors on Chrome

After Alireza's suggestion I made a change and got 2 errors on Chrome - Source of error 1

After Alireza's suggestion I made a change and got 2 errors on Chrome - Source of error 2

Edit 2 - As per Alireza Yadegari's suggestion, I applied console.

Applied console as per Alireza

3 Answers3

0

you have to use this piece of code in your constructor

this.handleCheckChildElement = this.handleCheckChildElement.bind(this)
  • I have updated the question - after inserting this line and trying to uncheck the check boxes, I am getting 2 errors, the previous error is not there, there are 2 new errors, see the last 3 screenshots –  Dec 07 '18 at 17:10
  • what is your result when you try to use console.log(items) and console.log(this.state) in your method? – Alireza Yadegari Dec 07 '18 at 17:15
  • My intention is that - there is a react table property called show: true. Default value of all columns is true, but wecan make it false by show: false. I am following this question (instead of making check boxes on the dashboard page , I need to make check boxes on the popup page and I am storing values of every constants in popup page and I need to transfer those constant values to the React Table Page (which is again imported & rendered in the parent dashboard page. You may check this and help me - https://stackoverflow.com/questions/53638095 –  Dec 07 '18 at 17:19
  • @Scooby do you have any porpose to use let { items } = { ...this.state }; instead of let items = this.state.items; – Alireza Yadegari Dec 07 '18 at 17:20
  • it was giving errors - Someone on stack gave me this solution - https://stackoverflow.com/questions/53657372 –  Dec 07 '18 at 17:23
  • Please check the defaultprops and proptypes of the checkbox page. I am concerned whether any type mismatch is happening –  Dec 07 '18 at 17:24
  • I understand what are you trying to do but define of your 'items' is wrong try it like this const { items} = this.state; and let me know if your errors gone – Alireza Yadegari Dec 07 '18 at 17:26
  • Got this error 36:19 error 'items' is constant no-const-assign –  Dec 07 '18 at 17:31
  • I have applied consoles and here is the result, see the last screenshot –  Dec 07 '18 at 17:38
  • replace this piece of code with your code let tempItems = this.state.items ; tempItems.forEach(item => { if (item.value === event.target.value) { item.isChecked = event.target.checked; } this.setState({ items: tempItems }) }); – Alireza Yadegari Dec 07 '18 at 17:43
  • Alireza I will try and say what happened. Alireza if possible can you make a small demo in codesandbox about this type of functionality –  Dec 07 '18 at 17:52
  • got this error - 68:9 error Assignment to property of function parameter 'item' no-param-reassign –  Dec 07 '18 at 18:12
  • try this `let tempItems:any; this.state.items.forEach(item => { let tempItem = item; if (item.value === event.target.value) { tempItem.isChecked = event.target.checked; tempItems.push(tempItem); } }); this.setState({ items: tempItems })` – Alireza Yadegari Dec 07 '18 at 18:36
  • because ,my answer is too long for comment I write it in another answer – Alireza Yadegari Dec 07 '18 at 18:37
0

let { items } = { ...this.state };

this is wrong .... firstly you destructuring array to object then saying give me items prop from given object... of course this is wrong

const { items} = this.state;

takes items prop from the state

and finally.... implement your task with foreach is bad idea...

CheckBox.defaultProps = {
   id: '', 
   handleCheckChildElement: null,
   isChecked: null, value: '', 
};

i don't understand what it does. you know?

  • Got this error 36:19 error 'items' is constant no-const-assign –  Dec 07 '18 at 17:21
  • try with let ` let {items} = this.state` –  Dec 07 '18 at 17:22
  • Please check the defaultprops and proptypes of the checkbox page. I am concerned whether any type mismatch is happening –  Dec 07 '18 at 17:25
  • Getting 2 errors. Error 1 - Uncaught TypeError: Cannot read property 'isChecked' of undefined. Error 2 - Uncaught TypeError: this.state.items.map is not a function. –  Dec 07 '18 at 17:28
  • id: PropTypes.string id is not string it is number replace like this id: PropTypes.number –  Dec 07 '18 at 17:28
  • I changed it to PropTypes.number but still same error –  Dec 07 '18 at 17:36
  • if possible can you make a small demo in codesandbox about this type of functionality –  Dec 08 '18 at 02:27
0

I think your project is a sample and no need for further examples. I just say about your mistakes.

first, when you are using methods it is good to use 'bind(this)' to show react where is the method belongs.

secondly, when you are using state, react just allows you to change it in the constructor and wherever you want to change it you have to use 'setState' method (you can read the reason for this in react documentation).

finally, if you have an array in your state you have to get an array in some temp object change the temp object and then apply changes with 'setState' method. if you have more question please feel free to ask.