Awesome Open Source
Awesome Open Source

OMG Counters

↕️️ Increment/decrement counters using various frontend frameworks.

cool badge increment decrement so cool


When a hello world is too simple, but a todo app is too complex.

No counters were harmed in the making of these examples.

Attribution

Table of Contents

Don't see your favorite framework? Make a PR! (see contributing guidelines)

Vanilla JS

<!-- html -->
<h1 class="count"></h1>
<button class="increment" onclick="increment()">Increment</button>
<button class="decrement" onclick="decrement()">Decrement</button>
// javascript
let count = 0
const $count = document.getElementsByClassName('count')[0]
$count.textContent = count
function increment() { $count.textContent = ++count }
function decrement() { $count.textContent = --count }

Live Example on WebpackBin

jQuery

<!-- html -->
<h1 class="count"></h1>
<button class="increment">Increment</button>
<button class="decrement">Decrement</button>
// javascript
let count = 0
$('.count').text(count)
$('.increment').on('click', () => $('.count').text(++count))
$('.decrement').on('click', () => $('.count').text(--count))

Live Example on WebpackBin

RxJS

<!-- html -->
// <h1 id="count"></h1>
// <button id="increment">Increment</button>
// <button id="decrement">Decrement</button>
// javascript
const $factory = id => Rx.Observable.fromEvent(document.getElementById(id), 'click')
const setCount = count => document.getElementById('count').textContent = count

const inc$ = $factory('increment').mapTo(1)
const dec$ = $factory('decrement').mapTo(-1)

Rx.Observable.merge(inc$, dec$)
  .startWith(0)
  .scan((a, b) => a + b)
  .subscribe(setCount)

Live Example on WebpackBin

React

class Counter extends React.Component {
  state = {count: 0}

  increment = e =>
    this.setState({ count: this.state.count + 1 })

  decrement = e =>
    this.setState({ count: this.state.count - 1 })

  render = () =>
    <div>
      <h1>{this.state.count}</h1>
      <button onClick={this.increment}>Increment</button>
      <button onClick={this.decrement}>Decrement</button>
    </div>
}

Live Example on WebpackBin

React + Redux

import { createStore } from 'redux'

const reducer = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT': return state + 1
    case 'DECREMENT': return state - 1
    default: return state
  }
}

const store = createStore(reducer)

var Counter = ({ count, onIncrement, onDecrement }) => (
  <div>
    <h1>{count}</h1>
    <button onClick={onIncrement}>Increment</button>
    <button onClick={onDecrement}>Decrement</button>
  </div>
)

const render = () => {
  ReactDOM.render(
    <Counter
      count={store.getState()}
      onIncrement={()=> store.dispatch({type: 'INCREMENT'})}
      onDecrement={()=> store.dispatch({type: 'DECREMENT'})}
    />,
    document.querySelector('body')
  )
}

store.subscribe(render)
render()

Live Example on WebpackBin

AngularJS

const CounterComponent = {
  template: `
   <div>
     <h1>{{ $ctrl.counter }}</h1>
     <button ng-click="$ctrl.increaseCounter()">Increment</button>
     <button ng-click="$ctrl.decreaseCounter()">Decrement</button>
   </div>
  `,
  controller: class CounterController {
    constructor() {
      this.counter = 0
    }

    increaseCounter() {
      this.counter++
    }

    decreaseCounter() {
      this.counter--
    }
  }
}

export default CounterComponent

Live Example on WebpackBin

Angular 2+

import { Component } from '@angular/core'

@Component({
 selector: 'counter',
 template : `
   <div>
     <h1>{{counter}}</h1>
     <button (click)="onIncrement()">Increment</button>
     <button (click)="onDecrement()">Decrement</button>
   </div>
 `
})
export class CounterComponent {
 counter: number = 0

 onIncrement() {
   this.counter++
 }

 onDecrement() {
   this.counter--
 }
}

