Skip to content

adrianmcli/omg-counters

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

80 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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

About

😍 Increment decrement counters using various frontend frameworks.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published