all imlementations using Elm all imlementations of Twoway

a react-elm-components implementation
of the Twoway demo using Elm



port module Phonebooth exposing (main)

import Html exposing (Html, Attribute, div, input, text, button, p)
import Html.App as App
import Html.Attributes exposing (..)
import Html.Events exposing (onInput, onClick)


main =
    App.beginnerProgram { model = model, view = view, update = update }



-- MODEL


type alias Model =
    { name : String
    }


model : Model
model =
    { name = "Steve" }



-- UPDATE


type Msg
    = ChangeName String
    | SuitUp


update : Msg -> Model -> Model
update msg model =
    case msg of
        ChangeName newName ->
            { model | name = newName }

        SuitUp ->
            { name = "Batman" }



-- VIEW


view : Model -> Html Msg
view model =
    div []
        [ div [] [ input [ onInput ChangeName, value model.name ] [] ]
        , p []
            [ text "Your name is "
            , text model.name
            ]
        , button [ onClick SuitUp ] [ text "Put on costume" ]
        ]

The same file in a TypeScript implementation using Angular (2.4.9):

import {Component,ViewChild} from '@angular/core';

@Component({
  selector: '#app',
  template: `
    <input #field [(ngModel)]="name"><br/>
    <p>Your name is {{name}}.</p>
    <button (click)="change()">Put on costume</button>
  `
})
export class Phonebooth {
  @ViewChild('field') input
  name = 'Steve'
  change() {
    this.name = 'Batman'
    this.input.nativeElement.focus()
  }
}

The same file in a component implementation using AngularJS (1.5.8):

import angular from 'angular'

angular.module('phoneboothapp')
  .component('phonebooth', {
    template: `
      <input ng-model="$ctrl.name"><br/>
      <p>Your name is {{$ctrl.name}}.</p>
      <button ng-click="$ctrl.change()">Put on costume</button>
    `,
    controller: class Phonebooth {
      constructor ($element) {
        this.field = $element.find('input')[0]
        this.name = 'Steve'
      }
      change () {
        this.name = 'Batman'
        this.field.focus()
      }
    }
  })

The same file in an xstream implementation using CycleJS (12.2.2):

import xs from 'xstream'
import {div, input, p, button} from '@cycle/dom'

function Phonebooth ({DOM}) {
  const type$ = DOM.select('input')
    .events('input')
    .map(e => e.target.value)
    .startWith('Steve')
  const click$ = DOM.select('button')
    .events('click')
    .mapTo('Batman')
  return {
    DOM: xs.merge(type$, click$).map(name => div([
      input({props: {value: name}}),
      p(['Your name is ' + name + '.']),
      button(['Put on costume'])
    ])),
    focus: click$
  }
}

export default Phonebooth

The same file in an es6 implementation using Cyclow (0.5.0):

import {Block} from 'cyclow'

const Phonebooth = () => Block({
  on: {
    'in.init': () => state => ({name: 'Steve'}),
    'dom.text': text => state => ({name: text}),
    'dom.click': () => ({
      state: () => ({name: 'Batman'}),
      'dom.action': el => el.firstElementChild.focus()
    })
  },
  view: ({name}) => ({
    attrs: {id: 'app'},
    content: [
      {
        tag: 'input',
        attrs: {value: name},
        on: {keyup: (e, next) => next({text: e.target.value})}
      },
      {tag: 'p', content: `Your name is ${name}.`},
      {tag: 'button', content: 'Put on costume', on: {click: 'click'}}
    ]
  })
})

export default Phonebooth

The same file in a createClass implementation using React (15.3.1):

import React from 'react'

let Phonebooth = React.createClass({
  getInitialState: () => ({name: 'Steve'}),
  change () {
    this.setState({name: 'Batman'})
    this.refs.field.focus()
  },
  type (e) {
    this.setState({name: e.target.value})
  },
  render () {
    let name = this.state.name
    return <div>
      <div><input ref='field' onChange={this.type} value={name} /></div>
      <p>Your name is {name}</p>
      <button onClick={this.change}>Put on costume</button>
    </div>
  }
})

export default Phonebooth

The same file in a vanilla implementation using Vue (1.0.26):

import Vue from 'vue'

Vue.component('phonebooth', {
  template: `
    <input v-model="name" v-el:input><br/>
    <p>Your name is {{name}}.</p>
    <button v-on:click="change">Put on costume</button>
  `,
  data: () => ({name: 'Steve'}),
  methods: {
    change () {
      this.name = 'Batman'
      this.$els.input.focus()
    }
  }
})