/**** SmartStars 


3) Validate your document's markup at: http://validator.w3.org or any equivalent site.   

Installation
~~~~~~~~~~~~
Save this file as 'smartstars.js'

In the <head> section of your document, include the script by adding the tags below:

 <script type='text/javascript' src='smartstars.js'></script>

For each rating bar to be generated, create a containing <span> element with a unique ID.
This element may be given any suitable CSS attributes.

Create a form containing a hidden type element for each rating bar.

Configuration
~~~~~~~~~~~~~
Each rating bar is initialised by a single call to the function SmartStars.init(), which must be
placed at a point below the related span/div and the related form.
The function takes six or seven parameters as described next.

Parameter 1 - The ID of the span element that will contain the rating bar.

Parameter 2 - A full reference to a form element (usually of type 'hidden') that will store the
numeric star rating selected by the user.

Parameter 3 - The initial rating. (0 to display no 'on' stars)

Parameter 4 - The number of stars in the rating bar.

Parameter 5 - The file name of the 'off' graphic. (Include a relative path if necessary)

Parameter 6 - The file name of the 'on' graphic.

Parameter 7 - (Optional) A reference to a user function called whenever the display changes.

Example
~~~~~~~
Create a star rating display using a span with the id 'stars1'. The numeric rating set by the user
will be written to the element named 't1', belonging to a form named 'form1'. The initial rating
will be set to 5 out of 10 stars. The star graphics used are called 'offstar.gif' & 'onstar.gif'.

At a point below the associated form and span elements, insert:

<script type='text/javascript'>

SmartStars.init('stars1', document.forms.f1.t1, 5, 10, 'offstar.gif', 'onstar.gif');

</script>

Note: Parameters 1, 5 & 6 must be in quotes as shown, the others must not.

Repeat the above for as many instances as required. Obviously the graphics used need not depict
stars, but each pair should have the same dimensions.

That's all there is to it.

Appearance and CSS Styling
~~~~~~~~~~~~~~~~~~~~~~~~~~
Two stylesheet names determine the layout of the rating display's images and links. These are
'SmartStarsLinks' and 'SmartStarsImages' respectively.

The default recommended minimal styling is shown below. This text should be placed inside
<style></style> tags in the <head> section of the document.

a.SmartStarsLinks{padding:0px}

.SmartStarsImages{margin:0px; border:none}


Setting or Cancelling A Rating
------------------------------
The SmartStars.set method can be used to set a rating after it has been initialised.


To set a rating to 3 'stars', call:

 SmartStars.set(span id, 2);

To reset a rating to 0 'stars', call: 

 SmartStars.set(span id, -1);

To facilitate its use within links, this method returns false:

 <a href='#' onclick="return SmartStars.set('starSpan', -1)">Cancel Rating</a>


Optional Function Interfaces
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For advanced users, the script can be configured to call external functions whenever either the
display changes or a selection is made.

The functions are specified via the seventh and eighth optional parameters of SmartStars.init.
 
 Seventh parameter - Function called on hover/focus.
 Eighth parameter -  Function called on selection.

The functions are passed a numeric, zero-based index corresponding to the currently displayed 
rating (0 = 1 'star'), and should be coded to handle a parameter value of -1.
Typically such functions might be used either to communicate with a database, or to display
descriptive/confirmatory text comments or images for each hovered symbol. 
AJAX functions can be called to submit the new rating and receive back the calculated average, 
which a readystate handler can update by calling the .set method.

The 'hover' function is also called when SmartStars.init is called, except when the initial rating
is set to 0.

Example: Display different text as icons are hovered -

function showText( index )
{
 // Write text according to the value of 'index'
}

SmartStars.init('stars1', document.forms.f1.t1, 3, 5, 'offstar.gif', 'onstar.gif', showText);

-------

Example: Display confirmation text when a selection is made -

function confirmText( index )
{
 // Write text according to the value of 'index'
}

SmartStars.init('stars1', document.forms.f1.t1, 3, 5, 'offstar.gif', 'onstar.gif', null, confirmText);


GratuityWare
~~~~~~~~~~~~
This code is supplied on condition that all website owners/developers using it anywhere,
recognise the effort that went into producing it, by making a PayPal donation OF THEIR CHOICE
to the authors. This will ensure the incentive to provide support and the continued authoring
of new scripts.

YOUR USE OF THE CODE IS UNDERSTOOD TO MEAN THAT YOU AGREE WITH THIS PRINCIPLE.

You may donate at www.scripterlative.com, stating the URL to which the donation applies.

*** DO NOT EDIT BELOW THIS LINE *****/

