webmcp
view framework/env/ui/paginate.lua @ 569:5b19007574de
New argument active_link_attr for env.ui.paginate{...}
| author | jbe | 
|---|---|
| date | Wed Oct 13 17:21:44 2021 +0200 (2021-10-13) | 
| parents | c43f251262d8 | 
| children | 
 line source
     1 --[[--
     2 ui.paginate{
     3   selector         = selector,          -- a selector for items from the database (will be modified)
     4   anchor           = anchor,            -- optional name of anchor in document to jump to
     5   per_page         = per_page,          -- items per page, defaults to 10
     6   container_attr   = container_attr,    -- html attr for the container element
     7   link_attr        = link_attr,         -- html attr for each page link
     8   active_link_attr = active_link_attr,  -- alternative html attr for the active page link
     9   name             = name,              -- name of the CGI get variable, defaults to "page"
    10   position         = position,          -- position of page links relative to content: "before", "after", or "both" (default)
    11   content          = function()
    12     ...                                 -- code block which should be encapsulated with page selection links
    13   end
    14 }
    16 This function preceeds and appends the output of the given 'content' function with page selection links. The passed selector will be modified to show only a limited amount ('per_page') of items. The currently displayed page will be determined directly by request.get_param{...}, and not via the param.get(...) function, in order to pass page selections automatically to sub-views.
    18 --]]--
    20 function ui.paginate(args)
    21   local selector         = args.selector
    22   local anchor           = args.anchor
    23   local per_page         = args.per_page or 10
    24   local container_attr   = args.container_attr or { class = 'ui_paginate' }
    25   local link_attr        = args.link_attr or {}
    26   local active_link_attr = args.active_link_attr or link_attr
    27   local name             = args.name or 'page'
    28   local position         = args.position or 'both'
    29   local content          = args.content
    30   local count_selector = selector:get_db_conn():new_selector()
    31   count_selector:add_field('count(1)')
    32   count_selector:add_from(selector)
    33   count_selector:single_object_mode()
    34   local count = count_selector:exec().count
    35   local page_count = 1
    36   if count > 0 then
    37     page_count = math.floor((count - 1) / per_page) + 1
    38   end
    39   local current_page = atom.integer:load(request.get_param{name=name}) or 1
    40   if current_page > page_count then
    41     current_page = page_count
    42   end
    43   selector:limit(per_page)
    44   selector:offset((current_page - 1) * per_page)
    45   local id     = request.get_id_string()
    46   local params = request.get_param_strings()
    47   local function pagination_elements()
    48     if page_count > 1 then
    49       for page = 1, page_count do
    50         if page > 1 then
    51           slot.put(" ")
    52         end
    53         params[name] = page
    54         local attr
    55         if current_page == page then
    56           attr = table.new(active_link_attr)
    57           if attr.class then
    58             attr.class = attr.class .. " active"
    59           else
    60             attr.class = "active"
    61           end
    62         else
    63           attr = table.new(link_attr)
    64         end
    65         ui.link{
    66           attr   = attr,
    67           module = request.get_module(),
    68           view   = request.get_view(),
    69           id     = id,
    70           params = params,
    71           anchor = anchor,
    72           text   = tostring(page)
    73         }
    74       end
    75     end
    76   end
    77   ui.container{
    78     attr = container_attr,
    79     content = function()
    80       if position == 'before' or position == 'both' then
    81         ui.container{
    82           attr = { class = 'ui_paginate_head ui_paginate_select' },
    83           content = pagination_elements
    84         }
    85       end
    86       ui.container{
    87         attr = { class = 'ui_paginate_content' },
    88         content = content
    89       }
    90       if position == 'after' or position == 'both' then
    91         ui.container{
    92           attr = { class = 'ui_paginate_foot ui_paginate_select' },
    93           content = pagination_elements
    94         }
    95       end
    96     end
    97   }
    98 end
