X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/2e847cf21b8ab9d15fa167b315ca5b2fa92638fc..6a7e4474cba9d8be4b2ec445e10f1691f7277c50:/src/ext-core/examples/rating/rating.js diff --git a/src/ext-core/examples/rating/rating.js b/src/ext-core/examples/rating/rating.js new file mode 100644 index 00000000..49e7051a --- /dev/null +++ b/src/ext-core/examples/rating/rating.js @@ -0,0 +1,267 @@ +/*! + * 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; + } + } +});