liquid_feedback_frontend
annotate app/main/vote/list.lua @ 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 | 77d58efe99fd |
| children | 3036f2732b83 |
| rev | line source |
|---|---|
| bsw/jbe@19 | 1 local issue = Issue:by_id(param.get("issue_id"), atom.integer) |
| bsw/jbe@19 | 2 |
| bsw/jbe@19 | 3 local member_id = param.get("member_id", atom.integer) |
| bsw/jbe@19 | 4 local member |
| bsw/jbe@19 | 5 |
| bsw/jbe@19 | 6 local readonly = false |
| bsw/jbe@19 | 7 if member_id then |
| bsw/jbe@19 | 8 if not issue.closed then |
| bsw/jbe@19 | 9 error("access denied") |
| bsw/jbe@19 | 10 end |
| bsw/jbe@19 | 11 member = Member:by_id(member_id) |
| bsw/jbe@19 | 12 readonly = true |
| bsw/jbe@19 | 13 end |
| bsw/jbe@19 | 14 |
| bsw/jbe@19 | 15 if member then |
| bsw/jbe@19 | 16 slot.put_into("title", _("Ballot of '#{member_name}' for issue ##{issue_id}", { |
| bsw/jbe@19 | 17 member_name = member.name, |
| bsw/jbe@19 | 18 issue_id = issue.id |
| bsw/jbe@19 | 19 })) |
| bsw/jbe@19 | 20 else |
| bsw/jbe@19 | 21 member = app.session.member |
| bsw/jbe@19 | 22 slot.put_into("title", _"Voting") |
| bsw/jbe@19 | 23 |
| bsw/jbe@19 | 24 slot.select("actions", function() |
| bsw/jbe@19 | 25 ui.link{ |
| bsw/jbe@19 | 26 content = function() |
| bsw/jbe@19 | 27 ui.image{ static = "icons/16/cancel.png" } |
| bsw/jbe@19 | 28 slot.put(_"Cancel") |
| bsw/jbe@19 | 29 end, |
| bsw/jbe@19 | 30 module = "issue", |
| bsw/jbe@19 | 31 view = "show", |
| bsw/jbe@19 | 32 id = issue.id |
| bsw/jbe@19 | 33 } |
| bsw/jbe@19 | 34 end) |
| bsw/jbe@19 | 35 |
| bsw/jbe@19 | 36 end |
| bsw/jbe@19 | 37 |
| bsw/jbe@19 | 38 |
| bsw/jbe@5 | 39 local warning_text = _"Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon." |
| bsw/jbe@5 | 40 |
| bsw/jbe@5 | 41 ui.script{ static = "js/browser_warning.js" } |
| bsw/jbe@5 | 42 ui.script{ script = "checkBrowser(" .. encode.json(_"Your web browser is not fully supported yet." .. " " .. warning_text:gsub("\n", "\n\n")) .. ");" } |
| bsw/jbe@5 | 43 |
| bsw/jbe@19 | 44 |
| bsw/jbe@19 | 45 local tempvoting_string = param.get("scoring") |
| bsw/jbe@19 | 46 |
| bsw/jbe@19 | 47 local tempvotings = {} |
| bsw/jbe@19 | 48 if tempvoting_string then |
| bsw/jbe@19 | 49 for match in tempvoting_string:gmatch("([^;]+)") do |
| bsw/jbe@19 | 50 for initiative_id, grade in match:gmatch("([^:;]+):([^:;]+)") do |
| bsw/jbe@19 | 51 tempvotings[tonumber(initiative_id)] = tonumber(grade) |
| bsw/jbe@19 | 52 end |
| bsw/jbe@5 | 53 end |
| bsw/jbe@19 | 54 end |
| bsw/jbe@5 | 55 |
| bsw/jbe@19 | 56 local initiatives = issue:get_reference_selector("initiatives"):add_where("initiative.admitted"):exec() |
| bsw/jbe@5 | 57 |
| bsw/jbe@5 | 58 local min_grade = -1; |
| bsw/jbe@5 | 59 local max_grade = 1; |
| bsw/jbe@5 | 60 |
| bsw/jbe@5 | 61 for i, initiative in ipairs(initiatives) do |
| bsw/jbe@5 | 62 -- TODO performance |
| bsw/jbe@19 | 63 initiative.vote = Vote:by_pk(initiative.id, member.id) |
| bsw/jbe@19 | 64 if tempvotings[initiative.id] then |
| bsw/jbe@19 | 65 initiative.vote = {} |
| bsw/jbe@19 | 66 initiative.vote.grade = tempvotings[initiative.id] |
| bsw/jbe@19 | 67 end |
| bsw/jbe@5 | 68 if initiative.vote then |
| bsw/jbe@5 | 69 if initiative.vote.grade > max_grade then |
| bsw/jbe@5 | 70 max_grade = initiative.vote.grade |
| bsw/jbe@5 | 71 end |
| bsw/jbe@5 | 72 if initiative.vote.grade < min_grade then |
| bsw/jbe@5 | 73 min_grade = initiative.vote.grade |
| bsw/jbe@5 | 74 end |
| bsw/jbe@5 | 75 end |
| bsw/jbe@5 | 76 end |
| bsw/jbe@5 | 77 |
| bsw/jbe@5 | 78 local sections = {} |
| bsw/jbe@5 | 79 for i = min_grade, max_grade do |
| bsw/jbe@5 | 80 sections[i] = {} |
| bsw/jbe@5 | 81 for j, initiative in ipairs(initiatives) do |
| bsw/jbe@5 | 82 if (initiative.vote and initiative.vote.grade == i) or (not initiative.vote and i == 0) then |
| bsw/jbe@5 | 83 sections[i][#(sections[i])+1] = initiative |
| bsw/jbe@5 | 84 end |
| bsw/jbe@5 | 85 end |
| bsw/jbe@5 | 86 end |
| bsw/jbe@5 | 87 |
| bsw/jbe@19 | 88 local approval_count, disapproval_count = 0, 0 |
| bsw/jbe@19 | 89 for i = min_grade, -1 do |
| bsw/jbe@19 | 90 if #sections[i] > 0 then |
| bsw/jbe@19 | 91 disapproval_count = disapproval_count + 1 |
| bsw/jbe@19 | 92 end |
| bsw/jbe@19 | 93 end |
| bsw/jbe@19 | 94 local approval_count = 0 |
| bsw/jbe@19 | 95 for i = 1, max_grade do |
| bsw/jbe@19 | 96 if #sections[i] > 0 then |
| bsw/jbe@19 | 97 approval_count = approval_count + 1 |
| bsw/jbe@19 | 98 end |
| bsw/jbe@19 | 99 end |
| bsw/jbe@5 | 100 |
| bsw/jbe@5 | 101 |
| bsw/jbe@5 | 102 |
| bsw/jbe@19 | 103 if not readonly then |
| bsw/jbe@19 | 104 util.help("vote.list", _"Voting") |
| bsw/jbe@19 | 105 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>') |
| bsw/jbe@19 | 106 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>') |
| bsw/jbe@19 | 107 end |
| bsw/jbe@19 | 108 |
| bsw/jbe@19 | 109 ui.script{ |
| bsw/jbe@19 | 110 script = function() |
| bsw/jbe@19 | 111 slot.put( |
| bsw/jbe@19 | 112 "voting_text_approval_single = ", encode.json(_"Approval [single entry]"), ";\n", |
| bsw/jbe@19 | 113 "voting_text_approval_multi = ", encode.json(_"Approval [many entries]"), ";\n", |
| bsw/jbe@19 | 114 "voting_text_first_preference_single = ", encode.json(_"Approval (first preference) [single entry]"), ";\n", |
| bsw/jbe@19 | 115 "voting_text_first_preference_multi = ", encode.json(_"Approval (first preference) [many entries]"), ";\n", |
| bsw/jbe@19 | 116 "voting_text_second_preference_single = ", encode.json(_"Approval (second preference) [single entry]"), ";\n", |
| bsw/jbe@19 | 117 "voting_text_second_preference_multi = ", encode.json(_"Approval (second preference) [many entries]"), ";\n", |
| bsw/jbe@19 | 118 "voting_text_third_preference_single = ", encode.json(_"Approval (third preference) [single entry]"), ";\n", |
| bsw/jbe@19 | 119 "voting_text_third_preference_multi = ", encode.json(_"Approval (third preference) [many entries]"), ";\n", |
| bsw/jbe@19 | 120 "voting_text_numeric_preference_single = ", encode.json(_"Approval (#th preference) [single entry]"), ";\n", |
| bsw/jbe@19 | 121 "voting_text_numeric_preference_multi = ", encode.json(_"Approval (#th preference) [many entries]"), ";\n", |
| bsw/jbe@19 | 122 "voting_text_abstention_single = ", encode.json(_"Abstention [single entry]"), ";\n", |
| bsw/jbe@19 | 123 "voting_text_abstention_multi = ", encode.json(_"Abstention [many entries]"), ";\n", |
| bsw/jbe@19 | 124 "voting_text_disapproval_above_one_single = ", encode.json(_"Disapproval (prefer to lower block) [single entry]"), ";\n", |
| bsw/jbe@19 | 125 "voting_text_disapproval_above_one_multi = ", encode.json(_"Disapproval (prefer to lower block) [many entries]"), ";\n", |
| bsw/jbe@19 | 126 "voting_text_disapproval_above_many_single = ", encode.json(_"Disapproval (prefer to lower blocks) [single entry]"), ";\n", |
| bsw/jbe@19 | 127 "voting_text_disapproval_above_many_multi = ", encode.json(_"Disapproval (prefer to lower blocks) [many entries]"), ";\n", |
| bsw/jbe@19 | 128 "voting_text_disapproval_above_last_single = ", encode.json(_"Disapproval (prefer to last block) [single entry]"), ";\n", |
| bsw/jbe@19 | 129 "voting_text_disapproval_above_last_multi = ", encode.json(_"Disapproval (prefer to last block) [many entries]"), ";\n", |
| bsw/jbe@19 | 130 "voting_text_disapproval_single = ", encode.json(_"Disapproval [single entry]"), ";\n", |
| bsw/jbe@19 | 131 "voting_text_disapproval_multi = ", encode.json(_"Disapproval [many entries]"), ";\n" |
| bsw/jbe@19 | 132 ) |
| bsw/jbe@19 | 133 end |
| bsw/jbe@19 | 134 } |
| bsw/jbe@5 | 135 |
| bsw/jbe@5 | 136 ui.form{ |
| bsw/jbe@19 | 137 attr = { |
| bsw/jbe@19 | 138 id = "voting_form", |
| bsw/jbe@19 | 139 class = readonly and "voting_form_readonly" or "voting_form_active" |
| bsw/jbe@19 | 140 }, |
| bsw/jbe@5 | 141 module = "vote", |
| bsw/jbe@5 | 142 action = "update", |
| bsw/jbe@5 | 143 params = { issue_id = issue.id }, |
| bsw/jbe@5 | 144 routing = { |
| bsw/jbe@5 | 145 default = { |
| bsw/jbe@5 | 146 mode = "redirect", |
| bsw/jbe@5 | 147 module = "issue", |
| bsw/jbe@5 | 148 view = "show", |
| bsw/jbe@5 | 149 id = issue.id |
| bsw/jbe@5 | 150 } |
| bsw/jbe@5 | 151 }, |
| bsw/jbe@5 | 152 content = function() |
| bsw/jbe@19 | 153 if not readonly then |
| bsw/jbe@19 | 154 local scoring = param.get("scoring") |
| bsw/jbe@19 | 155 if not scoring then |
| bsw/jbe@19 | 156 for i, initiative in ipairs(initiatives) do |
| bsw/jbe@19 | 157 local vote = initiative.vote |
| bsw/jbe@19 | 158 if vote then |
| bsw/jbe@19 | 159 tempvotings[initiative.id] = vote.grade |
| bsw/jbe@19 | 160 end |
| bsw/jbe@19 | 161 end |
| bsw/jbe@19 | 162 local tempvotings_list = {} |
| bsw/jbe@19 | 163 for key, val in pairs(tempvotings) do |
| bsw/jbe@19 | 164 tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val) |
| bsw/jbe@19 | 165 end |
| bsw/jbe@19 | 166 if #tempvotings_list > 0 then |
| bsw/jbe@19 | 167 scoring = table.concat(tempvotings_list, ";") |
| bsw/jbe@19 | 168 else |
| bsw/jbe@19 | 169 scoring = "" |
| bsw/jbe@19 | 170 end |
| bsw/jbe@19 | 171 end |
| bsw/jbe@19 | 172 slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>') |
| bsw/jbe@19 | 173 -- TODO abstrahieren |
| bsw/jbe@19 | 174 ui.tag{ |
| bsw/jbe@19 | 175 tag = "input", |
| bsw/jbe@19 | 176 attr = { |
| bsw/jbe@19 | 177 type = "button", |
| bsw/jbe@19 | 178 class = "voting_done", |
| bsw/jbe@19 | 179 value = _"Finish voting" |
| bsw/jbe@19 | 180 } |
| bsw/jbe@5 | 181 } |
| bsw/jbe@19 | 182 end |
| bsw/jbe@5 | 183 ui.container{ |
| bsw/jbe@5 | 184 attr = { id = "voting" }, |
| bsw/jbe@5 | 185 content = function() |
| bsw/jbe@19 | 186 local approval_index, disapproval_index = 0, 0 |
| bsw/jbe@5 | 187 for grade = max_grade, min_grade, -1 do |
| bsw/jbe@19 | 188 local entries = sections[grade] |
| bsw/jbe@5 | 189 local class |
| bsw/jbe@5 | 190 if grade > 0 then |
| bsw/jbe@5 | 191 class = "approval" |
| bsw/jbe@5 | 192 elseif grade < 0 then |
| bsw/jbe@5 | 193 class = "disapproval" |
| bsw/jbe@5 | 194 else |
| bsw/jbe@5 | 195 class = "abstention" |
| bsw/jbe@5 | 196 end |
| bsw/jbe@19 | 197 if |
| bsw/jbe@19 | 198 #entries > 0 or |
| bsw/jbe@19 | 199 (grade == 1 and not approval_used) or |
| bsw/jbe@19 | 200 (grade == -1 and not disapproval_used) or |
| bsw/jbe@19 | 201 grade == 0 |
| bsw/jbe@19 | 202 then |
| bsw/jbe@19 | 203 ui.container{ |
| bsw/jbe@19 | 204 attr = { class = class }, |
| bsw/jbe@19 | 205 content = function() |
| bsw/jbe@19 | 206 local heading |
| bsw/jbe@19 | 207 if class == "approval" then |
| bsw/jbe@19 | 208 approval_used = true |
| bsw/jbe@19 | 209 approval_index = approval_index + 1 |
| bsw/jbe@19 | 210 if approval_count > 1 then |
| bsw/jbe@19 | 211 if approval_index == 1 then |
| bsw/jbe@19 | 212 if #entries == 1 then |
| bsw/jbe@19 | 213 heading = _"Approval (first preference) [single entry]" |
| bsw/jbe@19 | 214 else |
| bsw/jbe@19 | 215 heading = _"Approval (first preference) [many entries]" |
| bsw/jbe@19 | 216 end |
| bsw/jbe@19 | 217 elseif approval_index == 2 then |
| bsw/jbe@19 | 218 if #entries == 1 then |
| bsw/jbe@19 | 219 heading = _"Approval (second preference) [single entry]" |
| bsw/jbe@19 | 220 else |
| bsw/jbe@19 | 221 heading = _"Approval (second preference) [many entries]" |
| bsw/jbe@19 | 222 end |
| bsw/jbe@19 | 223 elseif approval_index == 3 then |
| bsw/jbe@19 | 224 if #entries == 1 then |
| bsw/jbe@19 | 225 heading = _"Approval (third preference) [single entry]" |
| bsw/jbe@19 | 226 else |
| bsw/jbe@19 | 227 heading = _"Approval (third preference) [many entries]" |
| bsw/jbe@19 | 228 end |
| bsw/jbe@19 | 229 else |
| bsw/jbe@19 | 230 if #entries == 1 then |
| bsw/jbe@19 | 231 heading = _"Approval (#th preference) [single entry]" |
| bsw/jbe@19 | 232 else |
| bsw/jbe@19 | 233 heading = _"Approval (#th preference) [many entries]" |
| bsw/jbe@19 | 234 end |
| bsw/jbe@19 | 235 end |
| bsw/jbe@19 | 236 else |
| bsw/jbe@19 | 237 if #entries == 1 then |
| bsw/jbe@19 | 238 heading = _"Approval [single entry]" |
| bsw/jbe@19 | 239 else |
| bsw/jbe@19 | 240 heading = _"Approval [many entries]" |
| bsw/jbe@19 | 241 end |
| bsw/jbe@19 | 242 end |
| bsw/jbe@19 | 243 elseif class == "abstention" then |
| bsw/jbe@19 | 244 if #entries == 1 then |
| bsw/jbe@19 | 245 heading = _"Abstention [single entry]" |
| bsw/jbe@19 | 246 else |
| bsw/jbe@19 | 247 heading = _"Abstention [many entries]" |
| bsw/jbe@19 | 248 end |
| bsw/jbe@19 | 249 elseif class == "disapproval" then |
| bsw/jbe@19 | 250 disapproval_used = true |
| bsw/jbe@19 | 251 disapproval_index = disapproval_index + 1 |
| bsw/jbe@19 | 252 if disapproval_count > disapproval_index + 1 then |
| bsw/jbe@19 | 253 if #entries == 1 then |
| bsw/jbe@19 | 254 heading = _"Disapproval (prefer to lower blocks) [single entry]" |
| bsw/jbe@19 | 255 else |
| bsw/jbe@19 | 256 heading = _"Disapproval (prefer to lower blocks) [many entries]" |
| bsw/jbe@19 | 257 end |
| bsw/jbe@19 | 258 elseif disapproval_count == 2 and disapproval_index == 1 then |
| bsw/jbe@19 | 259 if #entries == 1 then |
| bsw/jbe@19 | 260 heading = _"Disapproval (prefer to lower block) [single entry]" |
| bsw/jbe@19 | 261 else |
| bsw/jbe@19 | 262 heading = _"Disapproval (prefer to lower block) [many entries]" |
| bsw/jbe@19 | 263 end |
| bsw/jbe@19 | 264 elseif disapproval_index == disapproval_count - 1 then |
| bsw/jbe@19 | 265 if #entries == 1 then |
| bsw/jbe@19 | 266 heading = _"Disapproval (prefer to last block) [single entry]" |
| bsw/jbe@19 | 267 else |
| bsw/jbe@19 | 268 heading = _"Disapproval (prefer to last block) [many entries]" |
| bsw/jbe@19 | 269 end |
| bsw/jbe@19 | 270 else |
| bsw/jbe@19 | 271 if #entries == 1 then |
| bsw/jbe@19 | 272 heading = _"Disapproval [single entry]" |
| bsw/jbe@19 | 273 else |
| bsw/jbe@19 | 274 heading = _"Disapproval [many entries]" |
| bsw/jbe@6 | 275 end |
| bsw/jbe@19 | 276 end |
| bsw/jbe@19 | 277 end |
| bsw/jbe@19 | 278 ui.tag { |
| bsw/jbe@19 | 279 tag = "div", |
| bsw/jbe@19 | 280 attr = { class = "cathead" }, |
| bsw/jbe@19 | 281 content = heading |
| bsw/jbe@19 | 282 } |
| bsw/jbe@19 | 283 for i, initiative in ipairs(entries) do |
| bsw/jbe@19 | 284 ui.container{ |
| bsw/jbe@19 | 285 attr = { |
| bsw/jbe@19 | 286 class = "movable", |
| bsw/jbe@19 | 287 id = "entry_" .. tostring(initiative.id) |
| bsw/jbe@19 | 288 }, |
| bsw/jbe@19 | 289 content = function() |
| bsw/jbe@19 | 290 local initiators_selector = initiative:get_reference_selector("initiating_members") |
| bsw/jbe@19 | 291 :add_where("accepted") |
| bsw/jbe@19 | 292 local initiators = initiators_selector:exec() |
| bsw/jbe@19 | 293 local initiator_names = {} |
| bsw/jbe@19 | 294 for i, initiator in ipairs(initiators) do |
| bsw/jbe@19 | 295 initiator_names[#initiator_names+1] = initiator.name |
| bsw/jbe@19 | 296 end |
| bsw/jbe@19 | 297 local initiator_names_string = table.concat(initiator_names, ", ") |
| bsw/jbe@19 | 298 ui.container{ |
| bsw/jbe@19 | 299 attr = { style = "float: right;" }, |
| bsw/jbe@19 | 300 content = function() |
| bsw/jbe@19 | 301 ui.link{ |
| bsw/jbe@19 | 302 attr = { class = "clickable" }, |
| bsw/jbe@19 | 303 content = _"Show", |
| bsw/jbe@19 | 304 module = "initiative", |
| bsw/jbe@19 | 305 view = "show", |
| bsw/jbe@19 | 306 id = initiative.id |
| bsw/jbe@19 | 307 } |
| bsw/jbe@19 | 308 slot.put(" ") |
| bsw/jbe@19 | 309 ui.link{ |
| bsw/jbe@19 | 310 attr = { class = "clickable", target = "_blank" }, |
| bsw/jbe@19 | 311 content = _"(new window)", |
| bsw/jbe@19 | 312 module = "initiative", |
| bsw/jbe@19 | 313 view = "show", |
| bsw/jbe@19 | 314 id = initiative.id |
| bsw/jbe@19 | 315 } |
| bsw/jbe@19 | 316 if not readonly then |
| bsw/jbe@19 | 317 slot.put(" ") |
| bsw/jbe@19 | 318 ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" } |
| bsw/jbe@19 | 319 end |
| bsw/jbe@19 | 320 end |
| bsw/jbe@19 | 321 } |
| bsw/jbe@19 | 322 if not readonly then |
| bsw/jbe@19 | 323 ui.container{ |
| bsw/jbe@19 | 324 attr = { style = "float: left;" }, |
| bsw/jbe@19 | 325 content = function() |
| bsw/jbe@19 | 326 ui.tag{ |
| bsw/jbe@19 | 327 tag = "input", |
| bsw/jbe@19 | 328 attr = { |
| bsw/jbe@19 | 329 onclick = "voting_moveUp(this.parentNode.parentNode); return(false);", |
| bsw/jbe@19 | 330 name = "move_up", |
| bsw/jbe@19 | 331 value = initiative.id, |
| bsw/jbe@19 | 332 class = not disabled and "clickable" or nil, |
| bsw/jbe@19 | 333 type = "image", |
| bsw/jbe@19 | 334 src = encode.url{ static = "icons/move_up.png" }, |
| bsw/jbe@19 | 335 alt = _"Move up" |
| bsw/jbe@19 | 336 } |
| bsw/jbe@19 | 337 } |
| bsw/jbe@19 | 338 slot.put(" ") |
| bsw/jbe@19 | 339 ui.tag{ |
| bsw/jbe@19 | 340 tag = "input", |
| bsw/jbe@19 | 341 attr = { |
| bsw/jbe@19 | 342 onclick = "voting_moveDown(this.parentNode.parentNode); return(false);", |
| bsw/jbe@19 | 343 name = "move_down", |
| bsw/jbe@19 | 344 value = initiative.id, |
| bsw/jbe@19 | 345 class = not disabled and "clickable" or nil, |
| bsw/jbe@19 | 346 type = "image", |
| bsw/jbe@19 | 347 src = encode.url{ static = "icons/move_down.png" }, |
| bsw/jbe@19 | 348 alt = _"Move down" |
| bsw/jbe@19 | 349 } |
| bsw/jbe@19 | 350 } |
| bsw/jbe@19 | 351 slot.put(" ") |
| bsw/jbe@19 | 352 end |
| bsw/jbe@6 | 353 } |
| bsw/jbe@6 | 354 end |
| bsw/jbe@6 | 355 ui.container{ |
| bsw/jbe@19 | 356 content = function() |
| bsw/jbe@19 | 357 slot.put(encode.html(initiative.shortened_name)) |
| bsw/jbe@19 | 358 if #initiators > 1 then |
| bsw/jbe@19 | 359 ui.container{ |
| bsw/jbe@19 | 360 attr = { style = "font-size: 80%;" }, |
| bsw/jbe@19 | 361 content = _"Initiators" .. ": " .. initiator_names_string |
| bsw/jbe@19 | 362 } |
| bsw/jbe@19 | 363 else |
| bsw/jbe@19 | 364 ui.container{ |
| bsw/jbe@19 | 365 attr = { style = "font-size: 80%;" }, |
| bsw/jbe@19 | 366 content = _"Initiator" .. ": " .. initiator_names_string |
| bsw/jbe@19 | 367 } |
| bsw/jbe@19 | 368 end |
| bsw/jbe@19 | 369 end |
| bsw/jbe@6 | 370 } |
| bsw/jbe@6 | 371 end |
| bsw/jbe@19 | 372 } |
| bsw/jbe@19 | 373 end |
| bsw/jbe@5 | 374 end |
| bsw/jbe@19 | 375 } |
| bsw/jbe@19 | 376 end |
| bsw/jbe@5 | 377 end |
| bsw/jbe@5 | 378 end |
| bsw/jbe@5 | 379 } |
| bsw/jbe@19 | 380 if not readonly then |
| bsw/jbe@19 | 381 ui.tag{ |
| bsw/jbe@19 | 382 tag = "input", |
| bsw/jbe@19 | 383 attr = { |
| bsw/jbe@19 | 384 type = "button", |
| bsw/jbe@19 | 385 class = "voting_done", |
| bsw/jbe@19 | 386 value = _"Finish voting" |
| bsw/jbe@19 | 387 } |
| bsw/jbe@5 | 388 } |
| bsw/jbe@19 | 389 end |
| bsw/jbe@5 | 390 end |
| bsw/jbe@5 | 391 } |
| bsw/jbe@5 | 392 |
| bsw/jbe@5 | 393 |