1
goffy
Implement modal calculator
  • 2022/7/11 15:33

  • goffy

  • Just can't stay away

  • Posts: 554

  • Since: 2010/12/27


Hi to all

in my modul wgsimpleacc I had the request to implement a simple calculator (if e.g. someone wants to sum up various small bills).
my goal was to implement a modal version.
I played around a little bit and I found (IMO) a good solution for this feature, which I want to share with you, maybe you can also use it.

first of all I need the modal form:
le="color: #000000"><?php <div class="modal fade" id="calcModal" tabindex="-1" role="dialog" aria-labelledby="calcModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title" id="calcModalLabel"><{$smarty.const._MA_WGSIMPLEACC_CALC}></h4> <button type="button" class="close" data-dismiss="modal" aria-label="<{$smarty.const._CLOSE}>"> <span class="btn btn-danger" aria-hidden="true">&times;</span> </button> </div> <div id="modal-body" class="modal-body"> <div class="calculator"> <input id="calc-screen" type="text" class="calculator-screen" value="" disabled /> <div class="calculator-keys"> <button type="button" class="btn btn-warning operator" value="+">+</button> <button type="button" class="btn btn-warning operator" value="-">-</button> <button type="button" class="btn btn-warning operator" value="*">&times;</button> <button type="button" class="btn btn-warning operator" value="/">&divide;</button> <button type="button" class="btn btn-primary digit" value="7">7</button> <button type="button" class="btn btn-primary digit" value="8">8</button> <button type="button" class="btn btn-primary digit" value="9">9</button> <button type="button" class="btn btn-primary digit" value="4">4</button> <button type="button" class="btn btn-primary digit" value="5">5</button> <button type="button" class="btn btn-primary digit" value="6">6</button> <button type="button" class="btn btn-primary digit" value="1">1</button> <button type="button" class="btn btn-primary digit" value="2">2</button> <button type="button" class="btn btn-primary digit" value="3">3</button> <button type="button" class="btn btn-primary digit" value="0">0</button> <button type="button" class="btn btn-primary decimal" value="."><{$sepComma}></button> <button type="button" class="btn btn-danger all-clear" value="all-clear">AC</button> <button type="button" class="btn btn-warning equal-sign operator" value="=">=</button> </div> </div> </div> <div class="modal-footer"> <button id="btnApplyResult" type="button" class="btn btn-secondary btn-success" data-dismiss="modal"><{$smarty.const._MA_WGSIMPLEACC_CALC_APPLY}></button> </div> </div> </div> </div>


