/** * @author Ryan Johnson * @copyright 2007 LivePipe LLC * @package Control.Rating * @license MIT * @url http://livepipe.net/projects/control_rating/ * @version 1.0.1 */ if(typeof(Control) == 'undefined') Control = {}; Control.Rating = Class.create(); Object.extend(Control.Rating,{ instances: [], findByElementId: function(id){ return Control.Rating.instances.find(function(instance){ return (instance.container.id && instance.container.id == id); }); } }); Object.extend(Control.Rating.prototype,{ container: false, value: false, options: {}, initialize: function(container,options){ Control.Rating.instances.push(this); this.value = false; this.links = []; this.container = $(container); this.container.update(''); this.options = { min: 1, max: 5, rated: false, input: false, reverse: false, capture: true, multiple: false, classNames: { off: 'rating_off', half: 'rating_half', on: 'rating_on', selected: 'rating_selected' }, updateUrl: false, updateParameterName: 'value', afterChange: Prototype.emptyFunction }; Object.extend(this.options,options || {}); if(this.options.value){ this.value = this.options.value; delete this.options.value; } if(this.options.input){ this.options.input = $(this.options.input); this.options.input.observe('change',function(input){ this.setValueFromInput(input); }.bind(this,this.options.input)); this.setValueFromInput(this.options.input,true); } var range = $R(this.options.min,this.options.max); (this.options.reverse ? $A(range).reverse() : range).each(function(i){ var link = this.buildLink(i); this.container.appendChild(link); this.links.push(link); }.bind(this)); this.setValue(this.value || this.options.min - 1,false,true); }, buildLink: function(rating){ var link = $(document.createElement('a')); link.value = rating; if(this.options.multiple || (!this.options.rated && !this.options.multiple)){ link.href = ''; link.onmouseover = this.mouseOver.bind(this,link); link.onmouseout = this.mouseOut.bind(this,link); link.onclick = this.click.bindAsEventListener(this,link); }else{ link.style.cursor = 'default'; link.observe('click',function(event){ Event.stop(event); return false; }.bindAsEventListener(this)); } link.addClassName(this.options.classNames.off); return link; }, disable: function(){ this.links.each(function(link){ link.onmouseover = Prototype.emptyFunction; link.onmouseout = Prototype.emptyFunction; link.onclick = Prototype.emptyFunction; link.observe('click',function(event){ Event.stop(event); return false; }.bindAsEventListener(this)); link.style.cursor = 'default'; }.bind(this)); }, setValueFromInput: function(input,prevent_callbacks){ this.setValue((input.options ? input.options[input.options.selectedIndex].value : input.value),true,prevent_callbacks); }, setValue: function(value,force_selected,prevent_callbacks){ this.value = value; if(this.options.input){ if(this.options.input.options){ $A(this.options.input.options).each(function(option,i){ if(option.value == this.value){ this.options.input.options.selectedIndex = i; throw $break; } }.bind(this)); }else this.options.input.value = this.value; } this.render(this.value,force_selected); if(!prevent_callbacks){ if(this.options.updateUrl){ var params = {}; params[this.options.updateParameterName] = this.value; new Ajax.Request(this.options.updateUrl,{ parameters: params }); } this.notify('afterChange',this.value); } }, render: function(rating,force_selected){ (this.options.reverse ? this.links.reverse() : this.links).each(function(link,i){ if(link.value <= Math.ceil(rating)){ link.className = this.options.classNames[link.value <= rating ? 'on' : 'half']; if(this.options.rated || force_selected) link.addClassName(this.options.classNames.selected); }else link.className = this.options.classNames.off; }.bind(this)); }, mouseOver: function(link){ this.render(link.value,true); }, mouseOut: function(link){ this.render(this.value); }, click: function(event,link){ this.options.rated = true; this.setValue((link.value ? link.value : link),true); if(!this.options.multiple) this.disable(); if(this.options.capture){ Event.stop(event); return false; } }, notify: function(event_name){ try{ if(this.options[event_name]) return [this.options[event_name].apply(this.options[event_name],$A(arguments).slice(1))]; }catch(e){ if(e != $break) throw e; else return false; } } }); if(typeof(Object.Event) != 'undefined') Object.Event.extend(Control.Rating);