liquid_feedback_frontend

view static/js/voting.js @ 945:b865f87ea810

Work on robustification of JavaScript voting
author jbe
date Thu Nov 08 13:17:37 2012 +0100 (2012-11-08)
parents ebcc40a3f8b3
children c328da62f45c
line source
1 jsProtect(function() {
2 voting_text_approval_single = "Approval"
3 voting_text_approval_multi = "Approval"
4 voting_text_first_preference_single = "Approval (first preference)"
5 voting_text_first_preference_multi = "Approval (first preference)"
6 voting_text_second_preference_single = "Approval (second preference)"
7 voting_text_second_preference_multi = "Approval (second preference)"
8 voting_text_third_preference_single = "Approval (third preference)"
9 voting_text_third_preference_multi = "Approval (third preference)"
10 voting_text_numeric_preference_single = "Approval (#th preference)"
11 voting_text_numeric_preference_multi = "Approval (#th preference)"
12 voting_text_abstention_single = "Abstention"
13 voting_text_abstention_multi = "Abstention"
14 voting_text_disapproval_above_one_single = "Disapproval (prefer to lower block)"
15 voting_text_disapproval_above_one_multi = "Disapproval (prefer to lower block)"
16 voting_text_disapproval_above_many_single = "Disapproval (prefer to lower blocks)"
17 voting_text_disapproval_above_many_multi = "Disapproval (prefer to lower blocks)"
18 voting_text_disapproval_above_last_single = "Disapproval (prefer to last block)"
19 voting_text_disapproval_above_last_multi = "Disapproval (prefer to last block)"
20 voting_text_disapproval_single = "Disapproval"
21 voting_text_disapproval_multi = "Disapproval"
23 function voting_setCategoryHeadings() {
24 var approvalCount = 0;
25 var disapprovalCount = 0;
26 var sections = document.getElementById("voting").childNodes;
27 for (var i=0; i<sections.length; i++) {
28 var section = sections[i];
29 if (section.className == "approval") approvalCount++;
30 if (section.className == "disapproval") disapprovalCount++;
31 }
32 var approvalIndex = 0;
33 var disapprovalIndex = 0;
34 for (var i=0; i<sections.length; i++) {
35 var section = sections[i];
36 if (
37 section.className == "approval" ||
38 section.className == "abstention" ||
39 section.className == "disapproval"
40 ) {
41 var setHeading = function(heading) {
42 var headingNodes = section.childNodes;
43 for (var j=0; j<headingNodes.length; j++) {
44 var headingNode = headingNodes[j];
45 if (headingNode.className == "cathead") {
46 headingNode.textContent = heading;
47 }
48 }
49 }
50 var count = 0;
51 var entries = section.childNodes;
52 for (var j=0; j<entries.length; j++) {
53 var entry = entries[j];
54 if (entry.className == "movable") count++;
55 }
56 if (section.className == "approval") {
57 if (approvalCount > 1) {
58 if (approvalIndex == 0) {
59 if (count == 1) setHeading(voting_text_first_preference_single);
60 else setHeading(voting_text_first_preference_multi);
61 } else if (approvalIndex == 1) {
62 if (count == 1) setHeading(voting_text_second_preference_single);
63 else setHeading(voting_text_second_preference_multi);
64 } else if (approvalIndex == 2) {
65 if (count == 1) setHeading(voting_text_third_preference_single);
66 else setHeading(voting_text_third_preference_multi);
67 } else {
68 var text;
69 if (count == 1) text = voting_text_numeric_preference_single;
70 else text = voting_text_numeric_preference_multi;
71 text = text.replace(/#/, "" + (approvalIndex + 1))
72 setHeading(text);
73 }
74 } else {
75 if (count == 1) setHeading(voting_text_approval_single);
76 else setHeading(voting_text_approval_multi);
77 }
78 approvalIndex++;
79 } else if (section.className == "abstention") {
80 if (count == 1) setHeading(voting_text_abstention_single);
81 else setHeading(voting_text_abstention_multi);
82 } else if (section.className == "disapproval") {
83 if (disapprovalCount > disapprovalIndex + 2) {
84 if (count == 1) setHeading(voting_text_disapproval_above_many_single);
85 else setHeading(voting_text_disapproval_above_many_multi);
86 } else if (disapprovalCount == 2 && disapprovalIndex == 0) {
87 if (count == 1) setHeading(voting_text_disapproval_above_one_single);
88 else setHeading(voting_text_disapproval_above_one_multi);
89 } else if (disapprovalIndex == disapprovalCount - 2) {
90 if (count == 1) setHeading(voting_text_disapproval_above_last_single);
91 else setHeading(voting_text_disapproval_above_last_multi);
92 } else {
93 if (count == 1) setHeading(voting_text_disapproval_single);
94 else setHeading(voting_text_disapproval_multi);
95 }
96 disapprovalIndex++;
97 }
98 }
99 }
100 }
101 function voting_move(element, up, dropX, dropY) {
102 jsProtect(function() {
103 if (typeof(element) == "string") element = document.getElementById(element);
104 var mouse = (up == null);
105 var oldParent = element.parentNode;
106 if (mouse) var centerY = dropY + element.clientHeight / 2;
107 var approvalCount = 0;
108 var disapprovalCount = 0;
109 var mainDiv = document.getElementById("voting");
110 var sections = mainDiv.childNodes;
111 for (var i=0; i<sections.length; i++) {
112 var section = sections[i];
113 if (section.className == "approval") approvalCount++;
114 if (section.className == "disapproval") disapprovalCount++;
115 }
116 if (mouse) {
117 for (var i=0; i<sections.length; i++) {
118 var section = sections[i];
119 if (
120 section.className == "approval" ||
121 section.className == "abstention" ||
122 section.className == "disapproval"
123 ) {
124 if (
125 centerY >= section.offsetTop &&
126 centerY < section.offsetTop + section.clientHeight
127 ) {
128 var entries = section.childNodes;
129 for (var j=0; j<entries.length; j++) {
130 var entry = entries[j];
131 if (entry.className == "movable") {
132 if (centerY < entry.offsetTop + entry.clientHeight / 2) {
133 if (element != entry) {
134 oldParent.removeChild(element);
135 section.insertBefore(element, entry);
136 }
137 break;
138 }
139 }
140 }
141 if (j == entries.length) {
142 oldParent.removeChild(element);
143 section.appendChild(element);
144 }
145 break;
146 }
147 }
148 }
149 if (i == sections.length) {
150 var newSection = document.createElement("div");
151 var cathead = document.createElement("div");
152 cathead.setAttribute("class", "cathead");
153 newSection.appendChild(cathead);
154 for (var i=0; i<sections.length; i++) {
155 var section = sections[i];
156 if (
157 section.className == "approval" ||
158 section.className == "abstention" ||
159 section.className == "disapproval"
160 ) {
161 if (centerY < section.offsetTop + section.clientHeight / 2) {
162 if (section.className == "disapproval") {
163 newSection.setAttribute("class", "disapproval");
164 disapprovalCount++;
165 } else {
166 newSection.setAttribute("class", "approval");
167 approvalCount++;
168 }
169 mainDiv.insertBefore(newSection, section);
170 break;
171 }
172 }
173 }
174 if (i == sections.length) {
175 newSection.setAttribute("class", "disapproval");
176 disapprovalCount++;
177 mainDiv.appendChild(newSection);
178 }
179 oldParent.removeChild(element);
180 newSection.appendChild(element);
181 }
182 } else {
183 var oldFound = false;
184 var prevSection = null;
185 var nextSection = null;
186 for (var i=0; i<sections.length; i++) {
187 var section = sections[i];
188 if (
189 section.className == "approval" ||
190 section.className == "abstention" ||
191 section.className == "disapproval"
192 ) {
193 if (oldFound) {
194 nextSection = section;
195 break;
196 } else if (section == oldParent) {
197 oldFound = true;
198 } else {
199 prevSection = section;
200 }
201 }
202 }
203 var create;
204 if (oldParent.className == "abstention") {
205 create = true;
206 } else {
207 create = false;
208 for (var i=0; i<oldParent.childNodes.length; i++) {
209 var entry = oldParent.childNodes[i];
210 if (entry.className == "movable") {
211 if (entry != element) {
212 create = true;
213 break;
214 }
215 }
216 }
217 }
218 var newSection;
219 if (create) {
220 newSection = document.createElement("div");
221 var cathead = document.createElement("div");
222 cathead.setAttribute("class", "cathead");
223 newSection.appendChild(cathead);
224 if (
225 oldParent.className == "approval" ||
226 (oldParent.className == "abstention" && up)
227 ) {
228 newSection.setAttribute("class", "approval");
229 approvalCount++;
230 } else {
231 newSection.setAttribute("class", "disapproval");
232 disapprovalCount++;
233 }
234 if (up) {
235 mainDiv.insertBefore(newSection, oldParent);
236 } else {
237 if (nextSection) mainDiv.insertBefore(newSection, nextSection);
238 else mainDiv.appendChild(newSection);
239 }
240 } else {
241 if (up) newSection = prevSection;
242 else newSection = nextSection;
243 }
244 if (newSection) {
245 oldParent.removeChild(element);
246 if (create || up) {
247 newSection.appendChild(element);
248 } else {
249 var inserted = false;
250 for (var i=0; i<newSection.childNodes.length; i++) {
251 var entry = newSection.childNodes[i];
252 if (entry.className == "movable") {
253 newSection.insertBefore(element, entry);
254 inserted = true;
255 break;
256 }
257 }
258 if (!inserted) newSection.appendChild(element);
259 }
260 }
261 }
262 // sections = mainDiv.childNodes;
263 for (i=0; i<sections.length; i++) {
264 var section = sections[i];
265 if (
266 (section.className == "approval" && approvalCount > 1) ||
267 (section.className == "disapproval" && disapprovalCount > 1)
268 ) {
269 var entries = section.childNodes;
270 for (var j=0; j<entries.length; j++) {
271 var entry = entries[j];
272 if (entry.className == "movable") break;
273 }
274 if (j == entries.length) {
275 section.parentNode.removeChild(section);
276 }
277 }
278 }
279 voting_setCategoryHeadings();
280 });
281 }
282 function elementDropped(element, dropX, dropY) {
283 voting_move(element, null, dropX, dropY);
284 }
285 window.addEventListener("load", function(event) {
286 jsProtect(function() {
287 var jsTest = true;
288 var jsTestSuccess = false;
289 voting_setCategoryHeadings();
290 var mainDiv = document.getElementById("voting");
291 var form = document.getElementById("voting_form");
292 var elements = document.getElementsByTagName("input");
293 for (var i=0; i<elements.length; i++) {
294 var element = elements[i];
295 if (element.className == "voting_done1" ||
296 element.className == "voting_done2" ||
297 element.name == "preview") {
298 element.addEventListener("click", function(event) {
299 jsProtect(function() {
300 event.preventDefault();
301 if (event.target.name == "preview") {
302 document.getElementById("preview2").value = "1";
303 }
304 var scoringString = "";
305 var approvalCount = 0;
306 var disapprovalCount = 0;
307 var sections = mainDiv.childNodes;
308 for (var j=0; j<sections.length; j++) {
309 var section = sections[j];
310 if (section.className == "approval") approvalCount++;
311 if (section.className == "disapproval") disapprovalCount++;
312 }
313 var approvalIndex = 0;
314 var disapprovalIndex = 0;
315 for (var j=0; j<sections.length; j++) {
316 var section = sections[j];
317 if (
318 section.className == "approval" ||
319 section.className == "abstention" ||
320 section.className == "disapproval"
321 ) {
322 var score;
323 if (section.className == "approval") {
324 score = approvalCount - approvalIndex;
325 approvalIndex++;
326 } else if (section.className == "abstention") {
327 score = 0;
328 } else if (section.className == "disapproval") {
329 score = -1 - disapprovalIndex;
330 disapprovalIndex++;
331 }
332 var entries = section.childNodes;
333 for (var k=0; k<entries.length; k++) {
334 var entry = entries[k];
335 if (entry.className == "movable") {
336 var id = entry.id.match(/[0-9]+/);
337 var field = document.createElement("input");
338 scoringString += id + ":" + score + ";";
339 }
340 }
341 }
342 }
343 var fields = form.childNodes;
344 for (var j=0; j<fields.length; j++) {
345 var field = fields[j];
346 if (field.name == "scoring") {
347 field.setAttribute("value", scoringString);
348 if (jsTest) {
349 jsTestSuccess = success;
350 return;
351 } else {
352 form.submit();
353 return;
354 }
355 }
356 }
357 alert('Hidden input field named "scoring" not found.');
358 });
359 }, false);
360 }
361 }
362 for (var i=0; i<elements.length; i++) {
363 var element = elements[i];
364 if (element.className == "voting_done1") {
365 element.click();
366 }
367 }
368 jsTest = false;
369 if (!jsTestSuccess) jsFail = true;
370 });
371 }, false);
372 function voting_moveUp(element) {
373 return voting_move(element, true);
374 }
375 function voting_moveDown(element) {
376 return voting_move(element, false);
377 }
378 });

Impressum / About Us