Index: trunk/extensions/ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.js |
— | — | @@ -60,8 +60,15 @@ |
61 | 61 | 'rating': '\ |
62 | 62 | <div class="articleFeedback-rating">\ |
63 | 63 | <div class="articleFeedback-label"></div>\ |
64 | | - <div class="articleFeedback-rating-fields articleFeedback-visibleWith-form"><input type="radio" /><input type="radio" /><input type="radio" /><input type="radio" /><input type="radio" /></div>\ |
65 | | - <div class="articleFeedback-rating-labels articleFeedback-visibleWith-form"><label></label><label></label><label></label><label></label><label></label><div class="articleFeedback-rating-clear"></div></div>\ |
| 64 | + <input type="hidden" />\ |
| 65 | + <div class="articleFeedback-rating-labels articleFeedback-visibleWith-form">\ |
| 66 | + <div class="articleFeedback-rating-label" rel="1"></div>\ |
| 67 | + <div class="articleFeedback-rating-label" rel="2"></div>\ |
| 68 | + <div class="articleFeedback-rating-label" rel="3"></div>\ |
| 69 | + <div class="articleFeedback-rating-label" rel="4"></div>\ |
| 70 | + <div class="articleFeedback-rating-label" rel="5"></div>\ |
| 71 | + <div class="articleFeedback-rating-clear"></div>\ |
| 72 | + </div>\ |
66 | 73 | <div class="articleFeedback-rating-average articleFeedback-visibleWith-report"></div>\ |
67 | 74 | <div class="articleFeedback-rating-meter articleFeedback-visibleWith-report"><div></div></div>\ |
68 | 75 | <div class="articleFeedback-rating-count articleFeedback-visibleWith-report"></div>\ |
— | — | @@ -98,18 +105,18 @@ |
99 | 106 | }, |
100 | 107 | 'updateRating': function() { |
101 | 108 | var $rating = $(this); |
102 | | - $rating.find( 'label' ).removeClass( 'articleFeedback-rating-label-full' ); |
103 | | - var $label = $rating |
104 | | - .find( 'label[for=' + $rating.find( 'input:radio:checked' ) |
105 | | - .attr( 'id' ) + ']' ); |
| 109 | + $rating.find( '.articleFeedback-rating-label' ) |
| 110 | + .removeClass( 'articleFeedback-rating-label-full' ); |
| 111 | + var val = $rating.find( 'input:hidden' ).val(); |
| 112 | + var $label = $rating.find( '.articleFeedback-rating-label[rel="' + val + '"]' ); |
106 | 113 | if ( $label.length ) { |
107 | 114 | $label |
108 | | - .prevAll( 'label' ) |
| 115 | + .prevAll( '.articleFeedback-rating-label' ) |
109 | 116 | .add( $label ) |
110 | 117 | .addClass( 'articleFeedback-rating-label-full' ) |
111 | 118 | .end() |
112 | 119 | .end() |
113 | | - .nextAll( 'label' ) |
| 120 | + .nextAll( '.articleFeedback-rating-label' ) |
114 | 121 | .removeClass( 'articleFeedback-rating-label-full' ); |
115 | 122 | $rating.find( '.articleFeedback-rating-clear' ).show(); |
116 | 123 | } else { |
— | — | @@ -132,8 +139,7 @@ |
133 | 140 | var data = {}; |
134 | 141 | for ( var key in context.options.ratings ) { |
135 | 142 | var id = context.options.ratings[key].id; |
136 | | - // Default to 0 if the radio set doesn't contain a checked element |
137 | | - data['r' + id] = context.$ui.find( 'input[name=r' + id + ']:checked' ).val() || 0; |
| 143 | + data['r' + id] = context.$ui.find( 'input[name="r' + id + '"]' ).val(); |
138 | 144 | } |
139 | 145 | var expertise = []; |
140 | 146 | context.$ui.find( '.articleFeedback-expertise input:checked' ).each( function() { |
— | — | @@ -204,6 +210,7 @@ |
205 | 211 | 'type': 'GET', |
206 | 212 | 'dataType': 'json', |
207 | 213 | 'context': context, |
| 214 | + 'cache': false, |
208 | 215 | 'data': { |
209 | 216 | 'action': 'query', |
210 | 217 | 'format': 'json', |
— | — | @@ -214,103 +221,101 @@ |
215 | 222 | }, |
216 | 223 | 'success': function( data ) { |
217 | 224 | var context = this; |
218 | | - if ( !$.isArray( data.query.articlefeedback ) ) { |
219 | | - mw.log( 'Report response error' ); |
| 225 | + if ( |
| 226 | + !$.isArray( data.query.articlefeedback ) |
| 227 | + || !data.query.articlefeedback.length |
| 228 | + ) { |
| 229 | + mw.log( 'ArticleFeedback invalid response error.' ); |
220 | 230 | context.$ui.find( '.articleFeedback-error' ).show(); |
221 | 231 | return; |
222 | 232 | } |
223 | | - if ( |
224 | | - data.query.articlefeedback.length |
225 | | - && typeof data.query.articlefeedback[0].expertise === 'string' |
226 | | - ) { |
227 | | - var $expertise = context.$ui.find( '.articleFeedback-expertise' ); |
228 | | - var tags = data.query.articlefeedback[0].expertise.split( '|' ); |
229 | | - for ( var i = 0; i < tags.length; i++ ) { |
230 | | - $expertise.find( 'input:checkbox[value=' + tags[i] + ']' ) |
231 | | - .attr( 'checked', true ); |
| 233 | + var feedback = data.query.articlefeedback[0]; |
| 234 | + |
| 235 | + // Expertise |
| 236 | + var $expertise = context.$ui.find( '.articleFeedback-expertise' ); |
| 237 | + if ( typeof feedback.expertise === 'string' ) { |
| 238 | + var tags = feedback.expertise.split( '|' ); |
| 239 | + if ( $.inArray( 'general', tags ) !== -1 ) { |
| 240 | + $expertise.find( 'input:checkbox' ).each( function() { |
| 241 | + $(this).attr( 'checked', $.inArray( $(this).val(), tags ) !== -1 ); |
| 242 | + } ); |
| 243 | + // IE7 seriously has issues, and we have to hide, then show |
| 244 | + $expertise.find( '.articleFeedback-expertise-options' ) |
| 245 | + .hide().show(); |
| 246 | + $.articleFeedback.fn.enableExpertise( $expertise ); |
232 | 247 | } |
233 | | - if ( $expertise.find( 'input:checkbox[value=general]:checked' ).size() ) { |
234 | | - $expertise |
235 | | - .each( function() { |
236 | | - $.articleFeedback.fn.enableExpertise( $(this) ); |
237 | | - } ) |
238 | | - .find( '.articleFeedback-expertise-options' ) |
239 | | - .show(); |
| 248 | + } else { |
| 249 | + $expertise |
| 250 | + .find( 'input:checkbox' ) |
| 251 | + .attr( 'checked', false ) |
| 252 | + .end() |
| 253 | + .find( '.articleFeedback-expertise-options' ) |
| 254 | + .hide(); |
| 255 | + } |
| 256 | + |
| 257 | + // Index rating data by rating ID |
| 258 | + var ratings = {}; |
| 259 | + if ( typeof feedback.ratings === 'object' && feedback.ratings !== null ) { |
| 260 | + for ( var i = 0; i < feedback.ratings.length; i++ ) { |
| 261 | + ratings[feedback.ratings[i].ratingid] = feedback.ratings[i]; |
240 | 262 | } |
241 | 263 | } |
242 | | - var expired = false; |
| 264 | + |
| 265 | + // Ratings |
243 | 266 | context.$ui.find( '.articleFeedback-rating' ).each( function() { |
244 | | - var ratingData; |
245 | | - // Try to get data provided for this rating |
| 267 | + var name = $(this).attr( 'rel' ); |
| 268 | + var rating = name in context.options.ratings |
| 269 | + && context.options.ratings[name].id in ratings ? |
| 270 | + ratings[context.options.ratings[name].id] : null; |
| 271 | + // Report |
246 | 272 | if ( |
247 | | - data.query.articlefeedback.length && |
248 | | - typeof data.query.articlefeedback[0].ratings !== 'undefined' |
| 273 | + rating !== null |
| 274 | + && 'total' in rating |
| 275 | + && 'count' in rating |
| 276 | + && rating.total > 0 |
249 | 277 | ) { |
250 | | - if ( 'status' in data.query.articlefeedback[0] ) { |
251 | | - if ( data.query.articlefeedback[0].status == 'expired' ) { |
252 | | - expired = true; |
253 | | - } |
254 | | - } |
255 | | - if ( 'ratings' in data.query.articlefeedback[0] ) { |
256 | | - var ratingsData = data.query.articlefeedback[0].ratings; |
257 | | - var id = context.options.ratings[$(this).attr( 'rel' )].id; |
258 | | - for ( var i = 0; i < ratingsData.length; i++ ) { |
259 | | - if ( ratingsData[i].ratingid == id ) { |
260 | | - ratingData = ratingsData[i]; |
261 | | - } |
262 | | - } |
263 | | - } |
264 | | - } |
265 | | - // Report |
266 | | - if ( typeof ratingData === 'undefined' || ratingData.total == 0 ) { |
267 | | - // Setup in "no ratings" mode |
| 278 | + var average = Math.round( ( rating.total / rating.count ) * 10 ) / 10; |
268 | 279 | $(this) |
269 | 280 | .find( '.articleFeedback-rating-average' ) |
270 | | - .html( ' ' ) |
| 281 | + .text( average + ( average % 1 === 0 ? '.0' : '' ) ) |
271 | 282 | .end() |
272 | 283 | .find( '.articleFeedback-rating-meter div' ) |
273 | | - .css( 'width', 0 ) |
| 284 | + .css( 'width', Math.round( average * 21 ) + 'px' ) |
274 | 285 | .end() |
275 | 286 | .find( '.articleFeedback-rating-count' ) |
276 | | - .text( mw.msg( 'articlefeedback-report-empty' ) ) |
| 287 | + .text( |
| 288 | + mw.msg( 'articlefeedback-report-ratings', rating.count ) |
| 289 | + ) |
277 | 290 | .end(); |
278 | 291 | } else { |
279 | | - // Setup using ratingData |
280 | | - var average = |
281 | | - Math.round( ( ratingData.total / ratingData.count ) * 10 ) / 10; |
| 292 | + // Special case for no ratings |
282 | 293 | $(this) |
283 | 294 | .find( '.articleFeedback-rating-average' ) |
284 | | - .text( average + ( average % 1 === 0 ? '.0' : '' ) ) |
| 295 | + .html( ' ' ) |
285 | 296 | .end() |
286 | 297 | .find( '.articleFeedback-rating-meter div' ) |
287 | | - .css( 'width', Math.round( average * 21 ) + 'px' ) |
| 298 | + .css( 'width', 0 ) |
288 | 299 | .end() |
289 | 300 | .find( '.articleFeedback-rating-count' ) |
290 | | - .text( mw.msg( |
291 | | - 'articlefeedback-report-ratings', ratingData.count |
292 | | - ) ) |
| 301 | + .text( mw.msg( 'articlefeedback-report-empty' ) ) |
293 | 302 | .end(); |
294 | 303 | } |
295 | 304 | // Form |
296 | | - if ( typeof ratingData.userrating !== 'undefined' ) { |
297 | | - if ( ratingData.userrating == 0 ) { |
298 | | - $(this) |
299 | | - .find( 'input' ) |
300 | | - .attr( 'checked', false ); |
301 | | - } else { |
302 | | - $(this) |
303 | | - .find( 'input[value="' + ratingData.userrating + '"]' ) |
304 | | - .attr( 'checked', true ); |
| 305 | + if ( rating !== null && typeof rating.userrating !== 'undefined' ) { |
| 306 | + $(this).find( 'input:hidden' ).val( rating.userrating ); |
| 307 | + if ( rating.userrating > 0 ) { |
| 308 | + // If any ratings exist, make sure expertise is enabled so users can |
| 309 | + // suppliment their ratings with expertise information |
| 310 | + $.articleFeedback.fn.enableExpertise( $expertise ); |
305 | 311 | } |
306 | | - // If any ratings exist, make sure expertise is enabled so users can |
307 | | - // suppliment their ratings. |
308 | | - $.articleFeedback.fn.enableExpertise( |
309 | | - context.$ui.find( '.articleFeedback-expertise' ) |
310 | | - ); |
| 312 | + } else { |
| 313 | + $(this).find( 'input:hidden' ).val( 0 ); |
311 | 314 | } |
| 315 | + // Update rating controls based on the form data |
312 | 316 | $.articleFeedback.fn.updateRating.call( $(this) ); |
313 | 317 | } ); |
314 | | - if ( expired ) { |
| 318 | + // Expiration |
| 319 | + if ( typeof feedback.status === 'string' && feedback.status === 'expired' ) { |
315 | 320 | context.$ui |
316 | 321 | .addClass( 'articleFeedback-expired' ) |
317 | 322 | .find( '.articleFeedback-expiry' ) |
— | — | @@ -321,7 +326,7 @@ |
322 | 327 | .find( '.articleFeedback-expiry' ) |
323 | 328 | .slideUp( 'fast' ); |
324 | 329 | } |
325 | | - // If being called just after a submit, we need to un-new the rating controls |
| 330 | + // Status change - un-new the rating controls |
326 | 331 | context.$ui.find( '.articleFeedback-rating-new' ) |
327 | 332 | .removeClass( 'articleFeedback-rating-new' ); |
328 | 333 | }, |
— | — | @@ -503,26 +508,10 @@ |
504 | 509 | .find( '.articleFeedback-visibleWith-report' ) |
505 | 510 | .hide() |
506 | 511 | .end() |
507 | | - // Connect labels and fields |
| 512 | + // Name the hidden fields |
508 | 513 | .find( '.articleFeedback-rating' ) |
509 | 514 | .each( function( rating ) { |
510 | | - var rel = $(this).attr( 'rel' ); |
511 | | - var id = 'articleFeedback-rating-field-' + rel + '-'; |
512 | | - $(this) |
513 | | - .find( '.articleFeedback-rating-fields input' ) |
514 | | - .attr( 'name', rel ) |
515 | | - .each( function( field ) { |
516 | | - $(this).attr( { |
517 | | - 'value': field + 1, |
518 | | - 'name': 'r' + ( rating + 1 ), |
519 | | - 'id': id + ( field + 1 ) |
520 | | - } ); |
521 | | - } ) |
522 | | - .end() |
523 | | - .find( '.articleFeedback-rating-labels label' ) |
524 | | - .each( function( i ) { |
525 | | - $(this).attr( 'for', id + ( i + 1 ) ); |
526 | | - } ); |
| 515 | + $(this).find( 'input:hidden' ) .attr( 'name', 'r' + ( rating + 1 ) ); |
527 | 516 | } ) |
528 | 517 | .end() |
529 | 518 | // Setup switch behavior |
— | — | @@ -544,18 +533,18 @@ |
545 | 534 | } ) |
546 | 535 | .end() |
547 | 536 | // Setup rating behavior |
548 | | - .find( '.articleFeedback-rating-labels label' ) |
| 537 | + .find( '.articleFeedback-rating-label' ) |
549 | 538 | .hover( |
550 | 539 | function() { |
551 | 540 | $(this) |
552 | 541 | .addClass( 'articleFeedback-rating-label-hover-head' ) |
553 | | - .prevAll( 'label' ) |
| 542 | + .prevAll( '.articleFeedback-rating-label' ) |
554 | 543 | .addClass( 'articleFeedback-rating-label-hover-tail' ); |
555 | 544 | }, |
556 | 545 | function() { |
557 | 546 | $(this) |
558 | 547 | .removeClass( 'articleFeedback-rating-label-hover-head' ) |
559 | | - .prevAll( 'label' ) |
| 548 | + .prevAll( '.articleFeedback-rating-label' ) |
560 | 549 | .removeClass( 'articleFeedback-rating-label-hover-tail' ); |
561 | 550 | $.articleFeedback.fn.updateRating.call( |
562 | 551 | $(this).closest( '.articleFeedback-rating' ) |
— | — | @@ -564,6 +553,7 @@ |
565 | 554 | ) |
566 | 555 | .mousedown( function() { |
567 | 556 | $.articleFeedback.fn.enableSubmission.call( context, true ); |
| 557 | + |
568 | 558 | if ( context.$ui.hasClass( 'articleFeedback-expired' ) ) { |
569 | 559 | // Changing one means the rest will get submitted too |
570 | 560 | context.$ui |
— | — | @@ -579,6 +569,9 @@ |
580 | 570 | $(this) |
581 | 571 | .closest( '.articleFeedback-rating' ) |
582 | 572 | .addClass( 'articleFeedback-rating-new' ) |
| 573 | + .find( 'input:hidden' ) |
| 574 | + .val( $(this).attr( 'rel' ) ) |
| 575 | + .end() |
583 | 576 | .end() |
584 | 577 | .addClass( 'articleFeedback-rating-label-down' ) |
585 | 578 | .nextAll() |
— | — | @@ -597,7 +590,7 @@ |
598 | 591 | $.articleFeedback.fn.enableSubmission.call( context, true ); |
599 | 592 | $(this).hide(); |
600 | 593 | var $rating = $(this).closest( '.articleFeedback-rating' ); |
601 | | - $rating.find( 'input:radio' ).attr( 'checked', false ); |
| 594 | + $rating.find( 'input:hidden' ).val( 0 ); |
602 | 595 | $.articleFeedback.fn.updateRating.call( $rating ); |
603 | 596 | } ); |
604 | 597 | // Show initial form and report values |
Index: trunk/extensions/ArticleFeedback/modules/jquery.articleFeedback/jquery.articleFeedback.css |
— | — | @@ -164,17 +164,11 @@ |
165 | 165 | margin-bottom: 0.75em; |
166 | 166 | } |
167 | 167 | |
168 | | -.articleFeedback-rating-fields { |
169 | | - width: 0px; |
170 | | - height: 0px; |
171 | | - overflow: hidden; |
172 | | -} |
173 | | - |
174 | 168 | .articleFeedback-rating-labels { |
175 | 169 | margin-left: 10px; |
176 | 170 | } |
177 | 171 | |
178 | | -.articleFeedback-rating-labels label, .articleFeedback-rating-clear { |
| 172 | +.articleFeedback-rating-label, .articleFeedback-rating-clear { |
179 | 173 | float: left; |
180 | 174 | height: 21px; |
181 | 175 | width: 21px; |
— | — | @@ -182,7 +176,7 @@ |
183 | 177 | background-position: center center; |
184 | 178 | cursor: pointer; |
185 | 179 | } |
186 | | -.articleFeedback-rating-labels label { |
| 180 | +.articleFeedback-rating-label { |
187 | 181 | /* @embed */ |
188 | 182 | background-image: url(images/star-empty.png); |
189 | 183 | } |
— | — | @@ -198,28 +192,28 @@ |
199 | 193 | background-image: url(images/trash-hover.png); |
200 | 194 | } |
201 | 195 | |
202 | | -.articleFeedback-rating-labels label.articleFeedback-rating-label-full { |
| 196 | +.articleFeedback-rating-label.articleFeedback-rating-label-full { |
203 | 197 | /* @embed */ |
204 | 198 | background-image: url(images/star-full.png); |
205 | 199 | } |
206 | 200 | |
207 | | -.articleFeedback-expired .articleFeedback-rating-labels label.articleFeedback-rating-label-full { |
| 201 | +.articleFeedback-expired .articleFeedback-rating-label.articleFeedback-rating-label-full { |
208 | 202 | /* @embed */ |
209 | 203 | background-image: url(images/star-full-expired.png); |
210 | 204 | } |
211 | 205 | |
212 | | -.articleFeedback-rating-new .articleFeedback-rating-labels label.articleFeedback-rating-label-full, |
213 | | -.articleFeedback-rating .articleFeedback-rating-labels label.articleFeedback-rating-label-hover-tail { |
| 206 | +.articleFeedback-rating-new .articleFeedback-rating-label.articleFeedback-rating-label-full, |
| 207 | +.articleFeedback-rating .articleFeedback-rating-label.articleFeedback-rating-label-hover-tail { |
214 | 208 | /* @embed */ |
215 | 209 | background-image: url(images/star-new.png); |
216 | 210 | } |
217 | 211 | |
218 | | -.articleFeedback-rating .articleFeedback-rating-labels label.articleFeedback-rating-label-hover-head { |
| 212 | +.articleFeedback-rating .articleFeedback-rating-label.articleFeedback-rating-label-hover-head { |
219 | 213 | /* @embed */ |
220 | 214 | background-image: url(images/star-new-hover.png); |
221 | 215 | } |
222 | 216 | |
223 | | -.articleFeedback-rating-new .articleFeedback-rating-labels label.articleFeedback-rating-label-down { |
| 217 | +.articleFeedback-rating-new .articleFeedback-rating-label.articleFeedback-rating-label-down { |
224 | 218 | /* @embed */ |
225 | 219 | background-image: url(images/star-new-down.png); |
226 | 220 | } |