MVC

Implementation of MVC in JavaScript

by Jeremy Likness

HTML

<div>
  <label for="inputBox">Type Something:</label>
  <input name="inputBox" id="inputBox" />
  <div id="output">
    Output Will Appear Here
  </div>
</div>

JavaScript

(function() {

	"use strict";

  var model, view, controller;

	// this is simply data and behavior. In this 
  // case a single property is tracked with an
  // event fired when it changes 
  function Model() {
    this._listeners = [];
    this._text = "";
  }

  Model.prototype.attach = function(fn) {
    this._listeners.push(fn);
  };

  Object.defineProperty(Model.prototype, "text", {
    configurable: false,
    enumerable: true,
    get: function() {
      return this._text;
    },
    set: function(val) {
      var i;
      this._text = val;
      for (i = 0; i < this._listeners.length; i += 1) {
        this._listeners[i]();
      }
    }
  });

	// the view renders the model to the output div and
  // raises an event when the input field changes
  function View(model, ui) {
    var that = this;
    this._model = model;
    this._model.attach(function() {
      that.modelChanged();
    });
    this._listeners = [];
    this.ui = ui;
    this.ui.input.onkeyup = function() {
      var i;
      for (i = 0; i < that._listeners.length; i += 1) {
        that._listeners[i]();
      }
    };
  };

  View.prototype.attach = function(fn) {
    this._listeners.push(fn);
  };

  View.prototype.modelChanged = function() {
    this.ui.output.innerText = this._model.text;
  };

	// the controller listens for inputs from the
  // view and manages the model
  function Controller(model, view) {
    var that = this;
    this._model = model;
    this._view = view;
    view.attach(function() {
      that._model.text = that._view.ui.input.value;
    });
  }

  model = new Model();
  view = new View(model, {
    input: document.getElementById('inputBox'),
    output: document.getElementById('output')
  });
  controller = new Controller(model, view);
  model.text = "Ready.";
})();