|
@@ -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(" "); // add " " after comma
|
|
|
}
|
|
|
// with comma, add before
|
|
|
- while (commaIdx>-1 && commaIdx!==befComma){
|
|
|
+ while(commaIdx>-1 && commaIdx!==befComma){
|
|
|
numArr.unshift(" "); // add " " before comma
|
|
|
+ commaIdx = numArr.indexOf(".");
|
|
|
}
|
|
|
// with comma, add after
|
|
|
- while (numArr.length < arrLength){
|
|
|
+ while(numArr.length < arrLength){
|
|
|
numArr.push(" "); // add " " after comma
|
|
|
}
|
|
|
+ numArr.unshift(" "); // 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(" ", 0)
|
|
|
+ return <></>
|
|
|
+ }
|
|
|
+ let no = numbers[parseInt(n)][imdtResIdx];
|
|
|
+ if(no === "" || no === " "){
|
|
|
+ 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>
|
|
|
);
|
|
|
}
|