Live Example on WebpackBin

Hyperapp

app({
  model: 0,
  update: {
    add: model => model + 1,
    sub: model => model - 1
  },
  view: (model, actions) =>
    <div>
      <h1>{model}</h1>
      <button onclick={actions.add}>Increment</button>
      <button onclick={actions.sub}>Decrement</button>
    </div>
})

Live Example on WebpackBin

Vue.js

<!-- html -->
<div id="app">
  <h1>{{ count }}</h1>
  <button v-on:click="increment">Increment</button>
  <button v-on:click="decrement">Decrement</button>
</div>
// javascript
new Vue({
  el: '#app',
  data: { count: 0 },
  methods: {
    increment: function() { this.count++ },
    decrement: function() { this.count-- }
  }
})

Live Example on WebpackBin

Elm

import Html exposing (beginnerProgram, div, h1, button, text)
import Html.Events exposing (onClick)


main =
  beginnerProgram { model = 0, view = view, update = update }


view model =
  div []
    [ h1 [] [ text (toString model) ]
    , button [ onClick Increment ] [ text "increment" ]
    , button [ onClick Decrement ] [ text "decrement" ]
    ]


type Msg = Increment | Decrement


update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1

Live Example

Cycle.js

const xs = xstream.default
const {div, button, h1, makeDOMDriver} = CycleDOM

function main(sources) {
  const action$ = xs.merge(
    sources.DOM.select('.dec').events('click').mapTo(-1),
    sources.DOM.select('.inc').events('click').mapTo(+1)
  )
  const count$ = action$.fold((x, y) => x + y, 0)
  const vdom$ = count$.map(count =>
    div([
      h1(count.toString()),
      button('.dec', 'Decrement'),
      button('.inc', 'Increment')
    ])
  )
  return { DOM: vdom$ }
}

Live Example on JSBin

Jumpsuit

const CounterState = State({
  initial: { count: 0 },
  increment: ({ count }) => ({ count: count + 1 }),
  decrement: ({ count }) => ({ count: count - 1 })
})

const Counter = Component({
  render() {
    return (
      <div>
        <h1>{ this.props.count }</h1>
        <button onClick={ Actions.increment }>Increment</button>
        <button onClick={ Actions.decrement }>Decrement</button>
      </div>
    )
  }
}, (state) => ({ count: state.counter.count }))

const globalState = { counter: CounterState }
Render(globalState, <Counter/>)

Live Example on WebpackBin

Mobx

const store = new class CounterStore {
  @observable count = 0
  @action increment = () => this.count++
  @action decrement = () => this.count--
}

const Counter = observer(() => {
  return (
    <div>
      <h1>{store.count}</h1>
      <button onClick={store.increment}>Increment</button>
      <button onClick={store.decrement}>Decrement</button>
    </div>
  )
})

Live Example on JSBin

Choo

app.model({
    state: { count: 0 },
    reducers: {
      increment: (state) => ({ count: state.count + 1 }),
      decrement: (state) => ({ count: state.count - 1 })
    }
})

const view = (state, previousState, send) => {
  return html`<div>
         <h1>${state.count}</h1>
         <button onclick=${increment}>Increment</button>
         <button onclick=${decrement}>Decrement</button></div>`

  function increment() { send('increment') }
  function decrement() { send('decrement') }
}

app.router([['/', view]])
document.body.appendChild(app.start())

View on WebpackBin

Marko

class {
  onCreate() {
    this.state = {count: 0};
  }

  increment(delta) {
    this.state.count += delta;
  }
}

<div>
  <h1>${state.count}</h1>
  <button on-click('increment', 1)>Increment</button>
  <button on-click('increment', -1)>Decrement</button>
</div>

Try Online at markojs.com


Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
javascript (68,103
frontend (488
examples (193
reference (74
counter (31
frameworks (19

Find Open Source By Browsing 7,000 Topics Across 59 Categories