jeudi 21 février 2019

ReactJs - checkbox issue on checkall

I got this error in react.js when clicking the check all checkbox and I will deselect the item with "lot_no" and boom, the clicked item gone.

I have 2 states: checked and data where checked contain all item checked by the person, and data is the all items being shown.

I am comparing the checked state to my data, if checked state includes item from data state, the checkbox should be checked otherwise unchecked

Please check my codes and demo as well.

https://stackblitz.com/edit/react-4v7wb6 enter image description here

My example data is this :

const data = [
  {
    document_id: 10095,
    detail_info: []
  },
  {
    document_id: 12221,
    detail_info: []
  },
  {
    document_id: 12226,
    detail_info: [
      {
        id: 738,
        lot_no: "B12345"
      },
      {
        id: 739,
        lot_no: "C12345"
      }
    ]
  },
  {
    document_id: 12229,
    detail_info: [
      {
        id: 740,
        lot_no: "D12345"
      },
      {
        id: 741,
        lot_no: "E12345"
      }
    ]
  }
];
export default data;

Code:

class App extends Component {
  constructor() {
    super();
    this.state = {
      checked:[],
      data: data
    };
  }

  checkBoxClick(item, index, e) {
    let checked = this.state.checked;
    const getIndex = this.state.checked
      .map(e => {
        return e.document_id;
      }).indexOf(item.document_id)

    let index1 = index[0];
    let index2 = index[1];
    if (e.target.checked) {
      if (getIndex === -1) {
        if (index2 === null) {
          checked.push({
            document_id: item.document_id,
            detail_info: []
          });
        } else {
          checked.push({
            document_id: item.document_id,
            detail_info: [item.detail_info[index2]]
          });
        }
        this.setState({ checked: checked });
      } else {
        checked[getIndex].detail_info.push(item.detail_info[index2]);
        this.setState({ checked: checked });
      }
    }

    // uncheck
    else {
      let clickedIndex = checked[getIndex].detail_info.indexOf(
        item.detail_info[index2]
      );

      if (getIndex !== -1) {
        if (index2 === null) {
          checked.splice(getIndex, 1);

        } else {

          // if no more child is checked, remove the parent from checked state
          if (checked[getIndex].detail_info.length===1){
            checked.splice(getIndex, 1);

          } else{

          checked[getIndex].detail_info.splice(clickedIndex, 1);

          }

        }
        this.setState({ checked: checked });

      }

    }
  }
  checkAll(e) {
     let {checked} = this.state
        if (e.target.checked){
            this.state.data.map((item,idx)=>{
                if (item.detail_info.length !==0 ){
                    checked.push({'document_id': item.document_id,
                    'detail_info': item.detail_info
                    })
                } else {
                    checked.push({'document_id': item.document_id,
                    'detail_info': [],
                    })
                }
                this.setState({checked:checked})

            })

        }
        else {
            this.state.data.map((item,idx)=>{
                    this.setState({checked:[]})

            })
        }
  }

  render() {
    return (
      <table>
        <thead>
          <tr>
            <th style=>
              <input type="checkbox" onChange={this.checkAll.bind(this)} /> All
            </th>
            <th>ID. </th>
            <th>Lot No.</th>
          </tr>
        </thead>
        {this.state.data.map((item, idx) => {
          const checkIfExist = obj => obj.document_id === item.document_id;
          let isChecked = this.state.checked.some(checkIfExist);
          return (
            <tbody key={idx}>
              {item.detail_info.length === 0 ? (
                <tr>
                  <td>
                    <input
                    checked={isChecked}
                      type="checkbox"
                      onChange={this.checkBoxClick.bind(this, item, [
                        idx,
                        null
                      ])}
                    />
                  </td>
                  <td>{item.document_id}</td>
                </tr>
              ) : (
                item.detail_info.map((a, b) => {
                  let isCheckedLot = false;
                  this.state.checked.map((c, d) => {
                    if (c.detail_info.length !== 0) {
                      return c.detail_info.map((e, f) => {
                        if (e.id === a.id) {
                          return (isCheckedLot = true);
                        }
                      });
                    }
                  });
                  return (
                    <tr key={b}>
                      <td>
                        <input
                          checked={isCheckedLot}
                          type="checkbox"
                          onChange={this.checkBoxClick.bind(this, item, [
                            idx,
                            b
                          ])}
                        />
                      </td>
                      <td>{item.document_id}</td>
                      <td>{a.lot_no}</td>
                    </tr>
                  );
                })
              )}
            </tbody>
          );
        })}
      </table>
    );
  }
}




Aucun commentaire:

Enregistrer un commentaire