liquid_feedback_frontend

diff static/js/voting.js @ 19:00d1004545f1

Dynamic interface using XMLHttpRequests, and many other changes

Bugfixes:
- Only allow voting on admitted initiatives
- Repaired issue search
- Don't display delegations for closed issues on member page
- Don't show revoke link in initiative, when issue is already half_frozen
- Localization for voting JavaScript
- Display author of suggestions

Disclosure of voting data after voting is finished:
- Possibility to inspect every ballot including preferences
- Show number of voters preferring one initiative to another initiative

Interface behaviour changes:
- Reversed default order of drafts
- Default order of suggestions changed
- Show new drafts of initiatives only once per day in timeline

Accessibility:
- Barrier-free voting implemented
- POST links are now accessible without JavaScript
- Changed gray for unsatisfied supporters in bar graph to a lighter gray

Other interface improvements:
- Optical enhancements
- Dynamic interface using XMLHttpRequests
- Show usage terms in about section
- Show own membership in area listing
- Show uninformed supporters greyed out and marked with yellow question mark
- Warning box in non-admitted initiatives
- When voted, don't display voting notice and change label of voting link
- Show object counts in more tabulator heads
- Enlarged member statement input field

Miscellaneous:
- Code cleanup
- Added README file containing installation instructions
- Use new WebMCP function ui.filters{...} instead of own ui.filter and ui.order functions
author bsw/jbe
date Sat Feb 20 22:10:31 2010 +0100 (2010-02-20)
parents afd9f769c7ae
children 7492497005bd
line diff
     1.1 --- a/static/js/voting.js	Tue Feb 02 00:31:06 2010 +0100
     1.2 +++ b/static/js/voting.js	Sat Feb 20 22:10:31 2010 +0100
     1.3 @@ -1,4 +1,25 @@
     1.4 -function setCategoryHeadings() {
     1.5 +voting_text_approval_single               = "Approval"
     1.6 +voting_text_approval_multi                = "Approval"
     1.7 +voting_text_first_preference_single       = "Approval (first preference)"
     1.8 +voting_text_first_preference_multi        = "Approval (first preference)"
     1.9 +voting_text_second_preference_single      = "Approval (second preference)"
    1.10 +voting_text_second_preference_multi       = "Approval (second preference)"
    1.11 +voting_text_third_preference_single       = "Approval (third preference)"
    1.12 +voting_text_third_preference_multi        = "Approval (third preference)"
    1.13 +voting_text_numeric_preference_single     = "Approval (#th preference)"
    1.14 +voting_text_numeric_preference_multi      = "Approval (#th preference)"
    1.15 +voting_text_abstention_single             = "Abstention"
    1.16 +voting_text_abstention_multi              = "Abstention"
    1.17 +voting_text_disapproval_above_one_single  = "Disapproval (prefer to lower block)"
    1.18 +voting_text_disapproval_above_one_multi   = "Disapproval (prefer to lower block)"
    1.19 +voting_text_disapproval_above_many_single = "Disapproval (prefer to lower blocks)"
    1.20 +voting_text_disapproval_above_many_multi  = "Disapproval (prefer to lower blocks)"
    1.21 +voting_text_disapproval_above_last_single = "Disapproval (prefer to last block)"
    1.22 +voting_text_disapproval_above_last_multi  = "Disapproval (prefer to last block)"
    1.23 +voting_text_disapproval_single            = "Disapproval"
    1.24 +voting_text_disapproval_multi             = "Disapproval"
    1.25 +
    1.26 +function voting_setCategoryHeadings() {
    1.27    var approvalCount = 0;
    1.28    var disapprovalCount = 0;
    1.29    var sections = document.getElementById("voting").childNodes;
    1.30 @@ -34,42 +55,53 @@
    1.31        if (section.className == "approval") {
    1.32          if (approvalCount > 1) {
    1.33            if (approvalIndex == 0) {
    1.34 -            if (count == 1) setHeading("Zustimmung (Erstwunsch)");
    1.35 -            else setHeading("Zustimmung (Erstwünsche)");
    1.36 +            if (count == 1) setHeading(voting_text_first_preference_single);
    1.37 +            else setHeading(voting_text_first_preference_multi);
    1.38            } else if (approvalIndex == 1) {
    1.39 -            if (count == 1) setHeading("Zustimmung (Zweitwunsch)");
    1.40 -            else setHeading("Zustimmung (Zweitwünsche)");
    1.41 +            if (count == 1) setHeading(voting_text_second_preference_single);
    1.42 +            else setHeading(voting_text_second_preference_multi);
    1.43            } else if (approvalIndex == 2) {
    1.44 -            if (count == 1) setHeading("Zustimmung (Drittwunsch)");
    1.45 -            else setHeading("Zustimmung (Drittwünsche)");
    1.46 +            if (count == 1) setHeading(voting_text_third_preference_single);
    1.47 +            else setHeading(voting_text_third_preference_multi);
    1.48            } else {
    1.49 -            if (count == 1) setHeading("Zustimmung (" + (approvalIndex+1) + ".-Wunsch)");
    1.50 -            else setHeading("Zustimmung (" + (approvalIndex+1) + ".-Wünsche)");
    1.51 +            var text;
    1.52 +            if (count == 1) text = voting_text_numeric_preference_single;
    1.53 +            else text = voting_text_numeric_preference_multi;
    1.54 +            text = text.replace(/#/, "" + (approvalIndex + 1))
    1.55 +            setHeading(text);
    1.56            }
    1.57          } else {
    1.58 -          setHeading("Zustimmung");
    1.59 +          if (count == 1) setHeading(voting_text_approval_single);
    1.60 +          else setHeading(voting_text_approval_multi);
    1.61          }
    1.62          approvalIndex++;
    1.63        } else if (section.className == "abstention") {
    1.64 -        setHeading("Enthaltung");
    1.65 +        if (count == 1) setHeading(voting_text_abstention_single);
    1.66 +        else setHeading(voting_text_abstention_multi);
    1.67        } else if (section.className == "disapproval") {
    1.68          if (disapprovalCount > disapprovalIndex + 2) {
    1.69 -          setHeading("Ablehnung (jedoch Bevorzugung gegenüber unteren Ablehnungsblöcken)")
    1.70 +          if (count == 1) setHeading(voting_text_disapproval_above_many_single);
    1.71 +          else setHeading(voting_text_disapproval_above_many_multi);
    1.72          } else if (disapprovalCount == 2 && disapprovalIndex == 0) {
    1.73 -          setHeading("Ablehnung (jedoch Bevorzugung gegenüber unterem Ablehnungsblock)")
    1.74 +          if (count == 1) setHeading(voting_text_disapproval_above_one_single);
    1.75 +          else setHeading(voting_text_disapproval_above_one_multi);
    1.76          } else if (disapprovalIndex == disapprovalCount - 2) {
    1.77 -          setHeading("Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)")
    1.78 +          if (count == 1) setHeading(voting_text_disapproval_above_last_single);
    1.79 +          else setHeading(voting_text_disapproval_above_last_multi);
    1.80          } else {
    1.81 -          setHeading("Ablehnung");
    1.82 +          if (count == 1) setHeading(voting_text_disapproval_single);
    1.83 +          else setHeading(voting_text_disapproval_multi);
    1.84          }
    1.85          disapprovalIndex++;
    1.86        }
    1.87      }
    1.88    }
    1.89  }
    1.90 -function elementDropped(element, dropX, dropY) {
    1.91 +function voting_move(element, up, dropX, dropY) {
    1.92 +  if (typeof(element) == "string") element = document.getElementById(element);
    1.93 +  var mouse = (up == null);
    1.94    var oldParent = element.parentNode;
    1.95 -  var centerY = dropY + element.clientHeight / 2
    1.96 +  if (mouse) var centerY = dropY + element.clientHeight / 2;
    1.97    var approvalCount = 0;
    1.98    var disapprovalCount = 0;
    1.99    var mainDiv = document.getElementById("voting");
   1.100 @@ -79,43 +111,7 @@
   1.101      if (section.className == "approval")       approvalCount++;
   1.102      if (section.className == "disapproval") disapprovalCount++;
   1.103    }
   1.104 -  for (var i=0; i<sections.length; i++) {
   1.105 -    var section = sections[i];
   1.106 -    if (
   1.107 -      section.className == "approval" ||
   1.108 -      section.className == "abstention" ||
   1.109 -      section.className == "disapproval"
   1.110 -    ) {
   1.111 -      if (
   1.112 -        centerY >= section.offsetTop &&
   1.113 -        centerY <  section.offsetTop + section.clientHeight
   1.114 -      ) {
   1.115 -        var entries = section.childNodes;
   1.116 -        for (var j=0; j<entries.length; j++) {
   1.117 -          var entry = entries[j];
   1.118 -          if (entry.className == "movable") {
   1.119 -            if (centerY < entry.offsetTop + entry.clientHeight / 2) {
   1.120 -              if (element != entry) {
   1.121 -                oldParent.removeChild(element);
   1.122 -                section.insertBefore(element, entry);
   1.123 -              }
   1.124 -              break;
   1.125 -            }
   1.126 -          }
   1.127 -        }
   1.128 -        if (j == entries.length) {
   1.129 -          oldParent.removeChild(element);
   1.130 -          section.appendChild(element);
   1.131 -        }
   1.132 -        break;
   1.133 -      }
   1.134 -    }
   1.135 -  }
   1.136 -  if (i == sections.length) {
   1.137 -    var newSection = document.createElement("div");
   1.138 -    var cathead = document.createElement("div");
   1.139 -    cathead.setAttribute("class", "cathead");
   1.140 -    newSection.appendChild(cathead);
   1.141 +  if (mouse) {
   1.142      for (var i=0; i<sections.length; i++) {
   1.143        var section = sections[i];
   1.144        if (
   1.145 @@ -123,28 +119,145 @@
   1.146          section.className == "abstention" ||
   1.147          section.className == "disapproval"
   1.148        ) {
   1.149 -        if (centerY < section.offsetTop + section.clientHeight / 2) {
   1.150 -          if (section.className == "disapproval") {
   1.151 -            newSection.setAttribute("class", "disapproval");
   1.152 -            disapprovalCount++;
   1.153 -          } else {
   1.154 -            newSection.setAttribute("class", "approval");
   1.155 -            approvalCount++;
   1.156 +        if (
   1.157 +          centerY >= section.offsetTop &&
   1.158 +          centerY <  section.offsetTop + section.clientHeight
   1.159 +        ) {
   1.160 +          var entries = section.childNodes;
   1.161 +          for (var j=0; j<entries.length; j++) {
   1.162 +            var entry = entries[j];
   1.163 +            if (entry.className == "movable") {
   1.164 +              if (centerY < entry.offsetTop + entry.clientHeight / 2) {
   1.165 +                if (element != entry) {
   1.166 +                  oldParent.removeChild(element);
   1.167 +                  section.insertBefore(element, entry);
   1.168 +                }
   1.169 +                break;
   1.170 +              }
   1.171 +            }
   1.172            }
   1.173 -          mainDiv.insertBefore(newSection, section);
   1.174 +          if (j == entries.length) {
   1.175 +            oldParent.removeChild(element);
   1.176 +            section.appendChild(element);
   1.177 +          }
   1.178            break;
   1.179          }
   1.180        }
   1.181      }
   1.182      if (i == sections.length) {
   1.183 -      newSection.setAttribute("class", "disapproval");
   1.184 -      disapprovalCount++;
   1.185 -      mainDiv.appendChild(newSection);
   1.186 +      var newSection = document.createElement("div");
   1.187 +      var cathead = document.createElement("div");
   1.188 +      cathead.setAttribute("class", "cathead");
   1.189 +      newSection.appendChild(cathead);
   1.190 +      for (var i=0; i<sections.length; i++) {
   1.191 +        var section = sections[i];
   1.192 +        if (
   1.193 +          section.className == "approval" ||
   1.194 +          section.className == "abstention" ||
   1.195 +          section.className == "disapproval"
   1.196 +        ) {
   1.197 +          if (centerY < section.offsetTop + section.clientHeight / 2) {
   1.198 +            if (section.className == "disapproval") {
   1.199 +              newSection.setAttribute("class", "disapproval");
   1.200 +              disapprovalCount++;
   1.201 +            } else {
   1.202 +              newSection.setAttribute("class", "approval");
   1.203 +              approvalCount++;
   1.204 +            }
   1.205 +            mainDiv.insertBefore(newSection, section);
   1.206 +            break;
   1.207 +          }
   1.208 +        }
   1.209 +      }
   1.210 +      if (i == sections.length) {
   1.211 +        newSection.setAttribute("class", "disapproval");
   1.212 +        disapprovalCount++;
   1.213 +        mainDiv.appendChild(newSection);
   1.214 +      }
   1.215 +      oldParent.removeChild(element);
   1.216 +      newSection.appendChild(element);
   1.217 +    }
   1.218 +  } else {
   1.219 +    var oldFound = false;
   1.220 +    var prevSection = null;
   1.221 +    var nextSection = null;
   1.222 +    for (var i=0; i<sections.length; i++) {
   1.223 +      var section = sections[i];
   1.224 +      if (
   1.225 +        section.className == "approval" ||
   1.226 +        section.className == "abstention" ||
   1.227 +        section.className == "disapproval"
   1.228 +      ) {
   1.229 +        if (oldFound) {
   1.230 +          nextSection = section;
   1.231 +          break;
   1.232 +        } else if (section == oldParent) {
   1.233 +          oldFound = true;
   1.234 +        } else {
   1.235 +          prevSection = section;
   1.236 +        }
   1.237 +      }
   1.238      }
   1.239 -    oldParent.removeChild(element);
   1.240 -    newSection.appendChild(element);
   1.241 +    var create;
   1.242 +    if (oldParent.className == "abstention") {
   1.243 +      create = true;
   1.244 +    } else {
   1.245 +      create = false;
   1.246 +      for (var i=0; i<oldParent.childNodes.length; i++) {
   1.247 +        var entry = oldParent.childNodes[i];
   1.248 +        if (entry.className == "movable") {
   1.249 +          if (entry != element) {
   1.250 +            create = true;
   1.251 +            break;
   1.252 +          }
   1.253 +        }
   1.254 +      }
   1.255 +    }
   1.256 +    var newSection;
   1.257 +    if (create) {
   1.258 +      newSection = document.createElement("div");
   1.259 +      var cathead = document.createElement("div");
   1.260 +      cathead.setAttribute("class", "cathead");
   1.261 +      newSection.appendChild(cathead);
   1.262 +      if (
   1.263 +        oldParent.className == "approval" ||
   1.264 +        (oldParent.className == "abstention" && up)
   1.265 +      ) {
   1.266 +        newSection.setAttribute("class", "approval");
   1.267 +        approvalCount++;
   1.268 +      } else {
   1.269 +        newSection.setAttribute("class", "disapproval");
   1.270 +        disapprovalCount++;
   1.271 +      }
   1.272 +      if (up) {
   1.273 +        mainDiv.insertBefore(newSection, oldParent);
   1.274 +      } else {
   1.275 +        if (nextSection) mainDiv.insertBefore(newSection, nextSection);
   1.276 +        else mainDiv.appendChild(newSection);
   1.277 +      }
   1.278 +    } else {
   1.279 +      if (up) newSection = prevSection;
   1.280 +      else newSection = nextSection;
   1.281 +    }
   1.282 +    if (newSection) {
   1.283 +      oldParent.removeChild(element);
   1.284 +      if (create || up) {
   1.285 +        newSection.appendChild(element);
   1.286 +      } else {
   1.287 +        var inserted = false;
   1.288 +        for (var i=0; i<newSection.childNodes.length; i++) {
   1.289 +          var entry = newSection.childNodes[i];
   1.290 +          if (entry.className == "movable") {
   1.291 +            newSection.insertBefore(element, entry);
   1.292 +            inserted = true;
   1.293 +            break;
   1.294 +          }
   1.295 +        }
   1.296 +        if (!inserted) newSection.appendChild(element);
   1.297 +      }
   1.298 +    }
   1.299    }
   1.300 -  sections = mainDiv.childNodes;
   1.301 +  // sections = mainDiv.childNodes;
   1.302    for (i=0; i<sections.length; i++) {
   1.303      var section = sections[i];
   1.304      if (
   1.305 @@ -161,10 +274,13 @@
   1.306        }
   1.307      }
   1.308    }
   1.309 -  setCategoryHeadings();
   1.310 +  voting_setCategoryHeadings();
   1.311 +}
   1.312 +function elementDropped(element, dropX, dropY) {
   1.313 +  voting_move(element, null, dropX, dropY);
   1.314  }
   1.315  window.addEventListener("load", function(event) {
   1.316 -  setCategoryHeadings();
   1.317 +  voting_setCategoryHeadings();
   1.318    var mainDiv = document.getElementById("voting");
   1.319    var form = document.getElementById("voting_form");
   1.320    var elements = document.getElementsByTagName("input");
   1.321 @@ -225,3 +341,9 @@
   1.322      }
   1.323    }
   1.324  }, false);
   1.325 +function voting_moveUp(element) {
   1.326 +  return voting_move(element, true);
   1.327 +}
   1.328 +function voting_moveDown(element) {
   1.329 +  return voting_move(element, false);
   1.330 +}

Impressum / About Us