--- /dev/null
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+</head>
+<body onload="prettyPrint();">
+ <pre class="prettyprint lang-js">/*!
+ * Ext JS Library 3.2.0
+ * Copyright(c) 2006-2010 Ext JS, Inc.
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+Ext.ns('Ext.ux');
+
+Ext.ux.Rating = Ext.extend(Ext.util.Observable, {
+ // Configuration options
+ starWidth: 16,
+ split: 1,
+ resetValue: '',
+ defaultSelected: -1,
+ selected: -1,
+ showTitles: true,
+
+ // Our class constructor
+ constructor : function(element, config) {
+ Ext.apply(this, config);
+ Ext.ux.Rating.superclass.constructor.call(this);
+
+ this.addEvents(
+ 'change',
+ 'reset'
+ );
+
+ this.el = Ext.get(element);
+ this.init();
+ },
+
+ init : function() {
+ var me = this;
+
+ // Some arrays we are going to store data in
+ this.values = [];
+ this.titles = [];
+ this.stars = [];
+
+ // We create a container to put all our stars into
+ this.container = this.el.createChild({
+ cls: 'ux-rating-container ux-rating-clearfix'
+ });
+
+ if(this.canReset) {
+ this.resetEl = this.container.createChild({
+ cls: 'ux-rating-reset',
+ cn: [{
+ tag: 'a',
+ title: this.showTitles ? (this.resetTitle || 'Reset your vote') : '',
+ html: 'Reset'
+ }]
+ });
+ this.resetEl.visibilityMode = Ext.Element.DISPLAY;
+
+ this.resetEl.hover(function() {
+ Ext.fly(this).addClass('ux-rating-reset-hover');
+ }, function() {
+ Ext.fly(this).removeClass('ux-rating-reset-hover');
+ });
+
+ this.resetEl.on('click', this.reset, this);
+ }
+
+ // We use DomQuery to select the radio buttons
+ this.radioBoxes = this.el.select('input[type=radio]');
+ // Then we can loop over the CompositeElement using each
+ this.radioBoxes.each(this.initStar, this);
+
+ // We use DomHelper to create our hidden input
+ this.input = this.container.createChild({
+ tag: 'input',
+ type: 'hidden',
+ name: this.name,
+ value: this.values[this.defaultSelected] || this.resetValue
+ });
+
+ // Lets remove all the radio buttons from the DOM
+ this.radioBoxes.remove();
+
+ this.select(this.defaultSelected === undefined ? false : this.defaultSelected)
+
+ if(this.disabled) {
+ this.disable();
+ } else {
+ // Enable will set up our event listeners
+ this.enable();
+ }
+ },
+
+ initStar : function(item, all, i) {
+ var sw = Math.floor(this.starWidth / this.split);
+
+ // We use the name and disabled attributes of the first radio button
+ if(i == 0) {
+ this.name = item.dom.name;
+ this.disabled = item.dom.disabled;
+ }
+
+ // Saving the value and title for this star
+ this.values[i] = item.dom.value;
+ this.titles[i] = item.dom.title;
+
+ if(item.dom.checked) {
+ this.defaultSelected = i;
+ }
+
+ // Now actually create the star!
+ var star = this.container.createChild({
+ cls: 'ux-rating-star'
+ });
+
+ var starLink = star.createChild({
+ tag: 'a',
+ html: this.values[i],
+ title: this.showTitles ? this.titles[i] : ''
+ });
+
+ // Prepare division settings
+ if(this.split) {
+ var odd = (i % this.split);
+ star.setWidth(sw);
+ starLink.setStyle('margin-left', '-' + (odd * sw) + 'px');
+ }
+
+ // Save the reference to this star so we can easily access it later
+ this.stars.push(star.dom);
+ },
+
+ onStarClick : function(ev, t) {
+ if(!this.disabled) {
+ this.select(this.stars.indexOf(t));
+ }
+ },
+
+ onStarOver : function(ev, t) {
+ if(!this.disabled) {
+ this.fillTo(this.stars.indexOf(t), true);
+ }
+ },
+
+ onStarOut : function(ev, t) {
+ if(!this.disabled) {
+ this.fillTo(this.selected, false);
+ }
+ },
+
+ reset : function(ev, t) {
+ this.select(-1);
+ },
+
+ select : function(index) {
+ if(index === false || index === -1) {
+ // remove current selection in el
+ this.value = this.resetValue;
+ this.title = "";
+ this.input.dom.value = '';
+
+ if(this.canReset) {
+ this.resetEl.setOpacity(0.5);
+ }
+
+ this.fillNone();
+
+ if(this.selected !== -1) {
+ this.fireEvent('change', this, this.values[index], this.stars[index]);
+ }
+ this.selected = -1;
+ }
+ else if(index !== this.selected) {
+ // Update some properties
+ this.selected = index;
+ this.value = this.values[index];
+ this.title = this.titles[index];
+
+ // Set the value of our hidden input so the rating can be submitted
+ this.input.dom.value = this.value;
+
+ if(this.canReset) {
+ this.resetEl.setOpacity(0.99);
+ }
+
+ // the fillTo() method will fill the stars up until the selected one
+ this.fillTo(index, false);
+
+ // Lets also not forget to fire our custom event!
+ this.fireEvent('change', this, this.values[index], this.stars[index]);
+ }
+ },
+
+ fillTo : function(index, hover) {
+ if (index != -1) {
+ var addClass = hover ? 'ux-rating-star-hover' : 'ux-rating-star-on';
+ var removeClass = hover ? 'ux-rating-star-on' : 'ux-rating-star-hover';
+
+ // We add a css class to each star up until the selected one
+ Ext.each(this.stars.slice(0, index+1), function() {
+ Ext.fly(this).removeClass(removeClass).addClass(addClass);
+ });
+
+ // And then remove the same class from all the stars after this one
+ Ext.each(this.stars.slice(index+1), function() {
+ Ext.fly(this).removeClass([removeClass, addClass]);
+ });
+ }
+ else {
+ this.fillNone();
+ }
+ },
+
+ fillNone : function() {
+ this.container.select('.ux-rating-star').removeClass(['ux-rating-star-hover', 'ux-rating-star-on']);
+ },
+
+ enable : function() {
+ if(this.canReset) {
+ this.resetEl.show();
+ }
+
+ this.input.dom.disabled = null;
+ this.disabled = false;
+
+ this.container.removeClass('ux-rating-disabled');
+
+ // We will be using the technique of event delegation by listening
+ // for bubbled up events on the container
+ this.container.on({
+ click: this.onStarClick,
+ mouseover: this.onStarOver,
+ mouseout: this.onStarOut,
+ scope: this,
+ delegate: 'div.ux-rating-star'
+ });
+ },
+
+ disable : function() {
+ if(this.canReset) {
+ this.resetEl.hide();
+ }
+
+ this.input.dom.disabled = true;
+ this.disabled = true;
+
+ this.container.addClass('ux-rating-disabled');
+
+ this.container.un({
+ click: this.onStarClick,
+ mouseover: this.onStarOver,
+ mouseout: this.onStarOut,
+ scope: this,
+ delegate: 'div.ux-rating-star'
+ });
+ },
+
+ getValue : function() {
+ return this.values[this.selected] || this.resetValue;
+ },
+
+ destroy : function() {
+ this.disable();
+ this.container.remove();
+ this.radioBoxes.appendTo(this.el);
+ if(this.selected !== -1) {
+ this.radioBoxes.elements[this.selected].checked = true;
+ }
+ }
+});
+</pre>
+</body>
+</html>
\ No newline at end of file