eltag Calculator

by fthompson

HTML

<!DOCTYPE html>
<html>
    <head>
        <title>eltag.js Calculator Example</title>
        <link href='calculator.css' type='text/css' rel='stylesheet'>
        <script defer src='https://cdn.jsdelivr.net/gh/TSedlar/[email protected]/eltag.min.js'></script>
        <script defer src='calculator.js'></script>
    </head>
    <body>
    </body>
</html>

CSS

#calculator {
    display: grid;
    grid-gap: 0.5rem;
    width: 20rem;
}

#display {
    grid-row: 1;
    grid-column: 1 / 5;
    text-align: right;
}

#number0 {
    grid-row: 6;
    grid-column: 1 / 3;
}

#number1 {
    grid-row: 5;
    grid-column: 1;
}

#number2 {
    grid-row: 5;
    grid-column: 2;
}

#number3 {
    grid-row: 5;
    grid-column: 3;
}

#number4 {
    grid-row: 4;
    grid-column: 1;
}

#number5 {
    grid-row: 4;
    grid-column: 2;
}

#number6 {
    grid-row: 4;
    grid-column: 3;
}

#number7 {
    grid-row: 3;
    grid-column: 1;
}

#number8 {
    grid-row: 3;
    grid-column: 2;
}

#number9 {
    grid-row: 3;
    grid-column: 3;
}

#dot {
    grid-row: 6;
    grid-column: 3;
}

#clear {
    grid-row: 2;
    grid-column: 1 / 3;
}

#backspace {
    grid-row: 2;
    grid-column: 3;
}

#divide {
    grid-row: 2;
    grid-column: 4;
}

#multiply {
    grid-row: 3;
    grid-column: 4;
}

#subtract {
    grid-row: 4;
    grid-column: 4;
}

#add {
    grid-row: 5;
    grid-column: 4;
}

#equals {
    grid-row: 6;
    grid-column: 4;
}

JavaScript

const { renderElement, app, range, each, div, button, span } = ElTag;

const state = {
    display: '0'
};

const actions = {
    addSymbol: symbol => this.setState({ display: this.state.display + symbol }),
    addNumber: number => {
        if (this.state.display === '0') {
            this.setState({ display: number });
        } else {
            actions.addSymbol(number);
        }
    },
    evaluate: () => this.setState({ display: eval(this.state.display) }),
    clearDisplay: () => this.setState({ display: '0' }),
    backspace: () => {
        let length = this.state.display.length;
        if (length > 0) {
            this.setState({ display: this.state.display.substring(0, length - 1)});
        } else {
            actions.clearDisplay();
        }
    }
};

const operators = [
    { symbol: '+', id: 'add' },
    { symbol: '-', id: 'subtract' },
    { symbol: '*', id: 'multiply' },
    { symbol: '/', id: 'divide' },
    { symbol: '.', id: 'dot' }
];

const view = [
    div({ id: 'calculator' }, [
        span({
            id: 'display',
            render: () => this.state.display
        }),
        ...range(0, 10, index => button({
            state: { number: index.toString() },
            id: 'number' + index,
            onclick: () => this.parent.actions.addNumber(this.state.number)
        }, index)),
        ...each(operators, item => button({
            state: { symbol: item.symbol },
            id: item.id,
            onclick: () => this.parent.actions.addSymbol(this.state.symbol)
        }, item.symbol)),
        button({
            id: 'equals',
            onclick: () => this.parent.actions.evaluate()
        }, '='),
        button({
            id: 'backspace',
            onclick: () => this.parent.actions.backspace()
        }, '\u232b'),
        button({
            id: 'clear',
            onclick: () => this.parent.actions.clearDisplay()
        }, 'C'),
    ])
];

const calculator = app({ state: state, actions: actions },...