Very Basic MVC in JavaScript

It works!

by jshacker

HTML

<div>
Try changing the numbers. Use buttons. OR you know what, enter a number.
</div>

<input type="number" id="number" value="3"> *
<input type="number" id="times" value="3"> = <span id="result"></span>

CSS

#result,
input[type="number"] {
  padding: 4px;
  font-size: 16px;
  background-color: transparent;
  border: none;
  text-align: center;
  display: inline-block;
}

JavaScript

function Event () {
  this.listeners = []
}

Event.prototype = {
  attach: function (listener) {
    this.listeners.push(listener)
  },
  notify: function (args) {
    this.listeners.forEach(function (l) {
      l(args)
    })
  }
}

function Model (numberValue, timesValue) {
  this.numberValue = numberValue
  this.timesValue = timesValue
  this.numberUpdated = new Event()
  this.timesUpdated = new Event()
  var self = this
  this.changeNumber = function (number) {
    self.numberValue = number
    self.numberUpdated.notify()
  }
  this.changeTimes = function (times) {
 		self.timesValue = times
    self.timesUpdated.notify()
  }
  this.getNumber = function () {
  	return self.numberValue
  }
  this.getTimes = function () {
  	return self.timesValue
  }
}

function View (model, elements) {
  this.model = model
  this.elements = elements
  this.numberChanged = new Event()
  this.timesChanged = new Event()
  var self = this  
  this.model.numberUpdated.attach(function () {
    self.recalculate()
  })
  this.model.timesUpdated.attach(function () {
    self.recalculate()
  })
  this.elements.number.addEventListener('input', function() {
    self.numberChanged.notify({value: self.elements.number.value})
  })
  this.elements.times.addEventListener('input', function() {
    self.timesChanged.notify({value: self.elements.times.value})
  })
  this.recalculate = function () {
    self.elements.result.innerHTML = self.model.getNumber() * self.model.getTimes()
  }
  this.show = function () {
  	self.elements.number.value = self.model.getNumber()
    self.elements.times.value = self.model.getTimes()
    self.recalculate()
  }
}

function Controller (model, view) {
  this.model = model
  this.view = view
  var self = this
  this.view.numberChanged.attach(function () {
    self.model.changeNumber(self.view.elements.number.value)
  })
  this.view.timesChanged.attach(function () {
   ...