0

I'm new to reactjs. I'm trying to get closer to it by creating a simple page where you can add, modify and delete some entries. My question is now: How can I achieve to delete an entry from a list. I have the following components:

This one is for displaying the list (component CompanyList):

import React, { Component } from 'react';
import Company from './Company';

class CompanyList extends Component {

    constructor(props) {
        super(props);
        this.state = {
            search: '',
            companies: props.companies
        };
    }

    updateSearch(event) {
        this.setState({ search: event.target.value.substr(0,20) })
    }

    addCompany(event) {
        event.preventDefault();
      let nummer = this.refs.nummer.value;
      let bezeichnung = this.refs.bezeichnung.value;
      let id = Math.floor((Math.random()*100) + 1);
      $.ajax({
          type: "POST",
          context:this,
          dataType: "json",
          async: true,
          url: "../data/post/json/companies",
          data: ({ 
              _token : window.Laravel.csrfToken,
              nummer: nummer,
              bezeichnung : bezeichnung,
          }),
          success: function (data) {
            id = data.Nummer;
            this.setState({
              companies: this.state.companies.concat({id, nummer, bezeichnung})
            })
            this.refs.bezeichnung.value = '';
            this.refs.nummer.value = '';
          }
      });
    }

    render() {
      let filteredCompanies = this.state.companies.filter(
        (company) => {
          return company.bezeichnung.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1;
        }
      );
        return (
        <div>
          <div className="row">
            <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">Search</div>
            <div className="col-xs-12 col-sm-12 col-md-9 col-lg-9">
              <div className="form-group">
                <input className="form-control" type="text" value={this.state.search} placeholder="Search" onChange={this.updateSearch.bind(this)} />
              </div>
            </div>
          </div>
          <form onSubmit={this.addCompany.bind(this)}>
            <div className="row">
              <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">Create new entry</div>
              <div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
                <div className="form-group">
                  <input className="form-control" type="number"  ref="nummer" placeholder="New company no." required />
                </div>
              </div>
              <div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
                <div className="form-group">
                  <input className="form-control" type="text" ref="bezeichnung" placeholder="New company name" required />
                </div>
              </div>
              <div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
                <div className="form-group">
                  <button type="submit" className="btn btn-default">Add new company</button>
                </div>
              </div>
            </div>
          </form>
          <div className="row">
            <div className="col-xs-10 col-sm-10 col-md-10 col-lg-10">
              <ul>
              { 
                filteredCompanies.map((company)=> {
                  return (
                    <div>
                      <Company company={company} key={company.id} />
                    </div>
                  );
                })
              }
              </ul>
            </div>
          </div>
        </div>
        );
    }
}

export default CompanyList

As you can see, I have another Company component, where each company is displayed. This is the component Company:

import React, { Component } from 'react';
import CompanyOptions from './CompanyOptions';


class Company extends Component {

    constructor(props) {
        super(props);
        this.state = {
            company: props.company,
            onClick: props.onClick,
            editFieldsCss: "displayNone",
            optionFieldsCss: "modal fade",
            deletionFieldsCss: "displayNone",
            currentCompany: props.company,
        };
    }

    editCompany(event) {
        event.preventDefault();
        let nummer = this.refs.companyNummer.value;
        let bezeichnung = this.refs.companyBezeichnung.value;
        let id = this.state.company.id;
        $.ajax({
            type: "POST",
            context:this,
            dataType: "json",
            async: true,
            url: "../data/post/json/companies/edit",
            data: ({ 
                _token : window.Laravel.csrfToken,
                nummer: nummer,
                bezeichnung : bezeichnung,
            }),
            success: function (data) {
                this.props.company.id = id;
                this.props.company.nummer = nummer;
                this.props.company.bezeichnung = bezeichnung;
                this.toggleEditFields();
                this.toggleOptionFields();
                $('#' + this.props.company.id).modal('hide');
            }
        });
    }

    deleteCompany(event) {
        event.preventDefault();
        let nummer = this.refs.companyNummer.value;
        let bezeichnung = this.refs.companyBezeichnung.value;
        let id = this.state.company.id;
        $.ajax({
            type: "POST",
            context:this,
            dataType: "json",
            async: true,
            url: "../data/post/json/companies/delete",
            data: ({ 
                _token : window.Laravel.csrfToken,
                id : id,
                nummer: nummer,
                bezeichnung : bezeichnung,
            }),
            success: function (data) {
                if(data == true) {
                    this.toggleEditFields();
                    this.toggleOptionFields();
                    $('#' + this.props.company.id).modal('hide');
                    this.setState({company:""});
                }
            }
        });
    }

    toggleEditFields() {
        var css = (this.state.editFieldsCss === "displayNone") ? "displayBlock" : "displayNone";
        this.setState({"editFieldsCss":css});
    }

