liquid_feedback_frontend
annotate static/js/partialload.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
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 | |
children |
rev | line source |
---|---|
bsw/jbe@19 | 1 |
bsw/jbe@19 | 2 partialload_queue = []; |
bsw/jbe@19 | 3 partialload_queueRPos = 0; |
bsw/jbe@19 | 4 partialload_queueWPos = 0; |
bsw/jbe@19 | 5 |
bsw/jbe@19 | 6 function partialload_getFormKeyValuePairs(form) { |
bsw/jbe@19 | 7 var result = {}; |
bsw/jbe@19 | 8 for (var i=0; i<form.elements.length; i++) { |
bsw/jbe@19 | 9 var inputElement = form.elements[i]; |
bsw/jbe@19 | 10 var key = inputElement.name; |
bsw/jbe@19 | 11 var value = inputElement.value; |
bsw/jbe@19 | 12 if (result[key] == null) result[key] = value; |
bsw/jbe@19 | 13 else if (typeof(result[key]) == "object") { |
bsw/jbe@19 | 14 result[key][result[key].length] = value; |
bsw/jbe@19 | 15 } else { |
bsw/jbe@19 | 16 result[key] = [result[key], value]; |
bsw/jbe@19 | 17 } |
bsw/jbe@19 | 18 } |
bsw/jbe@19 | 19 return result; |
bsw/jbe@19 | 20 } |
bsw/jbe@19 | 21 |
bsw/jbe@19 | 22 function partialload_encodeFormData(params) { |
bsw/jbe@19 | 23 var result = ""; |
bsw/jbe@19 | 24 for (var key in params) { |
bsw/jbe@19 | 25 var value = params[key]; |
bsw/jbe@19 | 26 if (typeof(value) == "string") { |
bsw/jbe@19 | 27 if (result != "") result += "&"; |
bsw/jbe@19 | 28 result += encodeURIComponent(key) + "=" + encodeURIComponent(value); |
bsw/jbe@19 | 29 } else if (typeof(value) == "object") { |
bsw/jbe@19 | 30 var i; |
bsw/jbe@19 | 31 for (i=0; i<value.length; i++) { |
bsw/jbe@19 | 32 if (result != "") result += "&"; |
bsw/jbe@19 | 33 result += encodeURIComponent(key) + "=" + encodeURIComponent(value[i]); |
bsw/jbe@19 | 34 } |
bsw/jbe@19 | 35 } |
bsw/jbe@19 | 36 } |
bsw/jbe@19 | 37 return result; |
bsw/jbe@19 | 38 } |
bsw/jbe@19 | 39 |
bsw/jbe@19 | 40 function partialload_addFormDataToUrl(url, params) { |
bsw/jbe@19 | 41 if (params != null && typeof(params) != "string") { |
bsw/jbe@19 | 42 params = partialload_encodeFormData(params); |
bsw/jbe@19 | 43 } |
bsw/jbe@19 | 44 if (params != null) { |
bsw/jbe@19 | 45 if (url.search(/\?/) >= 0) { |
bsw/jbe@19 | 46 if (url.search(/&$/) >= 0) { |
bsw/jbe@19 | 47 url = url + params; |
bsw/jbe@19 | 48 } else { |
bsw/jbe@19 | 49 url = url + "&" + params; |
bsw/jbe@19 | 50 } |
bsw/jbe@19 | 51 } else { |
bsw/jbe@19 | 52 url = url + "?" + params; |
bsw/jbe@19 | 53 } |
bsw/jbe@19 | 54 } |
bsw/jbe@19 | 55 return url; |
bsw/jbe@19 | 56 } |
bsw/jbe@19 | 57 |
bsw/jbe@19 | 58 function partialload_mergeEncodedFormData(data1, data2) { |
bsw/jbe@19 | 59 if (data2 == null || data2 == "") return data1; |
bsw/jbe@19 | 60 if (data1 == null || data1 == "") return data2; |
bsw/jbe@19 | 61 return data1 + "&" + data2; |
bsw/jbe@19 | 62 } |
bsw/jbe@19 | 63 |
bsw/jbe@19 | 64 function partialload_startNextRequest() { |
bsw/jbe@19 | 65 var entry = partialload_queue[partialload_queueRPos++]; |
bsw/jbe@19 | 66 var req = new XMLHttpRequest(); |
bsw/jbe@19 | 67 req.open(entry.method, entry.url, true); |
bsw/jbe@19 | 68 req.onreadystatechange = function() { |
bsw/jbe@19 | 69 if (req.readyState == 4) { |
bsw/jbe@19 | 70 if (req.status == 200) { |
bsw/jbe@19 | 71 if (entry.successHandler != null) entry.successHandler(req.responseText); |
bsw/jbe@19 | 72 } else { |
bsw/jbe@19 | 73 if (entry.failureHandler != null) entry.failureHandler(); |
bsw/jbe@19 | 74 } |
bsw/jbe@19 | 75 if (partialload_queue[partialload_queueRPos]) { |
bsw/jbe@19 | 76 partialload_startNextRequest(); |
bsw/jbe@19 | 77 } else { |
bsw/jbe@19 | 78 partialload_queue = []; |
bsw/jbe@19 | 79 partialload_queueRPos = 0; |
bsw/jbe@19 | 80 partialload_queueWPos = 0; |
bsw/jbe@19 | 81 } |
bsw/jbe@19 | 82 } |
bsw/jbe@19 | 83 } |
bsw/jbe@19 | 84 if (entry.data) { |
bsw/jbe@19 | 85 req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); |
bsw/jbe@19 | 86 } |
bsw/jbe@19 | 87 req.send(entry.data); |
bsw/jbe@19 | 88 } |
bsw/jbe@19 | 89 |
bsw/jbe@19 | 90 function queuedHttpRequest( |
bsw/jbe@19 | 91 url_or_form, |
bsw/jbe@19 | 92 urlParams, |
bsw/jbe@19 | 93 postParams, |
bsw/jbe@19 | 94 successHandler, |
bsw/jbe@19 | 95 failureHandler |
bsw/jbe@19 | 96 ) { |
bsw/jbe@19 | 97 var method; |
bsw/jbe@19 | 98 var data = null; |
bsw/jbe@19 | 99 if (typeof(postParams) == "string") { |
bsw/jbe@19 | 100 data = postParams; |
bsw/jbe@19 | 101 } else if (postParams != null) { |
bsw/jbe@19 | 102 data = partialload_encodeFormData(postParams); |
bsw/jbe@19 | 103 } |
bsw/jbe@19 | 104 var url; |
bsw/jbe@19 | 105 if (typeof(url_or_form) == "object") { |
bsw/jbe@19 | 106 // form element given |
bsw/jbe@19 | 107 var form = url_or_form; |
bsw/jbe@19 | 108 url = partialload_addFormDataToUrl(form.action, urlParams); |
bsw/jbe@19 | 109 var dataFromForm = partialload_encodeFormData( |
bsw/jbe@19 | 110 partialload_getFormKeyValuePairs(form) |
bsw/jbe@19 | 111 ); |
bsw/jbe@19 | 112 if (form.method != null && form.method.search(/^POST$/i) >= 0) { |
bsw/jbe@19 | 113 method = "POST"; |
bsw/jbe@19 | 114 data = partialload_mergeEncodedFormData(data, dataFromForm); |
bsw/jbe@19 | 115 } else { |
bsw/jbe@19 | 116 method = (postParams == NULL) ? "GET" : "POST"; |
bsw/jbe@19 | 117 url = partialload_addFormDataToUrl(url, dataFromForm); |
bsw/jbe@19 | 118 } |
bsw/jbe@19 | 119 } else { |
bsw/jbe@19 | 120 // URL given |
bsw/jbe@19 | 121 url = partialload_addFormDataToUrl(url_or_form, urlParams); |
bsw/jbe@19 | 122 if (postParams == null) { |
bsw/jbe@19 | 123 method = "GET"; |
bsw/jbe@19 | 124 } else { |
bsw/jbe@19 | 125 method = "POST"; |
bsw/jbe@19 | 126 if (typeof(postParams) == "string") { |
bsw/jbe@19 | 127 data = postParams; |
bsw/jbe@19 | 128 } else { |
bsw/jbe@19 | 129 data = partialload_encodeFormData(postParams); |
bsw/jbe@19 | 130 } |
bsw/jbe@19 | 131 } |
bsw/jbe@19 | 132 } |
bsw/jbe@19 | 133 partialload_queue[partialload_queueWPos++] = { |
bsw/jbe@19 | 134 method: method, |
bsw/jbe@19 | 135 url: url, |
bsw/jbe@19 | 136 data: data, |
bsw/jbe@19 | 137 successHandler: successHandler, |
bsw/jbe@19 | 138 failureHandler: failureHandler |
bsw/jbe@19 | 139 }; |
bsw/jbe@19 | 140 if (partialload_queueRPos == 0) { |
bsw/jbe@19 | 141 partialload_startNextRequest(); |
bsw/jbe@19 | 142 } |
bsw/jbe@19 | 143 } |
bsw/jbe@19 | 144 |
bsw/jbe@19 | 145 function setHtmlContent(node, htmlWithScripts) { |
bsw/jbe@19 | 146 var uniquePrefix = "placeholder" + Math.floor(Math.random()*10e16) + "_"; |
bsw/jbe@19 | 147 var i = 0; |
bsw/jbe@19 | 148 var scripts = []; |
bsw/jbe@19 | 149 var htmlWithPlaceholders = ""; |
bsw/jbe@19 | 150 // NOTE: This function can not handle CDATA blocks at random positions. |
bsw/jbe@19 | 151 htmlWithPlaceholders = htmlWithScripts.replace( |
bsw/jbe@19 | 152 /<script[^>]*>(.*?)<\/script>/ig, |
bsw/jbe@19 | 153 function(all, inside) { |
bsw/jbe@19 | 154 scripts[i] = inside; |
bsw/jbe@19 | 155 var placeholder = '<span id="' + uniquePrefix + i + '"></span>'; |
bsw/jbe@19 | 156 i++; |
bsw/jbe@19 | 157 return placeholder; |
bsw/jbe@19 | 158 } |
bsw/jbe@19 | 159 ) |
bsw/jbe@19 | 160 node.innerHTML = htmlWithPlaceholders; |
bsw/jbe@19 | 161 var documentWriteBackup = document.write; |
bsw/jbe@19 | 162 var documentWritelnBackup = document.writeln; |
bsw/jbe@19 | 163 var output; |
bsw/jbe@19 | 164 document.write = function(str) { output += str; } |
bsw/jbe@19 | 165 document.writeln = function(str) { output += str + "\n"; } |
bsw/jbe@19 | 166 for (i=0; i<scripts.length; i++) { |
bsw/jbe@19 | 167 var placeholderNode = document.getElementById(uniquePrefix + i); |
bsw/jbe@19 | 168 output = ""; |
bsw/jbe@19 | 169 eval(scripts[i]); |
bsw/jbe@19 | 170 if (output != "") { |
bsw/jbe@19 | 171 placeholderNode.innerHTML = output; |
bsw/jbe@19 | 172 while (placeholderNode.childNodes.length > 0) { |
bsw/jbe@19 | 173 var childNode = placeholderNode.childNodes[0]; |
bsw/jbe@19 | 174 placeholderNode.removeChild(childNode); |
bsw/jbe@19 | 175 placeholderNode.parentNode.insertBefore(childNode, placeholderNode); |
bsw/jbe@19 | 176 } |
bsw/jbe@19 | 177 } |
bsw/jbe@19 | 178 placeholderNode.parentNode.removeChild(placeholderNode); |
bsw/jbe@19 | 179 } |
bsw/jbe@19 | 180 document.write = documentWriteBackup; |
bsw/jbe@19 | 181 document.writeln = documentWritelnBackup; |
bsw/jbe@19 | 182 } |
bsw/jbe@19 | 183 |
bsw/jbe@19 | 184 function partialLoad( |
bsw/jbe@19 | 185 node, |
bsw/jbe@19 | 186 tempLoadingContent, |
bsw/jbe@19 | 187 failureContent, |
bsw/jbe@19 | 188 url_or_form, |
bsw/jbe@19 | 189 urlParams, |
bsw/jbe@19 | 190 postParams, |
bsw/jbe@19 | 191 successHandler, |
bsw/jbe@19 | 192 failureHandler |
bsw/jbe@19 | 193 ) { |
bsw/jbe@19 | 194 if (typeof(node) == "string") node = document.getElementById(node); |
bsw/jbe@19 | 195 if (tempLoadingContent != null) setHtmlContent(node, tempLoadingContent); |
bsw/jbe@19 | 196 queuedHttpRequest( |
bsw/jbe@19 | 197 url_or_form, |
bsw/jbe@19 | 198 urlParams, |
bsw/jbe@19 | 199 postParams, |
bsw/jbe@19 | 200 function(response) { |
bsw/jbe@19 | 201 setHtmlContent(node, response); |
bsw/jbe@19 | 202 if (successHandler != null) successHandler(); |
bsw/jbe@19 | 203 }, |
bsw/jbe@19 | 204 function() { |
bsw/jbe@19 | 205 if (failureContent != null) setHtmlContent(node, failureContent); |
bsw/jbe@19 | 206 if (failureHandler != null) failureHandler(); |
bsw/jbe@19 | 207 } |
bsw/jbe@19 | 208 ); |
bsw/jbe@19 | 209 } |
bsw/jbe@19 | 210 |
bsw/jbe@19 | 211 function partialMultiLoad( |
bsw/jbe@19 | 212 mapping, |
bsw/jbe@19 | 213 tempLoadingContents, |
bsw/jbe@19 | 214 failureContents, |
bsw/jbe@19 | 215 url_or_form, |
bsw/jbe@19 | 216 urlParams, |
bsw/jbe@19 | 217 postParams, |
bsw/jbe@19 | 218 successHandler, |
bsw/jbe@19 | 219 failureHandler |
bsw/jbe@19 | 220 ) { |
bsw/jbe@19 | 221 if (mapping instanceof Array) { |
bsw/jbe@19 | 222 var mappingHash = {} |
bsw/jbe@19 | 223 for (var i=0; i<mapping.length; i++) { |
bsw/jbe@19 | 224 mappingHash[mapping[i]] = mapping[i]; |
bsw/jbe@19 | 225 } |
bsw/jbe@19 | 226 mapping = mappingHash; |
bsw/jbe@19 | 227 } |
bsw/jbe@19 | 228 if (typeof(tempLoadingContents) == "string") { |
bsw/jbe@19 | 229 for (var key in mapping) { |
bsw/jbe@19 | 230 var node = key; |
bsw/jbe@19 | 231 if (typeof(node) == "string") node = document.getElementById(node); |
bsw/jbe@19 | 232 setHtmlContent(node, tempLoadingContents); |
bsw/jbe@19 | 233 } |
bsw/jbe@19 | 234 } else if (tempLoadingContents != null) { |
bsw/jbe@19 | 235 for (var key in tempLoadingContents) { |
bsw/jbe@19 | 236 var node = key; |
bsw/jbe@19 | 237 if (typeof(node) == "string") node = document.getElementById(node); |
bsw/jbe@19 | 238 setHtmlContent(node, tempLoadingContents[key]); |
bsw/jbe@19 | 239 } |
bsw/jbe@19 | 240 } |
bsw/jbe@19 | 241 queuedHttpRequest( |
bsw/jbe@19 | 242 url_or_form, |
bsw/jbe@19 | 243 urlParams, |
bsw/jbe@19 | 244 postParams, |
bsw/jbe@19 | 245 function(response) { |
bsw/jbe@19 | 246 var data = eval("(" + response + ")"); |
bsw/jbe@19 | 247 for (var key in mapping) { |
bsw/jbe@19 | 248 var node = key; |
bsw/jbe@19 | 249 if (typeof(node) == "string") node = document.getElementById(node); |
bsw/jbe@19 | 250 setHtmlContent(node, data[mapping[key]]); |
bsw/jbe@19 | 251 } |
bsw/jbe@19 | 252 if (successHandler != null) successHandler(); |
bsw/jbe@19 | 253 }, |
bsw/jbe@19 | 254 function() { |
bsw/jbe@19 | 255 if (typeof(failureContents) == "string") { |
bsw/jbe@19 | 256 for (var key in mapping) { |
bsw/jbe@19 | 257 var node = key; |
bsw/jbe@19 | 258 if (typeof(node) == "string") node = document.getElementById(node); |
bsw/jbe@19 | 259 setHtmlContent(node, failureContents); |
bsw/jbe@19 | 260 } |
bsw/jbe@19 | 261 } else if (failureContents != null) { |
bsw/jbe@19 | 262 for (var key in failureContents) { |
bsw/jbe@19 | 263 var node = key; |
bsw/jbe@19 | 264 if (typeof(node) == "string") node = document.getElementById(node); |
bsw/jbe@19 | 265 setHtmlContent(node, failureContents[key]); |
bsw/jbe@19 | 266 } |
bsw/jbe@19 | 267 } |
bsw/jbe@19 | 268 if (failureHandler != null) failureHandler(); |
bsw/jbe@19 | 269 } |
bsw/jbe@19 | 270 ); |
bsw/jbe@19 | 271 } |