liquid_feedback_frontend

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

Impressum / About Us