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
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

Impressum / About Us