Skip to content

Instantly share code, notes, and snippets.

@romeoh
Created August 28, 2012 23:46
Show Gist options
  • Save romeoh/3505409 to your computer and use it in GitHub Desktop.
Save romeoh/3505409 to your computer and use it in GitHub Desktop.
Javascript MVC model
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi"/>
<title></title>
<style type="text/css">
</style>
</head>
<body>
<select id="list" size="10" style="width: 15em"></select><br/>
<button id="plusBtn"> + </button>
<button id="minusBtn"> - </button>
<script type="text/javascript" src="jquery-1.7.2.min.js"></script>
<script type="text/javascript">
/*
* Model
*/
var ListModel = function (items) {
this._items = items;
this._selectedIndex = -1;
this.itemAdded = new Event(this);
this.itemRemoved = new Event(this);
this.selectedIndexChanged = new Event(this);
};
ListModel.prototype = {
getItems : function () {
return [].concat(this._items);
},
addItem : function (item) {
this._items.push(item);
this.itemAdded.notify({item: item});
},
removeItemAt : function (index) {
var item = this._items[index];
this._items.splice(index, 1);
this.itemRemoved.notify({item: item});
if (index == this._selectedIndex)
this.setSelectedIndex(-1);
},
getSelectedIndex : function () {
return this._selectedIndex;
},
setSelectedIndex : function (index) {
var previousIndex = this._selectedIndex;
this._selectedIndex = index;
this.selectedIndexChanged.notify({previous: previousIndex});
}
};
/*
* View
*/
var ListView = function (model, controller, elements) {
this._model = model;
this._controller = controller;
this._elements = elements;
var _this = this;
// attach model listeners
this._model.itemAdded.attach(function () {
_this.rebuildList();
});
this._model.itemRemoved.attach(function () {
_this.rebuildList();
});
// attach listeners to HTML controls
this._elements.list.change(function (e) {
_this._controller.updateSelected(e);
});
};
ListView.prototype = {
show : function () {
this.rebuildList();
var e = this._elements;
var _this = this;
e.addButton.click(function () { _this._controller.addItem() });
e.delButton.click(function () { _this._controller.delItem() });
},
rebuildList : function () {
var list = this._elements.list;
list.html('');
var items = this._model.getItems();
for (var key in items)
list.append($('<option>' + items[key] + '</option>'))
this._model.setSelectedIndex(-1);
}
};
/*
* Controller
*/
var ListController = function (model) {
this._model = model;
};
ListController.prototype = {
addItem : function () {
var item = prompt('Add item:', '');
if (item)
this._model.addItem(item);
},
delItem : function () {
var index = this._model.getSelectedIndex();
if (index != -1)
this._model.removeItemAt(this._model.getSelectedIndex());
},
updateSelected : function (e) {
this._model.setSelectedIndex(e.target.selectedIndex);
}
};
//Event
var Event = function (sender) {
this._sender = sender;
this._listeners = [];
};
Event.prototype = {
attach : function (listener) {
this._listeners.push(listener);
},
notify : function (args) {
for (var i = 0; i < this._listeners.length; i++) {
this._listeners[i](this._sender, args);
}
}
};
var model = new ListModel(['PHP', 'JavaScript', 'asp']);
var view = new ListView(model, new ListController(model),
{
'list' : $('#list'),
'addButton' : $('#plusBtn'),
'delButton' : $('#minusBtn')
}
);
view.show();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment