/** * Define the Synapse global. */ if(!window.Synapse) { var Synapse = {}; } if(!Synapse.Forms) { Synapse.Forms = {}; } if(!Synapse.Forms.ADTs) { Synapse.Forms.ADTs = {}; } /** * Define the logging functionality if not defined */ if(!Synapse.log) { Synapse.log = function(val) { if(window.console && console.log) { if(arguments.caller) { console.log('%s - %s', arguments.caller, val); } else { console.log('%s', val); } } } } /** * Define the stars constructor. * * args is an object defining the number of stars as the 'size' property, * the value of the initial vote, as a float, and which star image * to use for the current ranking 'starClick' and which star to use for * the mouseover 'starOver' both of which are integers where 1 is the red * star and n is the nth star. * @param DomNode elem * @param Object args */ Synapse.Forms.ADTs.Stars = function( elem, args ){ //make sure the element is an element if(!elem && !elem.parentNode && !elem.parentNode.replaceChild) { Synapse.log('Failed to make stars on elem'); } //are we having to use ugly for ie6? var isBadIE = (function(){ var rv = -1; // Return value assumes failure. if (navigator.appName == 'Microsoft Internet Explorer') { var ua = navigator.userAgent; var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); if (re.exec(ua) != null) rv = parseFloat( RegExp.$1 ); } else { return false; } return rv < 7; }()); //private vars var privateThis = { 'starWidth' : 16, 'starHeight' : 15, 'source' : ( isBadIE ? '/Synapse/packages/Synapse/Forms/ADTs/stars/stars.gif' : '/Synapse/packages/Synapse/Forms/ADTs/stars/stars.png' ) }; //Keep the scope clean, (function(){ var size, value, starOver, starClick; //figure the size if(args && args.size) { size = args.size; } else { size = parseInt(elem.getAttribute('size')); if(isNaN(size) || size <= 0) { size = 5; } } privateThis.size = size; //figure the value if(args && args.value) { value = args.value; } else { value = parseFloat(elem.getAttribute('value')); if(isNaN(value) || value < 0) { value = 0; } } privateThis.value = value; //figure the mousover star if(args && args.starOver) { starOver = args.starOver; } else { starOver = 2; } privateThis.starOver = starOver; //figure the mouse click star if(args && args.starClick) { starClick = args.starClick; } else { starClick = 7; } privateThis.starClick = starClick; //Determine if we're disabled if(args && args.disabled) { if(args.disabled == true) { disabled = true; } else { disabled = false; } } else { disabled = elem.getAttribute('disabled'); if(disabled && disabled !== false) { disabled = true; } } privateThis.disabled = disabled; }()); //put this in the registry Synapse.Forms.ADTs.Stars.elements[ Synapse.Forms.ADTs.Stars.elements.length ] = this; //Make the div var div = document.createElement('DIV'); (function(){ var atr = elem.getAttribute('style'); if(atr) { div.setAttribute('style', elem.getAttribute('style')); } }()); div.style.width = (privateThis.size*privateThis.starWidth)+'px'; div.style.height = privateThis.starHeight+'px'; div.style.position = 'relative'; div.style.overflow = 'hidden'; elem.parentNode.replaceChild(div, elem); //collect the radio buttons and such var radios = [], stars = []; //Create a mousover handler var overHandler = function(idx) { for(var i = 0; i < privateThis.size; i++) { if(i < idx) { stars[i].style.clip = 'rect('+(privateThis.starHeight*privateThis.starOver)+'px '+privateThis.starWidth+'px '+(privateThis.starHeight*(1+privateThis.starOver))+'px 0px)'; stars[i].style.top = '-'+(privateThis.starHeight*privateThis.starOver)+'px'; stars[i].style.left = (i*privateThis.starWidth)+'px'; } else if(i == idx) { stars[i].style.clip = 'rect('+(privateThis.starHeight*privateThis.starOver)+'px '+(3*privateThis.starWidth)+'px '+(privateThis.starHeight*(1+privateThis.starOver))+'px '+(privateThis.starWidth*2)+'px)'; stars[i].style.top = '-'+(privateThis.starHeight*privateThis.starOver)+'px'; stars[i].style.left = (i*privateThis.starWidth - privateThis.starWidth*2)+'px'; } else { stars[i].style.clip = 'rect(0px '+privateThis.starWidth+'px '+privateThis.starHeight+'px 0px)'; stars[i].style.top = '0px'; stars[i].style.left = (i*privateThis.starWidth)+'px'; } } } //Create a handler to set the value appropriately. var setValue = function(value) { for(var i = 0; i < privateThis.size; i++) { var sdiff = value - i; if(sdiff >= 0.66666) { stars[i].style.backgroundPosition = '0px -'+(privateThis.starHeight*privateThis.starClick)+'px'; } else if(sdiff > 0.33333) { stars[i].style.backgroundPosition = '-'+privateThis.starWidth+'px -'+(privateThis.starHeight*privateThis.starClick)+'px'; } else { stars[i].style.backgroundPosition = '-'+privateThis.starWidth+'px 0px'; } } } //Create an onclick handler var clickHandler = function(idx) { radios[idx].checked = true; for(var i = 0; i < privateThis.size; i++) { if(i <= idx) { stars[i].style.clip = 'rect('+(privateThis.starHeight*privateThis.starClick)+'px '+privateThis.starWidth+'px '+(privateThis.starHeight*(1+privateThis.starClick))+'px 0px)'; stars[i].style.top = '-'+(privateThis.starHeight*privateThis.starClick)+'px'; stars[i].style.left = (i*privateThis.starWidth)+'px'; } else { stars[i].style.clip = 'rect(0px '+(2*privateThis.starWidth)+'px '+privateThis.starHeight+'px '+privateThis.starWidth+'px)'; stars[i].style.top = '0px'; stars[i].style.left = (i*privateThis.starWidth - privateThis.starWidth)+'px'; } } setValue(idx+1); } //Create the images and radio buttons for(var i = 0; i < privateThis.size; i++) { var radio, star; //make the radio button if(privateThis.disabled != true) { radio = document.createElement('INPUT'); radio.setAttribute('name',elem.getAttribute('name')); radio.setAttribute('value',i+1); radio.setAttribute('type','radio'); radio.style.display = 'none'; div.appendChild(radio); radios[radios.length] = radio; } //make the image star = document.createElement('IMG'); star.setAttribute('src',privateThis.source); //star.setAttribute('class','synapse_star'); star.style.position = 'absolute'; star.style.left = (i*privateThis.starWidth)+'px'; //We're starting over a little. star.style.clip = 'rect(0px '+privateThis.starWidth+'px '+privateThis.starHeight+'px 0px)'; star.style.top = '0px'; if(privateThis.disabled != true) { star.style.cursor = 'pointer'; } div.appendChild(star); stars[stars.length] = star; //add backgrounds so that the value is represented star.style.backgroundImage = 'url('+privateThis.source+')'; if(star.style.backgroundRepeat) //For IE6, because Bob can't let go star.style.backgroundRepeat = 'none'; //scope and add handlers if(privateThis.disabled != true) { (function() { var idx = i; star.onmouseover = function(){ overHandler(idx); } star.onmouseout = function(){ overHandler(-1); } star.onclick = function(){ clickHandler(idx); } }()); } } //set the inital value setValue(privateThis.value); } //Stores the stars instances Synapse.Forms.ADTs.Stars.elements = []; Synapse.Forms.ADTs.Stars.onload = function(){ Synapse.log('Starting stars.onload.'); var elems = document.getElementsByTagName('input'); for(var i=elems.length - 1; i >= 0; i--) { if(elems[i].getAttribute('type') == 'stars') { //make the object new Synapse.Forms.ADTs.Stars(elems[i]); } } }