    toggleDeletionFields() {
        var css = (this.state.deletionFieldsCss === "displayNone") ? "displayBlock" : "displayNone";
        this.setState({"deletionFieldsCss":css});
    }

    toggleOptionFields() {
        /*
        var css = (this.state.optionFieldsCss === "modal fade in displayBlock") ? "modal fade" : "modal fade in displayBlock";
        this.setState({
            "optionFieldsCss":css,
            currentCompany: this.company
        });
        */
        $('#' + this.state.company.id).modal();
    }

    render() {
        return (
            <div>
                <li>
                    <div className="cursorPointer" onClick={this.toggleOptionFields.bind(this)}>
                        {this.props.company.nummer} {this.props.company.bezeichnung} 
                    </div>

                    <div className={this.state.optionFieldsCss} id={this.state.company.id} tabIndex="-1" role="dialog">
                        <div className="modal-dialog" role="document">
                            <div className="modal-content">
                                <div className="modal-header">
                                    <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                                    <h4 className="modal-title">Company entry "{this.props.company.bezeichnung}"</h4>
                                </div>
                                <div className="modal-body">
                                    <div key={this.state.company.id}>
                                        <div>
                                            <form onSubmit={this.editCompany.bind(this)}>
                                                <div className="row">
                                                    <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                                                        <strong>Modify company entry:</strong>
                                                    </div>
                                                </div>
                                                <div className="row">
                                                    <div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
                                                        Company no.
                                                    </div>
                                                    <div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
                                                        <div className="form-group">
                                                            <input className="form-control" type="number" min="1" step="1" ref="companyNummer" placeholder="Company no." defaultValue={this.state.company.nummer} required />
                                                        </div>
                                                    </div>
                                                </div>
                                                <div className="row">
                                                    <div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
                                                        Company name
                                                    </div>
                                                    <div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
                                                        <div className="form-group">
                                                            <input className="form-control" type="text" ref="companyBezeichnung" placeholder="Company name" defaultValue={this.state.company.bezeichnung} required />
                                                        </div>
                                                    </div>
                                                </div>
                                                <div className="row">
                                                    <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                                                        <div className="form-group">
                                                            <button type="submit" className="btn btn-success"><span className="glyphicon glyphicon-edit"></span> Save edits</button>
                                                        </div>
                                                    </div>
                                                </div>
                                            </form>
                                            <form onSubmit={this.deleteCompany.bind(this)}>
                                                <div className="row">
                                                    <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                                                        <div className="form-group">
                                                            <button type="button" onClick={this.toggleDeletionFields.bind(this)} className="btn btn-danger"><span className="glyphicon glyphicon-remove"></span> Delete company entry</button>
                                                        </div>
                                                    </div>
                                                </div>
                                                <div className="row" className={this.state.deletionFieldsCss}>
                                                    <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                                                        Please confirm deletion!
                                                    </div>
                                                    <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12 ">
                                                        <div className="form-group">
                                                            <button type="submit" className="btn btn-default">Yes</button>
                                                            <button type="button" className="btn btn-default marginLeft15px" onClick={this.toggleDeletionFields.bind(this)}>No</button>
                                                        </div>
                                                    </div>
                                                </div>
                                            </form>
                                        </div>
                                    </div>
                                </div>
                                <div className="modal-footer">
                                    <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </li>
            </div>
        );
    }
}

export default Company

How gets the CompanyList now the information, when I delete an item in Company? In Company I cannot access CompanyList, can I?

Liam
  • 27,717
  • 28
  • 128
  • 190
dns_nx
  • 3,651
  • 4
  • 37
  • 66

2 Answers2

1

Of course you can.

For example you can pass a reference to the CompanyList as one of the props in Company component:

<Company parent={this} company={company} key={company.id} />

And then call any methods available in the CompanyList to notify it of changes, upon call CompanyList might update its state and trigger rerender.

Amid
  • 21,508
  • 5
  • 57
  • 54
  • Thanks to your help as well. I had some difficulties to modify the array then, but it is good to know, that a can pass a reference to the objects. – dns_nx Jun 13 '17 at 12:56
1

I wouldn't pass whole parent object to the children because that kind of breaks encapsulation. Instead I would pass it only a function which would get called when item is deleted in the Company. This function would be of CompanyList.

So in CompanyList you would have function, e.g.

onCompanyItemDelete = function(arg){
   ...
}

when rendering companies you would have something like:

<Company onItemDelete={this.onCompanyItemDelete.bind(this)} company={company} key={company.id} />

and in Company you would call function when needed as this.props.onItemDelete.

To know more, you can check some other SO posts about passing function to child components or here.

Matej P.
  • 5,303
  • 1
  • 28
  • 44