Upgrade to ExtJS 3.3.0 - Released 10/06/2010
[extjs.git] / docs / source / rating.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.0
11  * Copyright(c) 2006-2010 Ext JS, Inc.
12  * licensing@extjs.com
13  * http://www.extjs.com/license
14  */
15 Ext.ns('Ext.ux');
16
17 Ext.ux.Rating = Ext.extend(Ext.util.Observable, {
18         // Configuration options
19     starWidth: 16,
20     split: 1,
21     resetValue: '',
22         defaultSelected: -1,    
23     selected: -1,
24     showTitles: true,    
25     
26         // Our class constructor
27     constructor : function(element, config) {
28         Ext.apply(this, config);
29         Ext.ux.Rating.superclass.constructor.call(this);
30         
31         this.addEvents(
32             'change',
33             'reset'
34         );
35         
36         this.el = Ext.get(element);
37         this.init();
38     },
39     
40     init : function() {
41         var me = this;
42         
43                 // Some arrays we are going to store data in
44         this.values = [];
45         this.titles = [];
46         this.stars = [];
47                 
48                 // We create a container to put all our stars into      
49         this.container = this.el.createChild({
50             cls: 'ux-rating-container ux-rating-clearfix'
51         });
52                                 
53         if(this.canReset) {
54             this.resetEl = this.container.createChild({
55                 cls: 'ux-rating-reset',
56                 cn: [{
57                     tag: 'a',
58                     title: this.showTitles ? (this.resetTitle || 'Reset your vote') : '',
59                     html: 'Reset'
60                 }]
61             });
62             this.resetEl.visibilityMode = Ext.Element.DISPLAY;
63             
64             this.resetEl.hover(function() {
65                 Ext.fly(this).addClass('ux-rating-reset-hover');
66             }, function() {
67                 Ext.fly(this).removeClass('ux-rating-reset-hover');
68             });
69             
70             this.resetEl.on('click', this.reset, this);
71         }
72
73                 // We use DomQuery to select the radio buttons
74                 this.radioBoxes = this.el.select('input[type=radio]');
75                 // Then we can loop over the CompositeElement using each
76         this.radioBoxes.each(this.initStar, this);
77         
78                 // We use DomHelper to create our hidden input
79                 this.input = this.container.createChild({
80                         tag: 'input',
81                         type: 'hidden',
82                         name: this.name,
83                         value: this.values[this.defaultSelected] || this.resetValue
84                 });
85                 
86                 // Lets remove all the radio buttons from the DOM
87                 this.radioBoxes.remove();
88                 
89         this.select(this.defaultSelected === undefined ? false : this.defaultSelected)
90
91         if(this.disabled) {
92             this.disable();
93         } else {
94                         // Enable will set up our event listeners
95             this.enable();
96         }
97     },
98
99     initStar : function(item, all, i) {
100         var sw = Math.floor(this.starWidth / this.split);
101         
102                 // We use the name and disabled attributes of the first radio button 
103                 if(i == 0) {
104                 this.name = item.dom.name;
105                 this.disabled = item.dom.disabled;              
106                 }
107                 
108                 // Saving the value and title for this star
109         this.values[i] = item.dom.value;
110         this.titles[i] = item.dom.title;
111
112         if(item.dom.checked) {
113             this.defaultSelected = i;
114         }
115         
116                 // Now actually create the star!
117         var star = this.container.createChild({
118             cls: 'ux-rating-star'
119         });
120         
121         var starLink = star.createChild({
122             tag: 'a',
123             html: this.values[i],
124             title: this.showTitles ? this.titles[i] : ''
125         });
126         
127         // Prepare division settings
128         if(this.split) {
129           var odd = (i % this.split);              
130           star.setWidth(sw);
131           starLink.setStyle('margin-left', '-' + (odd * sw) + 'px');
132         }
133
134                 // Save the reference to this star so we can easily access it later
135         this.stars.push(star.dom);
136     },
137     
138     onStarClick : function(ev, t) {
139         if(!this.disabled) {
140             this.select(this.stars.indexOf(t));
141         }
142     },
143
144     onStarOver : function(ev, t) {
145         if(!this.disabled) {
146             this.fillTo(this.stars.indexOf(t), true);
147         }        
148     },
149     
150     onStarOut : function(ev, t) {
151         if(!this.disabled) {
152             this.fillTo(this.selected, false);            
153         }
154     },
155     
156     reset : function(ev, t) {
157         this.select(-1);
158     },
159     
160     select : function(index) {
161         if(index === false || index === -1) {
162             // remove current selection in el
163             this.value = this.resetValue;
164             this.title = "";
165                         this.input.dom.value = '';    
166             
167             if(this.canReset) {
168                 this.resetEl.setOpacity(0.5);
169             }
170             
171             this.fillNone();
172             
173             if(this.selected !== -1) {
174                 this.fireEvent('change', this, this.values[index], this.stars[index]);              
175             }
176             this.selected = -1;            
177         }
178         else if(index !== this.selected) {
179                         // Update some properties         
180             this.selected = index;
181             this.value = this.values[index];
182             this.title = this.titles[index];
183                         
184                         // Set the value of our hidden input so the rating can be submitted                     
185                         this.input.dom.value = this.value;
186                         
187             if(this.canReset) {
188                 this.resetEl.setOpacity(0.99);
189             }
190             
191                         // the fillTo() method will fill the stars up until the selected one        
192             this.fillTo(index, false);
193             
194                         // Lets also not forget to fire our custom event!
195             this.fireEvent('change', this, this.values[index], this.stars[index]);            
196         }     
197     },
198     
199     fillTo : function(index, hover) {
200         if (index != -1) {
201             var addClass = hover ? 'ux-rating-star-hover' : 'ux-rating-star-on';
202             var removeClass = hover ? 'ux-rating-star-on' : 'ux-rating-star-hover';
203              
204                         // We add a css class to each star up until the selected one   
205             Ext.each(this.stars.slice(0, index+1), function() {
206                 Ext.fly(this).removeClass(removeClass).addClass(addClass);
207             });
208
209                         // And then remove the same class from all the stars after this one
210             Ext.each(this.stars.slice(index+1), function() {
211                 Ext.fly(this).removeClass([removeClass, addClass]);
212             });
213         }
214         else {
215             this.fillNone();
216         }        
217     },
218     
219     fillNone : function() {
220         this.container.select('.ux-rating-star').removeClass(['ux-rating-star-hover', 'ux-rating-star-on']);
221     },
222
223     enable : function() {               
224         if(this.canReset) {
225             this.resetEl.show();
226         }
227         
228         this.input.dom.disabled = null;
229         this.disabled = false;
230         
231         this.container.removeClass('ux-rating-disabled');
232  
233                 // We will be using the technique of event delegation by listening
234         // for bubbled up events on the container       
235         this.container.on({
236             click: this.onStarClick, 
237             mouseover: this.onStarOver,
238             mouseout: this.onStarOut,
239             scope: this,
240             delegate: 'div.ux-rating-star'
241         });        
242     },
243             
244     disable : function() {
245         if(this.canReset) {
246             this.resetEl.hide();
247         }
248         
249         this.input.dom.disabled = true;
250         this.disabled = true;
251         
252         this.container.addClass('ux-rating-disabled');
253
254         this.container.un({
255             click: this.onStarClick, 
256             mouseover: this.onStarOver,
257             mouseout: this.onStarOut,
258             scope: this,
259             delegate: 'div.ux-rating-star'
260         });        
261     },
262     
263     getValue : function() {
264         return this.values[this.selected] || this.resetValue;
265     },
266         
267         destroy : function() {
268                 this.disable();
269                 this.container.remove();
270                 this.radioBoxes.appendTo(this.el);
271                 if(this.selected !== -1) {
272                         this.radioBoxes.elements[this.selected].checked = true;
273                 }
274         }
275 });
276 </pre>    
277 </body>
278 </html>