additional to bootstrap I have added some style:
le="color: #000000"><?php .calculator { border: 1px solid #ccc; border-radius: 5px; width: 100%; } .calculator-screen { width: 100%; font-size: 5rem; height: 80px; border: none; background-color: #252525; color: #fff; text-align: right; padding-right: 20px; padding-left: 10px; } button { height: 60px; font-size: 24px !important; } .equal-sign { height: 100%; grid-area: 2 / 4 / 6 / 5; } .equal-sign:hover { background-color: #4e9ed4; } .calculator-keys { display: grid; grid-template-columns: repeat(4, 1fr); grid-gap: 20px; padding: 20px; }


for calculation itself I have implemented following code, which can handle click and keydown events:
le="color: #000000"><?php const calculator = { displayValue: '0', firstOperand: null, waitingForSecondOperand: false, operator: null, }; //Manage Operators const performCalculation = { '+': (firstOperand, secondOperand) => firstOperand + secondOperand, '-': (firstOperand, secondOperand) => firstOperand - secondOperand, '*': (firstOperand, secondOperand) => firstOperand * secondOperand, '/': (firstOperand, secondOperand) => firstOperand / secondOperand, '=': (firstOperand, secondOperand) => secondOperand }; function inputDigit(digit) { const { displayValue, waitingForSecondOperand } = calculator; if (waitingForSecondOperand === true) { calculator.displayValue = digit; calculator.waitingForSecondOperand = false; } else { calculator.displayValue = displayValue === '0' ? digit : displayValue + digit; } console.log(calculator); } function inputDecimal(dot) { // If the `displayValue` does not contain a decimal point if (!calculator.displayValue.includes(dot)) { // Append the decimal point calculator.displayValue += dot; } } function handleOperator(nextOperator) { const { firstOperand, displayValue, operator } = calculator const inputValue = parseFloat(displayValue); if (operator && calculator.waitingForSecondOperand) { calculator.operator = nextOperator; console.log(calculator); return; } if (firstOperand == null) { calculator.firstOperand = inputValue; } else if (operator) { const currentValue = firstOperand || 0; const result = performCalculation[operator](currentValue, inputValue); calculator.displayValue = String(result.toFixed(2)); calculator.firstOperand = result; } calculator.waitingForSecondOperand = true; calculator.operator = nextOperator; console.log(calculator); } function updateDisplay() { const display = document.querySelector('.calculator-screen'); display.value = calculator.displayValue; } function resetCalculator() { calculator.displayValue = '0'; calculator.firstOperand = null; calculator.secondOperand = null; calculator.currentValue = 0; calculator.waitingForSecondOperand = false; } updateDisplay(); //code for button clicks const keys = document.querySelector('.calculator-keys'); keys.addEventListener('click', (event) => { const { target } = event; if (!target.matches('button')) { return; } if (target.classList.contains('operator')) { handleOperator(target.value); updateDisplay(); return; } if (target.classList.contains('decimal')) { inputDecimal(target.value); updateDisplay(); return; } if (target.classList.contains('all-clear')) { resetCalculator(); updateDisplay(); return; } inputDigit(target.value); updateDisplay(); }); //code for keydown events document.getElementById("calcModal").addEventListener('keydown', function(event) { var key = event.key.toString(); if (key == '<{$sepComma}>') { inputDecimal('.'); updateDisplay(); return; } if (key == '+' || key == '-' || key == '/' || key == '*') { handleOperator(event.key); updateDisplay(); return; } if (key == 'Enter') { handleOperator('='); updateDisplay(); return; } if (key == 'Delete') { resetCalculator(); updateDisplay(); return; } if (key == '0' || key == '1' || key == '2' || key == '3' || key == '4' || key == '5' || key == '6' || key == '7' || key == '8' || key == '9') { //alculator.waitingForSecondOperand = false; inputDigit(event.key); updateDisplay(); return; } if (key == '<{$sepThousand}>') { //ignore thousands return; } //alert($key); }, true); //code for applying result to field of calling form $(function () { $("#btnApplyResult").click(function () { const display = document.querySelector('.calculator-screen'); $result = display.value; $result = $result.replace(".", "<{$sepComma}>"); document.getElementById("tra_amount").value = $result; }); });


finally in my form I added a button to call the modal form:
le="color: #000000"><?php $traAmountTray = new XoopsFormElementTray(_MA_WGSIMPLEACC_TRANSACTION_AMOUNT, '&nbsp;'); $traAmountTray->addElement(new XoopsFormText('', 'tra_amount', 20, 150, $traAmount)); $button = new XoopsFormButton('', 'calcAmount', _MA_WGSIMPLEACC_CALCULATOR); $button->setExtra('onclick="$('#calcModal').modal();"'); $traAmountTray->addElement($button); $form->addElement($traAmountTray);



have fun

2
Mamba
Re: Implement modal calculator
  • 2022/7/12 3:46

  • Mamba

  • Moderator

  • Posts: 11521

  • Since: 2004/4/23


Very cool!!!

Thank you for sharing!!!!
Support XOOPS => DONATE
Use 2.5.11 | Docs | Modules | Bugs

3
Cesagonchu
Re: Implement modal calculator

Thanks for sharing

Who's Online

84 user(s) are online (39 user(s) are browsing Support Forums)


Members: 0


Guests: 84


more...

Donat-O-Meter

Stats
Goal: $15.00
Due Date: Jul 31
Gross Amount: $0.00
Net Balance: $0.00
Left to go: $15.00
Make donations with PayPal!

Latest GitHub Commits