Browse Source

fixed everything, added carry, calculate result per digit

Bernadette Elena Hammerle 3 years ago
parent
commit
bfb200d1da
2 changed files with 188 additions and 30 deletions
  1. 4 1
      src/App.css
  2. 184 29
      src/App.js

+ 4 - 1
src/App.css

@@ -1,12 +1,15 @@
 #overview{
   font-family: monospace;
   background-color: #ccc;
-  width: 100px;
+  width: 200px;
   text-align: right;
   margin: auto;
   font-size: 2em;
 }
 
+#overview p{
+  margin: 0.2em 1em;
+}
 
 
 .App {

+ 184 - 29
src/App.js

@@ -1,16 +1,62 @@
-import React, { useState } from 'react';
-import './App.css';
+import React, { useState, useEffect, useRef } from "react";
+import "./App.css";
+
+let imdtRes;
+let imdtResIdx;
+let resArr = [];
 
 function App() {
   const [input, setInput] = useState("");
   const [result, setResult] = useState(0);
+  const [carryArr, setCarryArr] = useState([]);
+  const [commaIdx, setCommaIdx] = useState(0);
+  const [numbers, setNumbers] = useState(0);
 
   const handleInput = (e) => {
     setInput(e.target.value);
+    // TODO: reset results, etc.
+  }
+
+  const handleResChange = (e, nosLeft) => {
+    if(typeof e === "string"){
+      imdtRes = e;
+      let carryArrCopy = [...carryArr]
+      carryArrCopy[nosLeft] = carryArrCopy[nosLeft+1]
+      setCarryArr(carryArrCopy)
+    }else{
+      imdtRes = e.target.value;
+    }
+
+    resArr.unshift(imdtRes);
+
+    if(nosLeft === 0){
+      addResultToDiv(resArr)
+      let resCalc = resArr.join("")
+      resCalc = parseFloat(resCalc)
+      console.log(resCalc)
+      console.log(result)
+
+//      if(resCalc === result){
+//        alert("success")
+//        resCalc = 0;
+//      }else{
+//        alert("error")
+//        resCalc = 0;
+//      }
+    }
+  }
+
+  const handleCarryChange = (e, noOfDigits, idx) => {
+    if(typeof carryArr === "undefined"){
+       setCarryArr(Array(noOfDigits).fill("-"));
+    }
+    let carryArrCopy = [...carryArr]
+    carryArrCopy[idx] = e.target.value
+    setCarryArr(carryArrCopy);
   }
 
   const handleSubmit = (e) => {
-    setInput("1,33+22,4450");
+    setInput("1,3+22,450");
     startCalculation();
     e.preventDefault(); // avoid page reload
   }
@@ -23,19 +69,40 @@ function App() {
     return 0
   }
 
-  const addNumbersToDiv = (digits) => {
-    let number = "<p>" + digits.join("") + "</p>"
-    document.getElementById("overview").innerHTML += number;
+  const addNumbersToDiv = (numbers, noOfDigits) => {
+    for (let idx in numbers){
+      let no = numbers[idx].join("")
+      if(idx == numbers.length-1){
+        no = "+ " + no
+      }
+      let pNo = "<p>" + no + "</p>"
+      document.getElementById("overview").innerHTML += pNo;
+    }
+    document.getElementById("overview").innerHTML += "<hr>";
+  }
+
+  const addResultToDiv = (digits) => {
+    let res = "<p>" + digits.join("") + "</p>"
+    document.getElementById("overview").innerHTML += res;
   }
 
-  const numbersToArrOfArr = (numbers) => {
+  function numbersToArrOfArr(numbers) {
     let befComma = Math.max(...numbers).toString().split(".")[0].length;
     let afterComma = Math.max(...numbers.map(x => afterCommaLen(x)));
-    let arrLength = befComma + 1 + afterComma
+    let withComma = Math.max(...numbers.map(x => x.toString().indexOf(".")));
+
+    let arrLength;
+    if(withComma < 0){ // no comma found
+      arrLength = befComma;
+      console.log("no comma", arrLength, withComma)
+    }else{
+      arrLength = befComma + afterComma + 1; // add comma and after comma len
+      console.log("with comma", arrLength)
+    }
 
-    let numbersArr = numbers.map(x => x.toString().split(""))
+    let numbersArr = numbers.map(x => x.toString().split(""));
     for (let numArr of numbersArr){
-      let commaIdx = numArr.indexOf(".")
+      let commaIdx = numArr.indexOf(".");
 
       // without comma, add before
       while(commaIdx===-1 && numArr.length < befComma){
@@ -46,54 +113,142 @@ function App() {
         numArr.push("&nbsp;"); // add " " after comma
       }
       // with comma, add before
-      while (commaIdx>-1 && commaIdx!==befComma){
+      while(commaIdx>-1 && commaIdx!==befComma){
         numArr.unshift("&nbsp;"); // add " " before comma
+        commaIdx = numArr.indexOf(".");
       }
       // with comma, add after
-      while (numArr.length < arrLength){
+      while(numArr.length < arrLength){
         numArr.push("&nbsp;"); // add " " after comma
       }
+      numArr.unshift("&nbsp;"); // for carry
     }
 
     document.getElementById("overview").innerHTML = "";
-    numbersArr.map(digits => addNumbersToDiv(digits));
+    setNumbers(numbersArr);
+    setCommaIdx(befComma+1);
+    addNumbersToDiv(numbersArr, arrLength);
 
     // TODO: assert all have same length and comma at same index?
-    console.log(numbersArr)
-    return numbersArr
+
+    return [numbersArr, befComma]
   }
 
+
+
   const startCalculation = () => {
     if (input.includes("+")){
       let numbers = input.split("+").map(x => parseFloat(x.replace(",",".")));
+      let commaIdx = -1;
       setResult(numbers.reduce((x,y) => x+y, 0));
+      [numbers, commaIdx] = numbersToArrOfArr(numbers);
+    }
+  }
 
-      numbers = numbersToArrOfArr(numbers)
 
-      for (let i=numbers[0].length-1; i>=0; i--){
-        console.log(i, numbers.map(x => x[i]))
+  const ResultCarryForm = ({handleResChange, handleCarryChange}) => {
+    let resInputField = useRef(null);
+    let carryInputField = useRef(null);
+
+    // focus the input field
+    useEffect(()=>{
+      if(resInputField.current && resInputField.current.value === ""){
+        resInputField.current.focus();
       }
-      /*
-      Komma schieben später
-      übertrag und ergebnis input felder
-      nach eingabe automatisch weiter zu nächsten feld
-      wie komma setzen? max zahl von vorher?
-      ergebnis mit state result vergleichen
-      error or success message
-      */
-    }
+    },[])
 
 
+    let labelText = "";
+    let nosLeft = imdtResIdx;
+    let noOfDigits = 0;
+    let carryText = "Übertrag = ";
+
+    if(typeof numbers === "object" && imdtResIdx !== -1){
+      if(typeof imdtResIdx === "undefined"){
+        noOfDigits = Math.min(...numbers.map(n => n.length));
+        imdtResIdx = noOfDigits-1;
+        console.log("--", imdtResIdx, carryArr)
+      }
 
+      if(imdtResIdx === commaIdx){
+        handleResChange(".", nosLeft)
+        imdtResIdx = imdtResIdx - 1;
+      }
+      for (let n in numbers){ // iterate numbers
+        if(nosLeft === 1 && carryArr[1] === "0"){
+          nosLeft = 0;
+          imdtResIdx = -1;
+          handleResChange("&nbsp;", 0)
+          return <></>
+        }
+        let no = numbers[parseInt(n)][imdtResIdx];
+        if(no === "" || no === "&nbsp;"){
+          no = 0;
+        }
+        labelText += no;
+
+        if (parseInt(n) === numbers.length - 1){
+          if(typeof carryArr[imdtResIdx+1] !== "undefind" && carryArr[imdtResIdx+1] > 0){
+            labelText += " + " + carryArr[imdtResIdx+1].toString();
+          }
+          labelText += " = ";
+        }else{
+          labelText += " + "; // TODO: replace with -/* etc.
+        }
+      }
+
+      if(carryArr[imdtResIdx] > -1){
+        imdtRes = -1;
+        imdtResIdx = imdtResIdx - 1;
+        nosLeft = nosLeft - 1;
+      }
+
+      return (
+        <form>
+          <label htmlFor="input_result" id="input_result_label">
+            {labelText}
+          </label>
+          <input
+            onChange={(e) => handleResChange(e, nosLeft)}
+            type="text" id="input_result" size="2" tabIndex={1}
+            aria-labelledby="input_result_label" aria-required="true"
+            ref={resInputField}/>
+          <br/>
+          <label htmlFor="input_carry" id="input_carry_label">
+            {carryText}
+          </label>
+          <input
+            onChange={(e) => handleCarryChange(e, noOfDigits, imdtResIdx)}
+            type="text" id="input_carry" size="2" tabIndex={2}
+            aria-labelledby="input_carry_label" aria-required="true"
+            ref={carryInputField}/>
+        </form>
+      );
+    }else{
+      return (
+        <>
+        </>
+      );
+    }
   }
 
+
   return (
     <div className="App">
       <form onSubmit={(e) => handleSubmit(e)}>
-        <textarea onChange={(e) => handleInput(e)}></textarea>
+        <input
+          type="text"
+          onChange={(e) => handleInput(e)}
+          aria-label="your calculation"
+          aria-required="true"/>
         <input type="submit" value="calculate"/>
-        <div id="overview"></div>
       </form>
+      <div id="overview"></div>
+      <div id="calculation">
+        <ResultCarryForm
+          handleResChange={handleResChange}
+          handleCarryChange={handleCarryChange}/>
+      </div>
     </div>
   );
 }