inputEx-library

inputex-radio  3.0.0a

inputEx-library > inputex-radio > inputex-ratingstars.js (source view)
Search:
 
Filters
/**
 * @module inputex-ratingstars
 */
YUI.add("inputex-ratingstars",function(Y){

   var lang = Y.Lang,
       inputEx = Y.inputEx;

/**
 * Create a star rating Field
 * This field has been made by integrating script from http://www.unessa.net/en/hoyci/projects/yui-star-rating/
 * To use it with auto data sending, use RatingStars
 * @class inputEx.RatingStars
 * @extends inputEx.Field
 * @constructor
 * @param {Object} options The following options are added for RatingStars :
 * <ul>
 *  <li><b>averageValue</b>: average value before clicking, must be a float number</li>
 *  <li><b>nRates</b>: numbers of vote</li>
 *  <li><b>disableRate</b>: Disable the rate but show stars</li>
 *  <li><b>nStars</b>: <i>integer</i> number of stars (default : 5) </li>
 *  <li><b>disabled</b>: disable voting  </li>
 *  <li><b>message</b>: <i>string</i> C-like with % convention string for display Message (default 'Rating: % (% votes cast)') </li>
 *  *  <li><b>disableMessage</b>: <i>string</i> String to show when mouse pass hover the stars and stars are disabled</li>
 * </ul>
 */
inputEx.RatingStars = function(options) {
   inputEx.RatingStars.superclass.constructor.call(this,options);
   this.resetStars();
};

Y.extend(inputEx.RatingStars, inputEx.Field,{
  setOptions: function(options){
    inputEx.RatingStars.superclass.setOptions.call(this,options);
    
    // Added options
    if(lang.isArray(options.nStars) && options.nStars[0] && lang.isString(options.nStars[0])){
      this.options.nStars = options.nStars.length;
      this.options.starsMessages = options.nStars;
    } else {
      this.options.nStars = options.nStars || 5;
    }
    this.options.averageValue = lang.isNumber(options.averageValue) ? Math.round((options.averageValue)*10)/10 : null;
    this.options.disableRate = options.disableRate || false;
    this.options.nRates = options.nRates;
    this.options.name = options.name || "stars";
    
    this.dontReset = false ;// => used when the form is ajax submitted, then we pass true to this param
    this.disabled = options.disabled || false;
    
    // Overwrite options
    this.options.message = options.message || inputEx.messages.ratingMsg;
    this.options.disableMessage = options.disableMessage;
    this.options.className = options.className ? options.className : 'inputEx-Field inputEx-RatingStars';
    this.setMessage();

  },
  /**
   * Set message options of the selectField
   * @method setMessage
   */
  setMessage: function(){
    var messageArray = this.options.message.split("%");
    
    this.options.message = "";
    if (this.options.averageValue){
      this.options.message = this.options.message + messageArray[0] + this.options.averageValue + "/" + this.options.nStars 
    }
    if(this.options.nRates){
      this.options.message = this.options.message + messageArray[1] + this.options.nRates + messageArray[2]
    }
  },  
  /**
   * render stars
   * @method render
   */
  renderComponent: function(){
    this.starsEls = [];
    this.el = inputEx.cn('div');
    for (var i = 0 ; i < this.options.nStars; i++) {
      // first, make a div and then an a-element in it
      var star = inputEx.cn('div',{id:'star-' + i, className: "inputEx-star"});
      var that = this;
      star.index = i;
      star.onHover = function(){
        that.onHoverStar(this.index);
      }
      star.onClick = function(){
        //by convention the value of the field goes from 1 to 5, as the number of stars. It's weird because there's no 0, but this is it.
        that.onClickRating(this.index+1);
      }
      this.starsEls.push(star);
      var a = inputEx.cn('a',{href:'#' + i},null,i);
      star.appendChild(a);
      this.el.appendChild(star);

      // add needed listeners to every star
      Y.one(star).on('mouseover', star.onHover, star, true);
      Y.one(star).on('click', star.onClick, star, true);
    } 
    Y.one(this.el).on('mouseout', this.resetStars, this, true);
    this.fieldContainer.appendChild(this.el);
    this.divMess = this.fieldContainer.appendChild(inputEx.cn('div', {id: this.divEl.id+'-mess', className: 'inputEx-message'}, null, this.options.message ));

  },
  /**
   * When mouse is over a star
   * @method onHoverStar
   */
  onHoverStar: function(whichStar) {
      if(!this.disabled){
        /* hovers the selected star plus every star before it */
        if(!this.value){
          for (var i=0; i < this.options.nStars; i++) {
            var star = this.starsEls[i],
                a = star.firstChild;
            if(i < whichStar+1 ){
              Y.one(star).addClass('hover');
              Y.one(a).setStyle('width', '100%');            
            } else {
              Y.one(star).removeClass('on');
              Y.one(star).removeClass('hover');
            }

 
          }
        }
      
        if(this.options.starsMessages){
          this.showMessage("<span class=\"inputEx-starMess\">"+this.options.starsMessages[whichStar]+"</span>");
        }
      } else {
        if(this.options.disableMessage){
          this.showMessage("<span class=\"inputEx-disableMessage\">"+this.options.disableMessage+"</span>")
        }
      }
    },  
  /**
   * InitEvents
   * @method initEvents
   */
    initEvents: function(e, whichStar) {
      this.publish("rateEvt");
    },  
  /**
   * reset Stars and note
   * @method resetStars
   */
    resetStars: function(inValue) {
        /* Resets the status of each star */
        
        // if form is not submitted, the number of stars on depends on the 
        // given average value
        if (this.dontReset) {
          return
        }
        var value = lang.isNumber(inValue) ? inValue : this.options.averageValue ;
        var starsOn = Math.floor(value),
            rest = Math.floor((this.options.averageValue - starsOn)*10),
            lastStarWidth;
            
        if (rest > 0){
           starsOn = starsOn + 1;
           lastStarWidth = rest + '0%';
        }
        for (var i=0; i < this.options.nStars ; i++) {
            var star = this.starsEls[i],
                a = star.firstChild;
            Y.one(star).removeClass('hover');
            if(i < starsOn){
              Y.one(star).addClass('on');
            }  else {
              Y.one(star).removeClass('on');
            }
          
            // and for the last one, set width if needed
            if (i == starsOn - 1 && lastStarWidth){
              Y.one(a).setStyle('width', lastStarWidth);
            }
        }
        this.showMessage();
    },
    /**
     * Tell something under the stars
     * @method showMessage
     */
    showMessage: function(text){
      if(!text){
        //default message
        var text = this.options.message
      }
      this.divMess.innerHTML = text;
    },
    /**
     * onAsync is called by the containing form when request is Send
     * @method onAsync
     */
    onAsync : function(){
      this.showMessage("<span class=\"thanks\">"+inputEx.messages.sendingRate+"</span>");
    },
    onEndAsync : function(){
       this.afterRating();
    },
    /**
    * 
    * @method onClickRating
    */
    onClickRating: function(value){
      if(this.disabled){
        return
      }
      this.setValue(value);
      this.dontReset = true;
      this.disable();
      this.fire("rate",value);  
      
    },
    afterRating: function(){
      this.showMessage("<span class=\"thanks\">"+inputEx.messages.thanksRate+"</span>");      
    },
    disable: function(){
      this.disabled = true;  
    },
    enable: function(){
      this.disabled = false;
    },
    setValue: function(value){
      inputEx.RatingStars.superclass.setValue.call(this,value);
      this.value = value;
    },
    getValue: function(){
      return this.value;  
    }
});

 
 // Register this class as "url" type
 inputEx.registerType("ratingstars", inputEx.RatingStars);

},'3.0.0a',{
  requires: ['inputex-field']
});

Copyright © 2011 Eric Abouaf All rights reserved.