Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>JS Bin</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
  <script src="//cdnjs.cloudflare.com/ajax/libs/mithril/0.1.28/mithril.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/radio/0.2.0/radio.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.8.0/ramda.min.js"></script>
</head>
<body>
  <div class="container">
    <div id="app"></div>
  </div>
</body>
</html>
 
.line {
  text-decoration: line-through;
}
.pointy {
  cursor: pointer;
}
 
var Dialog = {}
Dialog.controller = function() {
  var self = this
  self.noopContentProvider = {
    header: function() {},
    body: function() {},
    footer: function() {}
  }
  self.dialogContentProvider = self.noopContentProvider
  self.visible = m.prop(false)
  self.onclose = function() {
    self.visible(false)
    self.dialogContentProvider.onclose()
    self.dialogContentProvider = self.noopContentProvider
  }
  self.onopen = function(dialogContentProvider) {
    self.dialogContentProvider = dialogContentProvider
    self.visible(true)
  }
  radio('dialog-open').subscribe(self.onopen)
  radio('dialog-close').subscribe(self.onclose)
  self.documentHeight = function() {
    var doc = document.documentElement
    return Math.max(doc.clientHeight, window.innerHeight || 0)
  }
}
Dialog.view = function(ctrl) {
  var smallClose = m('span',
                     {onclick: ctrl.onclose},
                     m.trust('&times;'))
  var header = m('.modal-header', [
    m('button[type=button].close', [smallClose]),
    m('h4.modal-title', ctrl.dialogContentProvider.header())
  ])
  var body = m('.modal-body', [
    m('p', ctrl.dialogContentProvider.body())
  ])
  var footer = m('.modal-footer', [
    m('button[type=button].btn.btn-default',
      {onclick: ctrl.onclose},
      'Cancel'),
    ctrl.dialogContentProvider.footer()
  ])
  var modalClass = ctrl.visible() ? '.show' : ''
  var dialog = m('.modal' + modalClass, [
    m('.modal-dialog', [
      m('.modal-content', [header, body, footer])
    ])
  ])
  var maybeOverlay = ''
  if (ctrl.visible()) {
    maybeOverlay = m('.modal-backdrop.fade.in',
                     {style: 'height:' + ctrl.documentHeight() + 'px'})
  }
  return m('.row', [
    maybeOverlay,
    m('.col-lg-6.col-md-12', [dialog])
  ])
}
// -----------------------------------------------------------------
var TodoEditDialog = function(todo) {
  var self = this
  var todoCopy = {
    name: m.prop(todo.name),
    completed: m.prop(todo.completed)
  }
  
  var onSaveClicked = function() {
    todo.name = todoCopy.name()
    todo.completed = todoCopy.completed()
    radio('dialog-close').broadcast()
  }
  self.header = function() {
    return 'Editing: ' + todoCopy.name()
  }
  self.body = function() {
    return [
      m('input.form-control',
        {onchange: m.withAttr('value', todoCopy.name),
         value: todoCopy.name()}),
      m('.checkbox', [
        m('label', [
          m('input[type=checkbox]',
            {onchange: m.withAttr('checked', todoCopy.completed),
             checked: todoCopy.completed()}),
          'Completed'
        ])
      ])
    ]
  }
  self.footer = function() {
    return m('button[type=button].btn.btn-primary',
             {onclick: onSaveClicked},
             'Save changes')
  }
  self.onclose = function() {
    console.log('TodoEditDialog closed!')
  }
}
// -----------------------------------------------------------------
var Todo = function(name) {
  var self = this
  self.id = 'todo_' + Todo._id++
  self.name = name
  self.completed = false
}
Todo._id = 0
Todo.controller = function() {
  var self = this
  self.todoList = [
    new Todo('laundry'),
    new Todo('fix car'),
    new Todo('take out trash')
  ]
  self.onTodoClicked = function() {
    radio('dialog-open').broadcast(new TodoEditDialog(this))
  }
}
Todo.view = function(ctrl) {
  var mkTodo = function(t) {
    return m('h4.pointy' + (t.completed ? '.line' : ''),
             {key: t.id,
              onclick: ctrl.onTodoClicked.bind(t)},
             t.name)
  }
  return m('.todo-list', R.map(mkTodo, ctrl.todoList))
}
// -----------------------------------------------------------------
App = {}
App.controller = function() {
  var self = this
  self.dialogCtrl = new Dialog.controller()
  self.todoCtrl = new Todo.controller()
}
App.view = function(ctrl) {
  return m('div', [
    Dialog.view(ctrl.dialogCtrl),
    Todo.view(ctrl.todoCtrl)
  ])
}
m.module(document.getElementById('app'), App)
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers