147 lines
5.8 KiB
JavaScript
147 lines
5.8 KiB
JavaScript
|
|
class SimpleCalculator {
|
|||
|
|
constructor(containerId) {
|
|||
|
|
this.container = document.getElementById(containerId);
|
|||
|
|
if (!this.container) return;
|
|||
|
|
this.currentInput = "0";
|
|||
|
|
this.previousInput = "";
|
|||
|
|
this.operation = null;
|
|||
|
|
this.init();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
init() {
|
|||
|
|
this.container.innerHTML = `
|
|||
|
|
<div class="w-72 bg-slate-800 p-4 rounded-2xl shadow-xl select-none text-slate-100">
|
|||
|
|
<!-- Écran avec une hauteur fixe (min-h) pour éviter qu'il ne rétrécisse -->
|
|||
|
|
<div id="calc-screen" class="bg-slate-900 text-right p-4 rounded-xl mb-4 text-2xl font-mono tracking-wider overflow-hidden min-h-[4rem] flex flex-col justify-center">
|
|||
|
|
<div id="calc-prev" class="text-xs text-slate-400 h-4"></div>
|
|||
|
|
<div id="calc-current">0</div>
|
|||
|
|
</div>
|
|||
|
|
<!-- Clavier -->
|
|||
|
|
<div class="grid grid-cols-4 gap-2">
|
|||
|
|
<button data-action="clear" class="col-span-2 bg-red-600 hover:bg-red-500 p-3 rounded-xl font-bold transition">AC</button>
|
|||
|
|
<button data-action="delete" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">⌫</button>
|
|||
|
|
<button data-action="operator" data-value="/" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">÷</button>
|
|||
|
|
|
|||
|
|
<button data-action="number" data-value="7" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">7</button>
|
|||
|
|
<button data-action="number" data-value="8" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">8</button>
|
|||
|
|
<button data-action="number" data-value="9" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">9</button>
|
|||
|
|
<button data-action="operator" data-value="*" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">×</button>
|
|||
|
|
|
|||
|
|
<button data-action="number" data-value="4" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">4</button>
|
|||
|
|
<button data-action="number" data-value="5" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">5</button>
|
|||
|
|
<button data-action="number" data-value="6" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">6</button>
|
|||
|
|
<button data-action="operator" data-value="-" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">-</button>
|
|||
|
|
|
|||
|
|
<button data-action="number" data-value="1" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">1</button>
|
|||
|
|
<button data-action="number" data-value="2" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">2</button>
|
|||
|
|
<button data-action="number" data-value="3" class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">3</button>
|
|||
|
|
<button data-action="operator" data-value="+" class="bg-amber-600 hover:bg-amber-500 p-3 rounded-xl font-bold transition">+</button>
|
|||
|
|
|
|||
|
|
<button data-action="number" data-value="0" class="col-span-2 bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">0</button>
|
|||
|
|
<button data-action="number" data-value="." class="bg-slate-700 hover:bg-slate-600 p-3 rounded-xl font-bold transition">.</button>
|
|||
|
|
<button data-action="calculate" class="bg-emerald-600 hover:bg-emerald-500 p-3 rounded-xl font-bold transition">=</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
this.prevScreen = this.container.querySelector("#calc-prev");
|
|||
|
|
this.currentScreen = this.container.querySelector("#calc-current");
|
|||
|
|
this.addListeners();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
addListeners() {
|
|||
|
|
this.container.addEventListener("click", (e) => {
|
|||
|
|
const button = e.target.closest("button");
|
|||
|
|
if (!button) return;
|
|||
|
|
|
|||
|
|
const action = button.getAttribute("data-action");
|
|||
|
|
const value = button.getAttribute("data-value");
|
|||
|
|
|
|||
|
|
if (action === "number") {
|
|||
|
|
this.appendNumber(value);
|
|||
|
|
} else if (action === "operator") {
|
|||
|
|
this.chooseOperation(value);
|
|||
|
|
} else if (action === "calculate") {
|
|||
|
|
this.compute();
|
|||
|
|
} else if (action === "clear") {
|
|||
|
|
this.clear();
|
|||
|
|
} else if (action === "delete") {
|
|||
|
|
this.deleteDigit();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.updateScreen();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
appendNumber(number) {
|
|||
|
|
if (number === "." && this.currentInput.includes(".")) return;
|
|||
|
|
if (this.currentInput === "0" && number !== ".") {
|
|||
|
|
this.currentInput = number;
|
|||
|
|
} else {
|
|||
|
|
this.currentInput += number;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
chooseOperation(op) {
|
|||
|
|
if (this.currentInput === "") return;
|
|||
|
|
if (this.previousInput !== "") {
|
|||
|
|
this.compute();
|
|||
|
|
}
|
|||
|
|
this.operation = op;
|
|||
|
|
this.previousInput = this.currentInput;
|
|||
|
|
this.currentInput = "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
compute() {
|
|||
|
|
let computation;
|
|||
|
|
const prev = parseFloat(this.previousInput);
|
|||
|
|
const current = parseFloat(this.currentInput);
|
|||
|
|
if (isNaN(prev) || isNaN(current)) return;
|
|||
|
|
|
|||
|
|
switch (this.operation) {
|
|||
|
|
case "+":
|
|||
|
|
computation = prev + current;
|
|||
|
|
break;
|
|||
|
|
case "-":
|
|||
|
|
computation = prev - current;
|
|||
|
|
break;
|
|||
|
|
case "*":
|
|||
|
|
computation = prev * current;
|
|||
|
|
break;
|
|||
|
|
case "/":
|
|||
|
|
computation = current === 0 ? "Erreur" : prev / current;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.currentInput = computation.toString();
|
|||
|
|
this.operation = null;
|
|||
|
|
this.previousInput = "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
clear() {
|
|||
|
|
this.currentInput = "0";
|
|||
|
|
this.previousInput = "";
|
|||
|
|
this.operation = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
deleteDigit() {
|
|||
|
|
if (this.currentInput.length === 1) {
|
|||
|
|
this.currentInput = "0";
|
|||
|
|
} else {
|
|||
|
|
this.currentInput = this.currentInput.slice(0, -1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
updateScreen() {
|
|||
|
|
this.currentScreen.innerText =
|
|||
|
|
this.currentInput === "" ? "0" : this.currentInput;
|
|||
|
|
if (this.operation != null) {
|
|||
|
|
this.prevScreen.innerText = `${this.previousInput} ${this.operation}`;
|
|||
|
|
} else {
|
|||
|
|
this.prevScreen.innerText = "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|