I wrote a calculator on pure JS using DOM. And the problem I've faced was that if I input an expression using buttons and push "=" button, everything works great. I mean the expression is being replaced by result. But if I paste expression to input using CTRL-V, then nothing happens. Expression remains in input form and is not replaced by result. Even though I can console the result. Here's the code
class Calculator extends HTMLElement {
constructor() {
super()
this.defaultValue = 0
this.root = document.getElementById('root')
this.calcContainer = document.createElement('div')
this.calcContainer.setAttribute('class', 'calculator card border border-dark')
this.root.appendChild(this.calcContainer)
this.addInput()
this.onClickButton = (e, button) => {
e.preventDefault()
const newValue =
this.input.value == this.defaultValue ? button : `${this.input.value}${button}`
this.input.setAttribute('value', newValue)
}
this.addSpecialSymbols()
this.addNumbers()
this.addOperators()
}
addInput() {
let value = this.defaultValue
this.input = document.createElement('input')
this.input.setAttribute('value', value)
this.calcContainer.appendChild(this.input)
}
addSpecialSymbols() {
specialSymbolsArr.map((item) => {
const button = document.createElement('button')
const { className, innerHtml, action } = item
button.setAttribute('class', className)
button.innerHTML = innerHtml
button.addEventListener('click', action.bind(this))
this.calcContainer.appendChild(button)
})
}
addNumbers() {
const numbers = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
numbers.forEach((num) => {
const button = document.createElement('button')
button.innerText = num
button.setAttribute('type', 'button')
button.setAttribute('class', 'btn btn-outline-info')
if (num === 0) {
button.setAttribute('class', 'zero btn btn-outline-secondary')
}
button.addEventListener('click', (e) => {
this.onClickButton(e, num)
})
this.calcContainer.appendChild(button)
})
}
addOperators() {
ids.forEach((id) => {
const button = document.createElement('button')
const { className, innerHtml, operator } = entities[id]
button.innerHTML = innerHtml
button.setAttribute('type', 'button')
button.setAttribute('class', className)
if (operator !== '=') {
button.addEventListener('click', (e) => {
this.onClickButton(e, operator)
})
} else {
button.addEventListener('click', () => {
console.log(this.input.value)
this.input.setAttribute('value', `${getResult(this.input.value)}`)
// this.input.value = getResult(this.input.value)
console.log(this.input.value)
})
}
this.calcContainer.appendChild(button)
})
}
}
In this part of code I logged values of input and it showed expression both times. Even though setAttribute
had to change expression for result.
console.log(this.input.value)
this.input.setAttribute('value', `${getResult(this.input.value)}`)
console.log(this.input.value)
})
If I change initialisation of value manually then it works fine. But afterwards inout becomes 'blocked', buttons doesn't affect input.
button.addEventListener('click', () => {
console.log(this.input.value)
this.input.value = getResult(this.input.value)
console.log(this.input.value)
})
I guess this is conflict of setAttribute
method and initialisation of of input value by browser while pasting something to input. Could somebody help please to solve this problem?