Rating Widget
I read an article comparing React vs Angular. I implemented the MVC design pattern in Javascript for this widget to show that there's lots of frameworks out there.
by Joey Guerra
HTML
Rating is <span id="clickable-rating"></span> <br/>
Clickable Rating <br/>
<div id="fundoo-rating">
<ul class="rating">
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
</ul>
</div>
<br/>
Readonly rating <br/>
<div id="readonly-rating">
<ul class="rating">
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
<li>★</li>
</ul>
</div>
CSS
.rating{
color: #a9a9a9;
margin: 0;
padding: 0;
}
ul.rating {
display: inline-block;
}
.rating li {
list-style-type: none;
display: inline-block;
padding: 1px;
text-align: center;
font-weight: bold;
cursor: pointer;
}
.rating .filled {
color: #21568b;
}
JavaScript
// MVC Code
function Observable(obj){
var observers = {};
this.observe = function(key, observer){
if(observers[key] === undefined) observers[key] = [];
observers[key].push(observer);
};
this.stopObserving = function(observer){
for(key in observers){
var i = 0;
var ubounds = observers[key].length;
for(i; i < ubounds; i++){
if(observers[key][i] === observer){
observers[key].splice(i, 1);
if(observers[key].length === 0) delete observers[key];
break;
}
}
}
};
this.changed = function(key, old, v){
if(observers[key] === undefined) return;
var i = 0;
var ubounds = observers[key].length;
for(i; i<ubounds; i++){
observers[key][i](key, old, v, this);
}
};
this.release = function(){
var key = null;
for(key in observers){
var observer = null;
while(observer = observers[key].pop()){}
}
};
if(obj){
for(var key in obj){
(function(m, key, obj){
Object.defineProperty(m, key, {
get: function(){
return obj[key];
}
, set: function(v){
var old = obj[key];
obj[key] = v;
m.changed('value', old, v, m);
}
, enumerable: true
});
})(this, key, obj);
}
}
return this;
}
function View(container, controller, model){
this.container = container;
this.controller = controller || new Controller(null, model);
this.model = model;
this.release = function(){
if(this.model){
this.model.stopObserving(this);
}
};
this.views = [];
return this;
}
function Controller(delegate, model){
this.model = model;
this.delegate = delegate;
this.view = null;
this.release = function(){
if(this.model){
this.model.stopObserving(this);
}
};
...