Simple Calculator using Vue and Bootstrap 5

The HTML Markup

Bootstrap 5 provides all the UI styling and responsive behavior. It’s a great fit with Vue now that it’s no longer dependent on jQuery. The Bootstrap grid row & col-* are used to responsively change the calculator width as screen…


This content originally appeared on DEV Community and was authored by Carol Skelly

The HTML Markup

Bootstrap 5 provides all the UI styling and responsive behavior. It's a great fit with Vue now that it's no longer dependent on jQuery. The Bootstrap grid row & col-* are used to responsively change the calculator width as screen size changes.

<div class="row">
        <div class="col-xxl-2 col-lg-3 col-md-4 col-sm-6 mx-auto bg-dark rounded-3 shadow-sm p-3">
            <input class="form-control form-control-lg text-success" v-model="calculator.displayValue" />
            <!-- calculator number pad using grid -->
            <div class="row g-0 text-center mt-2">
                <div class="col-auto text-white">
                    <div class="row g-1 g-lg-1">
                        <div v-for="(key,i) in keypad" :key="i" class="ms-auto col-3 py-2">
                            <button class="btn btn-dark text-warning w-100" @click="processKey(key.value)">{{ key.label }}</button>
                        </div>
                        <div class="col-12 pt-2">
                            <button class="btn btn-dark border-secondary btn-lg text-warning w-100 fw-bold lead" @click="processKey('=')">=</button>
                        </div>
                        <div class="col-12">
                            <div v-if="errValue" class="alert alert-warning p-2 text-truncate small" role="alert">
                              {{ errValue }}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

Bootstrap 5 Vue Calculator

The Vue App Data

Calculator state is kept in it's own data calculator object to track the displayValue, firstOperand and operator. waitingForSecondOperand let's us know when it's ready to perform a calculation.

The keypad array is ordered by how I wanted the keys to render as columns inside the Bootstrap row...

<div v-for="(key,i) in keypad" :key="i" class="ms-auto col-3 py-2">
   <button class="btn btn-dark w-100" @click="processKey(key.value)">{{ key.label }}</button>
