Example 2 - MVC with JavaScript




Code:

dojo.lang.declare('ListModel', null, {

	initializer : function (items) {
		this._items = items;
		this._selected = -1;
	},

	getItems : function () {
		return [].concat(this._items);
	},

	addItem : function (item) {
		this._items.push(item);
	},

	removeItemAt : function (index) {
		this._items.splice(index, 1);
	},

	removeSelectedItem : function () {
		if (-1 != this._selected) {
			this.removeItemAt(this._selected);
		}
	},

	setSelected : function (index) {
		this._selected = index;
	},

	getSelected : function () {
		return this._selected;
	},

	moveUpSelectedItem : function () {
		if (-1 != this._selected && 0 != this._selected) {
			var item = this._items[this._selected];
			this._items.splice(this._selected, 1);
			this._selected--;
			this._items.splice(this._selected, 0, item);
		}
	},

	moveDownSelectedItem : function () {
		if (-1 != this._selected 
			&& (this._items.length - 1) != this._selected) 
		{
			var item = this._items[this._selected];
			this._items.splice(this._selected, 1);
			this._selected++;
			this._items.splice(this._selected, 0, item);
		}
	}

});

dojo.lang.declare('ListView', null, {

	initializer : function (model, controller, elements) {
		this._model = model;
		this._controller = controller;
		this._elements = elements;
		with (dojo.event) {
			// Connect view to model
			connect(this._model, 'addItem', this, 'rebuildList');
			connect(this._model, 'removeSelectedItem', this, 'rebuildList');
			connect(this._model, 'moveUpSelectedItem', this, 'rebuildList');
			connect(this._model, 'moveDownSelectedItem', this, 'rebuildList');
			// Connect view to controller
			connect(elements.addButton, 'onclick', this._controller, 'addItem');
			connect(elements.delButton, 'onclick', this._controller, 'delItem');
			connect(elements.upButton, 'onclick', this._controller, 'upItem');
			connect(elements.downButton, 'onclick', this._controller, 'downItem');
			connect(elements.list, 'onchange', this._controller, 'updateSelected');
		}
	},

	show : function () {
		this.rebuildList();
	},

	rebuildList : function () {
		var list = this._elements.list;
		while (list.lastChild) {
			list.removeChild(list.lastChild);
		}
		var items = this._model.getItems();
		for (var key in items) {
			list.appendChild(document.createElement('option')
				).appendChild(document.createTextNode(items[key]));
		}
		var selected = this._model.getSelected();
		if (0 > selected || selected > (items.length - 1)) {
			this._controller.clearSelection();
		} else {
			list.selectedIndex = selected;
		}
	}

});

dojo.lang.declare('ListController', null, {

	initializer : function (model) {
		this._model = model;
	},

	addItem : function (e) {
		var item = prompt('Add item:', '');
		if (item) {
			this._model.addItem(item);
		}
		e.preventDefault();
	},

	delItem : function (e) {
		this._model.removeSelectedItem();
		e.preventDefault();
	},

	upItem : function (e) {
		this._model.moveUpSelectedItem();
		e.preventDefault();
	},

	downItem : function (e) {
		this._model.moveDownSelectedItem();
		e.preventDefault();
	},

	updateSelected : function (e) {
		this._model.setSelected(e.target.selectedIndex);
	},

	clearSelection : function () {
		this._model.setSelected(-1);
	}


});

dojo.addOnLoad(function () {
	var model = new ListModel(['PHP', 'JavaScript']);
	var view = new ListView(model, new ListController(model),
		{
			'list' : dojo.byId('list'), 
			'addButton' : dojo.byId('plusBtn'), 
			'delButton' : dojo.byId('minusBtn'),
			'upButton' : dojo.byId('upBtn'),
			'downButton' : dojo.byId('downBtn')
		}
	);
	view.show();
});

Example for the article Model-View-Controller (MVC) with JavaScript.
Tested with Dojo.0.4.3.