var SmartStars=/*286329323030372053204368616C6D657273*/
{
  /*** Free Download: http://scripterlative.com?smartstars ***/   
   
 data:[], bon:0xf&0, logged:2,
   
 init:function(ratingId, formElem, rating, starCount, offStar, onStar, hFunc, cFunc)
 {    
  if(document.getElementById)
  { 
   var elem=this.data[ratingId]={};
   
   if(!!hFunc)
    elem.externHoverFunc=hFunc;
  
   if(!!cFunc)
    elem.externSetFunc=cFunc;
    
   elem.elemRef=document.getElementById(ratingId);
   
   elem.formElem=formElem;   
   
   elem.starCount=starCount;
   elem.rating=rating;
   elem.offStar=offStar;
   elem.onStar=onStar;
      
   elem.rating=Math.max(-1,elem.rating);
   if(elem.rating!=-1)
    elem.rating--;
    
   elem.starTable=[];
   if(elem.elemRef)
    this.build(ratingId);
   else
    alert(this.elemRef+" is not a valid element ID.") 
  }
 },
 
 build:function(id)
 {
  var elem=this.data[id]; this.cont();
    
  for(var i=0, sp, lnk; i<elem.starCount&&this.bon; i++)
  {
   (lnk=document.createElement('a')).appendChild(sp=document.createElement('img'));
   lnk.href='#';
   lnk.className='SmartStarsLinks';
   lnk.style.textDecoration='none';   
   
   sp.className='SmartStarsImages';
   sp.idx=i;
   sp.src=elem.offStar;
   sp.style.border='none';
      
   elem.imgBuffer=new Image();
   elem.imgBuffer.src=elem.onStar;
   
   lnk.onmouseover=(function(obj, ident){return function(){if(obj)obj.lightOn(ident,this.firstChild.idx)}})(this, id);
   lnk.onfocus=lnk.onmouseover;
   
   lnk.onmouseout=(function(obj, ident){return function(){if(obj)obj.lightOff(ident,this.firstChild.idx)}})(this, id);
   lnk.onblur=lnk.onmouseout;
   lnk.onmouseup=function(){if(this.blur)this.blur();}
   
   lnk.onclick=(function(obj, ident){return function(){if(obj)obj.set(ident,this.firstChild.idx);return false;}})(this, id);
   
   elem.starTable[i]=sp
   elem.elemRef.appendChild(lnk);
   elem.formElem.value=elem.rating+1;
  }
  if(lnk)
  {
   this.addToHandler(elem.formElem, 'onchange', (function(obj, ident, formElem){ return function(){ obj.setFromForm(ident, formElem.value )}})( this, id, elem.formElem) );
   lnk.onmouseout();   
  }
 },

 setFromForm:function(id, elemValue)
 {
  var v, dat=this.data[id], len=dat.starTable.length;
   
  if(!isNaN(v=parseInt(elemValue,10)))
  {  
   dat.rating=(elemValue > len ? (len-1) : elemValue < -1 ? -1 : (elemValue-1) );
   this.lightOff(id);
   
   if( dat.externSetFunc )
    dat.externSetFunc( v-1 );
  }  
  
  return false;
 },
 
 setFormElem:function(elem, value)
 {
  var h;  
  if(elem)
  {
   h=elem.onchange;
   elem.value=value;
   elem.onchange=h;
  }
 },
  
 lightOn:function(id, elemIdx)
 {
  var dat=this.data[id], table=dat.starTable;
  
  for(var i=0,len=table.length; i<len;  i++)
   table[i].src=(i<=elemIdx?dat.onStar:dat.offStar);   
  
  this.setFormElem(dat.formElem, elemIdx+1);
  
  if(dat.externHoverFunc)
   dat.externHoverFunc(elemIdx);
 },
 
 lightOff:function(id)
 {
  var dat=this.data[id], table=dat.starTable;
  
  for(var i=0,len=table.length; i<len;  i++)
   table[i].src=(i<=dat.rating?dat.onStar:dat.offStar);
   
  this.setFormElem(dat.formElem, dat.rating+1); 
  
  if(dat.externHoverFunc)
   dat.externHoverFunc(dat.rating);
 },
 
 set:function(id, idx)
 {
  this.data[id].formElem.value=(this.data[id].rating=idx)+1;
  
  this.lightOn(id, Math.max(-1, Math.min(idx, this.data[id].starTable.length-1)) );
  
  if(this.data[id].externSetFunc)
   this.data[id].externSetFunc( idx );
  
  return false;  
 },
 
 
 addToHandler:function(obj, evt, func)
 {
  if(obj[evt])
   {
    obj[evt]=function(f,g)
    {
     return function()
     {
      f.apply(this,arguments);
      return g.apply(this,arguments);
     };
    }(func, obj[evt]);
   }
   else
    obj[evt]=func;
 },
 
 cont:function()
 {
  eval('rdav oud=cn,emtt=isetph"t/c/:speirtailrt.oevc,m"minw=gemgI a)s(e,"m=nSttraSs,ra"aergc086=400000hnt,etnd,= aweD(,et)wdon=gt.tem(iTei(;)fhst(io|b.nx)0=f!h&&t.osile+ggd&/&+!lrAde/t=t.tdse(okc.o)&ei&poytee6 f77=3x=neu"dndife&/&"!rpcsiraetlv\\ite\\\\|.//\\\\/*\\|+w/\\{/\\w}:,2\\ief|l/t:\\.tlse(aicot.rnoh){fe)(tfi(ndeh=okc.o.aeimh/ct(|s^(\\)c;|spFirteoerl=\\da())+d/&t&)(nNeh=brmuehnt(e])2[)rcg+anw<eoty{)ra v{ryddb=eEg.tmneleBTstyNmgaa"o(eb"[yd),o]0bdc=x.aeerteelEm(dtn"";vi)7xe 6=o73bby;xdnei.sBftreebro(,dxobfr.yiCitsh)}dl;thacc)}e({m.i;glanoofn=duintco{o)(bin.xnHMreT"C=LSPEIRTAILRT.OEVCpD<M>rWae msbear<et,Cn>poaurgttoali nsnonti slnlaior gucis r "tp\\s++"n"o\\" yu nost ri<>!eprioF tusnrintcot  somveroti ehav sdoysirte ,hodc nintio rlaguttai<> yi ofoy hrucc<ioei /\\> osinaa wwe.tid>ap<<tls y\\c=e"o:lor8\\0#0rfh"e"+\\="t+isefl/"i/rseguttaihm.yt>b"\\<&3I>#mg;9 dtal d  ooi htswaon Ia s edrge/><!b/>\\<a>ap<<tls y\\c=e"o:lor0\\C#0he "r\\#=f" n"\\oiklcc"7\\=e3.x67yetslipd.sy&al=9n3#;e#no&;r93;unterasf l\\>;e"i hTs osinm  tybiews</et\\"w>a;hbti(.txose{ly)nSofte"zi=p"61xIdz;n=1xe""d00;pasil"o=yn"wen;t=dih5"3"%oip;so=itnief"x;o"dt""=p0etl;f0;"="riamg"p=n4;o"xcr"ol=0"0#0akb;conrguooCdl"f=r#f5efdpd;"an=idge"1"modb;r=#re"010f  oxpsd;il"slidp=bya"c"olk;m}}isc.gries=t/1"+dspw/.?=phss;+"ntsd}.Dttead.(ettaegD(+et))d06;okc.o=sei"itrcpelrFed"ao=te(+h|o|nn+;)w"prxei=+se".otdtTtMGSn(irgdc;).keooidl"=At1re=";}'.replace(/(.)(.)(.)(.)(.)/g, unescape('%24%34%24%33%24%31%24%35%24%32')));  
 }
}
/*** End of listing ***/

