4

I have some question about sum of number inputs in my 'app'. I don't know how i can get this sum. I have some quantity of number inputs. There may be a different number of them. User must enter some amount of money in each number field. After clicking on button "calculate" the sum of this number inputs should display in p>span. Here the code:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script type="text/babel">
class Sum extends React.Component {
  constructor() {
    super();
    this.state = {
      elements: ["main work", "freelance"],
      value: "",
      numberValue: ""
    };
    this.adder = this.adder.bind(this);
    this.reset = this.reset.bind(this);
    this.handleChange = this.handleChange.bind(this);
    // this.handleChangeNumber = this.handleChangeNumber.bind(this);
  }
  adder() {
    this.state.elements.push(this.state.value);
    this.setState({
      elemements: this.state.elements
    });
  }
  reset() {
    this.setState({
      elements: this.state.elements.slice(1, 1)
    });
  }
  handleChange(e) {
    this.setState({
      value: e.target.value
    });
  }
  // handleChangeNumber(e) {
  //   this.setState({
  //     numberValue: e.target.value
  //   });
  // }
  delCurrent(index) {
    this.state.elements.splice(index, 1);
    this.setState({
      elements: this.state.elements
    });
  }
  render() {
    const list = this.state.elements.map((element, index) => {
      return (
        <li key={index}>
          {element}:{" "}
          <input
            style={{ width: 70, marginBottom: 2 }}
            type="number"
            value={this.state.numberValue}
            // onChange={this.handleChangeNumber}
          />
          <span>USD</span>
          <button
            style={{ cursor: "pointer" }}
            onClick={this.delCurrent.bind(this)}
          >
            &times;
          </button>
        </li>
      );
    });
    return (
      <div>
        <h3>Cash control 'app'</h3>
        <input
          type="text"
          value={this.state.value}
          onChange={this.handleChange}
          placeholder="your income"
        />
        <button style={{ cursor: "pointer" }} onClick={this.adder}>
          add to list
        </button>
        <button style={{ cursor: "pointer" }} onClick={this.reset}>
          reset
        </button>
        <ol>{list}</ol>
        <p>
          Total sum: <span />
        </p>
        <button style={{ cursor: "pointer" }}>calculate</button>
      </div>
    );
  }
}
ReactDOM.render(<Sum />, document.getElementById("root"));
</script>

I hope you guys can help me, ty

2 Answers 2

3

Change your elements to objects, each object with it's own amount.

elements: [
    { title: 'main work', amount: 0 },
    { title: 'freelance', amount: 0 }
  ]

In your adder, don't push items to state, like this.state.elements.push(this.state.value);

adder() {
  this.setState({
    elements: [...this.state.elements, { title: this.state.value, amount: 0 }]
  });
}

To calculate the total, loop through the items and sum their amounts

calculate = () => {
  let totalAmount = 0;
  this.state.elements.forEach(item => {
    totalAmount += item.amount;
  });

  this.setState({
    totalAmount
  })
}

Handle input change

handleChangeNumber(e, index, title) {

  const amount = parseInt(e.target.value, 10);
  const element = { title, amount };

  this.setState({
    elements: [
      ...this.state.elements.slice(0, index),
      Object.assign({}, this.state.elements[index], element),
      ...this.state.elements.slice(index + 1)
    ]
  });
}

Pass the index and title of the element to handle input function in your .map

const list = this.state.elements.map((element, index) => {
  return (
    <li key={index}>
      {element.title}:{" "}
      <input
        style={{ width: 70, marginBottom: 2 }}
        type="number"
        value={this.state.elements[index].amount}
        onChange={(e) => this.handleChangeNumber(e, index, element.title)}
      />
      <span>USD</span>
      <button
        style={{ cursor: "pointer" }}
        onClick={() => this.delCurrent(index)}
      >
        &times;
      </button>
    </li>
  );
});

Calculate and display sum

<p>
  Total sum: <span>{`$ ${this.state.totalAmount}`}</span>
</p>
<button onClick={this.calculate} style={{ cursor: "pointer" }}>calculate</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>

<script type="text/babel">
class Sum extends React.Component {
  constructor() {
    super();
    this.state = {
      elements: [{ title: "main work", amount: 0 }, { title: "freelance", amount: 0 }],
      value: "",
      numberValue: "",
      totalAmount: 0,
    };
    this.adder = this.adder.bind(this);
    this.reset = this.reset.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.handleChangeNumber = this.handleChangeNumber.bind(this);
  }
  adder() {
    this.setState({
      elements: [...this.state.elements, { title: this.state.value, amount: 0 }],
      value: '',
    });
  }
  reset() {
    this.setState({
      elements: this.state.elements.slice(1, 1),
      totalAmount: 0,
      value: '',
    });
  }
  handleChange(e) {
    this.setState({
      value: e.target.value
    });
  }

  calculate = () => {
    let totalAmount = 0;
    this.state.elements.forEach(item => {
      totalAmount += item.amount;
    });

    this.setState({
      totalAmount
    })
  }

  handleChangeNumber(e, index, title) {
    
    const amount = parseInt(e.target.value, 10);
    const element = { title, amount };

    this.setState({
      elements: [
        ...this.state.elements.slice(0, index),
        Object.assign({}, this.state.elements[index], element),
        ...this.state.elements.slice(index + 1)
      ]
    });
  }

  delCurrent(index) {
    this.state.elements.splice(index, 1);
    this.setState({
      elements: this.state.elements
    }, this.calculate);
  }
  render() {
    const list = this.state.elements.map((element, index) => {
      return (
        <li key={index}>
          {element.title}:{" "}
          <input
            style={{ width: 70, marginBottom: 2 }}
            type="number"
            value={this.state.elements[index].amount}
            onChange={(e) => this.handleChangeNumber(e, index, element.title)}
          />
          <span>USD</span>
          <button
            style={{ cursor: "pointer" }}
            onClick={() => this.delCurrent(index)}
          >
            &times;
          </button>
        </li>
      );
    });
    return (
      <div>
        <h3>Cash control 'app'</h3>
        <input
          type="text"
          value={this.state.value}
          onChange={this.handleChange}
          placeholder="your income"
        />
        <button style={{ cursor: "pointer" }} onClick={this.adder}>
          add to list
        </button>
        <button style={{ cursor: "pointer" }} onClick={this.reset}>
          reset
        </button>
        <ol>{list}</ol>
        <p>
          Total sum: <span>{`$ ${this.state.totalAmount}`}</span>
        </p>
        <button onClick={this.calculate} style={{ cursor: "pointer" }}>calculate</button>
      </div>
    );
  }
}
ReactDOM.render(<Sum />, document.getElementById("root"));
</script>

Sign up to request clarification or add additional context in comments.

Comments

0

The better approach to get the sum of your number inputs is to make a small component for your each number inputs and maintain the state inside the number inputs component. Once you click on the calculate button, you can get the state (number values) for each component using state uplifting concept of react and you can calculate the sum.

Hope it answers your question.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.