</div>
...
  data () {
      return {
        calculator: {
            displayValue: '0',
            firstOperand: null,
            waitingForSecondOperand: false,
            operator: null,
        },
        errValue: null,
        keypad: [
            {label:'7', value: 7},
            {label:'8', value: 8},
            {label:'9', value: 9},
            {label:'x', value: '*'},
            {label:'4', value: 4},
            {label:'5', value: 5},
            {label:'6', value: 6},
            {label:'+', value: '+'},
            {label:'1', value: 1},
            {label:'2', value: 2},
            {label:'3', value: 3},
            {label:'-', value: '-'},
            {label:'AC', value: 'AC'},
            {label:'.', value: '.'},
            {label:'0', value: 0},
            {label:'/', value: '/'},
        ],
  },
...

The Vue App Methods

Of course the calculator actually needs to calculate so I define a series of methods to watch the keystrokes and perform basic math functions. Most of them should be self-explanatory. You will see that errValue is used to store any errors, and resets upon keypress or clear.

When a key is pressed, processKey() is called to determine which key and then call the appropriate function...

  • inputDigit() - when any digit is clicked
  • handleOperator() - when any operator is clicked
  • equalPressed() - when the equal sign is clicked
  • inputDecimal() - to handle the decimal point (.)
  • resetCalculator() - to clear the calculator ('AC')
...
  methods: {
    processKey: function(val) {
        this.errValue = null
        switch (val){
          case "AC": this.resetCalculator()
            break;
          case 0:
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 6:
          case 7:
          case 8:
          case 9: this.inputDigit(val)
          break; 
          case "+": this.handleOperator("+")
            break;
          case "-": this.handleOperator("-")
            break;
          case "/": this.handleOperator("/")
            break;
          case "*": this.handleOperator("*")
            break;
          case "=": this.equalPressed();
            break;
          case ".": this.inputDecimal(".")
              break;
          default:
              this.errValue = 'KEY ERROR: in default'
        }
    },
    equalPressed() {
        const { firstOperand, displayValue, operator } = this.calculator
        try{
            this.calculator.displayValue = this.calculate(firstOperand, displayValue, operator)
        }
        catch (e){
            this.errValue = e
        }
    },
    inputDigit(digit) {
        const { displayValue, waitingForSecondOperand } = this.calculator
        console.log(waitingForSecondOperand)
        if (waitingForSecondOperand === true) {
            this.calculator.displayValue = digit
            this.calculator.waitingForSecondOperand = false
        } else {
            console.log(displayValue)
            this.calculator.displayValue =
                displayValue === '0' ? digit : displayValue + '' + digit
        }
    },
    inputDecimal(dot) {
        const { displayValue, waitingForSecondOperand } = this.calculator
        if (waitingForSecondOperand === true) {
            this.calculator.displayValue = '0.'
            this.calculator.waitingForSecondOperand = false
            return
        }

        // check for existing decimal
        if (displayValue % 1 === 0) {
            this.calculator.displayValue += dot
        }
    },
    handleOperator(nextOperator) {
        const { firstOperand, displayValue, operator, waitingForSecondOperand } = this.calculator
        const inputValue = parseFloat(displayValue)

        if (operator && waitingForSecondOperand) {
            this.calculator.operator = nextOperator
            return
        }

        if (firstOperand == null && !isNaN(inputValue)) {
            this.calculator.firstOperand = inputValue
        } else if (operator) {
            const currentValue = firstOperand || 0
            const result = this.calculate(currentValue, inputValue, operator)
            this.calculator.displayValue = String(result)
            this.calculator.firstOperand = result
        }

        this.calculator.waitingForSecondOperand = true
        this.calculator.operator = nextOperator
    },
    calculate(firstOperand, secondOperand, operator) {
        if (operator === '+') {
            return firstOperand + secondOperand
        } else if (operator === '-') {
            return firstOperand - secondOperand
        } else if (operator === '*') {
            return firstOperand * secondOperand
        } else if (operator === '/') {
            if (secondOperand == 0){
                this.errValue = 'ERROR: Cannot divide by 0'
            }
            else {
                return firstOperand / secondOperand
            }
        }

        return secondOperand
    },
    resetCalculator() {
      this.calculator.displayValue = '0'
      this.calculator.firstOperand = null
      this.calculator.waitingForSecondOperand = false
      this.calculator.operator = null
    },
  },
...

Demo | Source

As always, you can play with the latest Bootstrap 5, and find more handy Vue snippets and examples on Codeply!

Thanks for reading!


This content originally appeared on DEV Community and was authored by Carol Skelly


Print Share Comment Cite Upload Translate Updates
APA

Carol Skelly | Sciencx (2021-06-23T16:51:37+00:00) Simple Calculator using Vue and Bootstrap 5. Retrieved from https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/

MLA
" » Simple Calculator using Vue and Bootstrap 5." Carol Skelly | Sciencx - Wednesday June 23, 2021, https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/
HARVARD
Carol Skelly | Sciencx Wednesday June 23, 2021 » Simple Calculator using Vue and Bootstrap 5., viewed ,<https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/>
VANCOUVER
Carol Skelly | Sciencx - » Simple Calculator using Vue and Bootstrap 5. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/
CHICAGO
" » Simple Calculator using Vue and Bootstrap 5." Carol Skelly | Sciencx - Accessed . https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/
IEEE
" » Simple Calculator using Vue and Bootstrap 5." Carol Skelly | Sciencx [Online]. Available: https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/. [Accessed: ]
rf:citation
» Simple Calculator using Vue and Bootstrap 5 | Carol Skelly | Sciencx | https://www.scien.cx/2021/06/23/simple-calculator-using-vue-and-bootstrap-5/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.