liquid_feedback_frontend
diff env/ui/tabs.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 | 80c215dbf076 |
children | 4f39f0a0d5b5 |
line diff
1.1 --- a/env/ui/tabs.lua Tue Feb 02 00:31:06 2010 +0100 1.2 +++ b/env/ui/tabs.lua Sat Feb 20 22:10:31 2010 +0100 1.3 @@ -1,41 +1,239 @@ 1.4 -function ui.tabs(tabs) 1.5 - ui.container{ 1.6 - attr = { class = "ui_tabs" }, 1.7 - content = function() 1.8 +if config.user_tab_mode == "accordeon" or config.user_tab_mode == "accordeon_first_expanded" or config.user_tab_mode == "accordeon_all_expanded" then 1.9 + 1.10 + function ui.tabs(tabs) 1.11 + local params = param.get_all_cgi() 1.12 + local current_tabs_string = params["tab"] 1.13 + local current_tabs = {} 1.14 + if current_tabs_string then 1.15 + for current_tab in current_tabs_string:gmatch("([^%|]+)") do 1.16 + current_tabs[current_tab] = current_tab 1.17 + end 1.18 + end 1.19 + 1.20 + local unique_string = param.get("tab_id") or multirand.string(16, '0123456789abcdef') 1.21 + 1.22 + function render_tab(tab, first) 1.23 local params = param.get_all_cgi() 1.24 - local current_tab = params["tab"] 1.25 - ui.container{ 1.26 - attr = { class = "ui_tabs_links" }, 1.27 + local active = false 1.28 + for current_tab in pairs(current_tabs) do 1.29 + if tab.name == current_tab then 1.30 + active = true 1.31 + end 1.32 + end 1.33 + if config.user_tab_mode == "accordeon_first_expanded" then 1.34 + if first and current_tabs_string == nil then 1.35 + active = true 1.36 + end 1.37 + end 1.38 + local link_tabs = {} 1.39 + if config.user_tab_mode == "accordeon" 1.40 + or config.user_tab_mode == "accordeon_first_expanded" 1.41 + or config.user_tab_mode == "accordeon_all_expanded" and current_tabs_string 1.42 + then 1.43 + if not current_tabs_string and not first then 1.44 + link_tabs[tabs[1].name] = true 1.45 + end 1.46 + for current_tab in pairs(current_tabs) do 1.47 + if current_tab ~= tab.name then 1.48 + link_tabs[current_tab] = true 1.49 + end 1.50 + end 1.51 + elseif config.user_tab_mode == "accordeon_all_expanded" and not current_tabs_string then 1.52 + for i, current_tab in ipairs(tabs) do 1.53 + if current_tab.name ~= tab.name then 1.54 + link_tabs[current_tab.name] = true 1.55 + end 1.56 + end 1.57 + end 1.58 + if not active then 1.59 + link_tabs[tab.name] = true 1.60 + end 1.61 + local link_tab_string = "" 1.62 + for link_tab in pairs(link_tabs) do 1.63 + if #link_tab_string > 0 then 1.64 + link_tab_string = link_tab_string .. "|" 1.65 + end 1.66 + link_tab_string = link_tab_string .. link_tab 1.67 + end 1.68 + params["tab"] = link_tab_string 1.69 + local onclick 1.70 + if not tab.content then 1.71 + onclick = 1.72 + 'if (ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"]) {' .. 1.73 + 'el=document.getElementById("tab' .. unique_string .. '_content_' .. tab.name .. '");' .. 1.74 + 'el.innerHTML="";' .. 1.75 + 'el.style.display="none";' .. 1.76 + 'ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"]=false' .. 1.77 + '} else {' .. 1.78 + 'ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"]=true;' .. 1.79 + 'document.getElementById("tab' .. unique_string .. '_content_' .. tab.name .. '").style.display="block"; ' .. 1.80 + ui._partial_load_js{ 1.81 + params = { tab = tab.name } 1.82 + } .. 1.83 + '};' .. 1.84 + 'return(false);' 1.85 + end 1.86 + ui.link{ 1.87 + attr = { 1.88 + name = "tab_" .. tab.name, 1.89 + class = ( 1.90 + tab.name == current_tab and "ui_tabs_accordeon_head selected" or 1.91 + not current_tab and i == 1 and "ui_tabs_accordeon_head selected" or 1.92 + "ui_tabs_accordeon_head" 1.93 + ), 1.94 + id = "tab" .. unique_string .. "_head_" .. tab.name, 1.95 + onclick = onclick, 1.96 + }, 1.97 + module = request.get_module(), 1.98 + view = request.get_view(), 1.99 + id = param.get_id_cgi(), 1.100 + params = params, 1.101 + anchor = "tab" .. unique_string .. "_" .. tab.name, 1.102 content = function() 1.103 - for i, tab in ipairs(tabs) do 1.104 - params["tab"] = i > 1 and tab.name or nil 1.105 - ui.link{ 1.106 - attr = { 1.107 - class = ( 1.108 - tab.name == current_tab and "selected" or 1.109 - not current_tab and i == 1 and "selected" or 1.110 - "" 1.111 - ) 1.112 - }, 1.113 - module = request.get_module(), 1.114 - view = request.get_view(), 1.115 - id = param.get_id_cgi(), 1.116 - text = tab.label, 1.117 - params = params 1.118 + if tab.icon then 1.119 + if not tab.icon.attr then 1.120 + tab.icon.attr = {} 1.121 + end 1.122 + tab.icon.attr.id = "tab" .. unique_string .. "_icon_" .. tab.name 1.123 + tab.icon.attr.width = 16 1.124 + tab.icon.attr.height = 16 1.125 + ui.image(tab.icon) 1.126 + end 1.127 + slot.put(tab.label) 1.128 + end 1.129 + } 1.130 + local expanded = active or not request.get_json_request_slots() and config.user_tab_mode == "accordeon_all_expanded" and not current_tabs_string 1.131 + ui.container{ 1.132 + attr = { 1.133 + class = "ui_tabs_accordeon_content", 1.134 + style = not expanded and "display: none;" or nil, 1.135 + id = "tab" .. unique_string .. "_content_" .. tab.name 1.136 + }, 1.137 + content = function() 1.138 + if expanded then 1.139 + ui.script{ script = 'ui_tabs_active["' .. unique_string .. '"]["' .. tab.name .. '"] = true;' } 1.140 + execute.view{ 1.141 + module = tab.module, 1.142 + view = tab.view, 1.143 + id = tab.id, 1.144 + params = tab.params 1.145 } 1.146 - slot.put(" ") 1.147 + else 1.148 + slot.put(" ") 1.149 end 1.150 end 1.151 } 1.152 + end 1.153 + 1.154 + if not request.get_json_request_slots() or not current_tabs_string then 1.155 + ui.script{ script = "ui_tabs_active['" .. unique_string .. "'] = {};" } 1.156 + ui.container{ 1.157 + attr = { class = "ui_tabs" }, 1.158 + content = function() 1.159 + for i, tab in ipairs(tabs) do 1.160 + local static_params = tabs.static_params or {} 1.161 + static_params.tab = tab.name 1.162 + static_params.tab_id = unique_string 1.163 + ui.partial{ 1.164 + module = tabs.module, 1.165 + view = tabs.view, 1.166 + id = tabs.id, 1.167 + params = static_params, 1.168 + param_names = { "page" }, 1.169 + hourglass_target = "tab" .. unique_string .. "_icon_" .. tab.name, 1.170 + target = "tab" .. unique_string .. "_content_" .. tab.name, 1.171 + content = function() 1.172 + render_tab(tab, i == 1) 1.173 + end 1.174 + } 1.175 + end 1.176 + end 1.177 + } 1.178 + else 1.179 + local dyntab 1.180 for i, tab in ipairs(tabs) do 1.181 - if tab.name == current_tab or not current_tab and i == 1 then 1.182 - ui.container{ 1.183 - attr = { class = "ui_tabs_content" }, 1.184 - content = tab.content 1.185 - } 1.186 + if tab.name == current_tabs_string then 1.187 + dyntab = tab 1.188 end 1.189 end 1.190 + if dyntab then 1.191 + local static_params = tabs.static_params or {} 1.192 + static_params.tab = dyntab.name 1.193 + static_params.tab_id = unique_string 1.194 + dyntab.params.tab_id = unique_string 1.195 + ui.partial{ 1.196 + module = tabs.module, 1.197 + view = tabs.view, 1.198 + id = tabs.id, 1.199 + params = static_params, 1.200 + param_names = { "page" }, 1.201 + hourglass_target = "tab" .. unique_string .. "_icon_" .. dyntab.name, 1.202 + target = "tab" .. unique_string .. "_content_" .. dyntab.name, 1.203 + content = function() 1.204 + execute.view{ 1.205 + module = dyntab.module, 1.206 + view = dyntab.view, 1.207 + id = dyntab.id, 1.208 + params = dyntab.params, 1.209 + } 1.210 + end 1.211 + } 1.212 + end 1.213 end 1.214 - } 1.215 -end 1.216 + end 1.217 + 1.218 +else -- 'classic tab' 1.219 1.220 + function ui.tabs(tabs) 1.221 + ui.container{ 1.222 + attr = { class = "ui_tabs" }, 1.223 + content = function() 1.224 + local params = param.get_all_cgi() 1.225 + local current_tab = params["tab"] 1.226 + ui.container{ 1.227 + attr = { class = "ui_tabs_links" }, 1.228 + content = function() 1.229 + for i, tab in ipairs(tabs) do 1.230 + params["tab"] = i > 1 and tab.name or nil 1.231 + ui.link{ 1.232 + attr = { 1.233 + class = ( 1.234 + tab.name == current_tab and "selected" or 1.235 + not current_tab and i == 1 and "selected" or 1.236 + "" 1.237 + ) 1.238 + }, 1.239 + module = request.get_module(), 1.240 + view = request.get_view(), 1.241 + id = param.get_id_cgi(), 1.242 + content = tab.label, 1.243 + params = params 1.244 + } 1.245 + slot.put(" ") 1.246 + end 1.247 + end 1.248 + } 1.249 + for i, tab in ipairs(tabs) do 1.250 + if tab.name == current_tab or not current_tab and i == 1 then 1.251 + ui.container{ 1.252 + attr = { class = "ui_tabs_content" }, 1.253 + content = function() 1.254 + if tab.content then 1.255 + tab.content() 1.256 + else 1.257 + execute.view{ 1.258 + module = tab.module, 1.259 + view = tab.view, 1.260 + id = tab.id, 1.261 + params = tab.params, 1.262 + } 1.263 + end 1.264 + end 1.265 + } 1.266 + end 1.267 + end 1.268 + end 1.269 + } 1.270 + end 1.271 + 1.272 +end 1.273 \ No newline at end of file