webmcp
view framework/env/ui/multiselect.lua @ 149:5229687c7601
Removed metatable entries in JSON library module (since they should not be set directly); Added documentation to JSON library
| author | jbe | 
|---|---|
| date | Wed Jul 30 22:56:21 2014 +0200 (2014-07-30) | 
| parents | 81dfcfd960ed | 
| children | 
 line source
     1 --[[--
     2 ui.multiselect{
     3   name               = name,                -- HTML name ('html_name' is NOT a valid argument for this function)
     4   container_attr     = container_attr,      -- extra HTML attributes for the container (div) enclosing field and label
     5   container2_attr    = container2_attr,     -- extra HTML attributes for the container (div) of the real element (in checkbox case only)
     6   attr               = attr,                -- extra HTML attributes for the field
     7   label              = label,               -- text to be used as label for the input field
     8   label_attr         = label_attr,          -- extra HTML attributes for the label
     9   readonly           = readonly_flag        -- set to true, to force read-only mode
    10   foreign_records    = foreign_records,     -- list of records to be chosen from, or function returning such a list
    11   foreign_id         = foreign_id,          -- name of id field in foreign records
    12   foreign_name       = foreign_name,        -- name of field to be used as name in foreign records
    13   selected_ids       = selected_ids,        -- list of ids of currently selected foreign records
    14   connecting_records = connecting_records,  -- list of connection entries, determining which foreign records are currently selected
    15   own_id             = own_id,              -- TODO documentation needed
    16   own_reference      = own_reference,       -- name of foreign key field in connecting records, which references the main record
    17   foreign_reference  = foreign_reference,   -- name of foreign key field in connecting records, which references foreign records
    18   format_options     = format_options       -- format options for format.string
    19 }
    21 This function inserts a select field with possibility of multiple selections in the active slot. This function does not reside within ui.field.*, because multiple selections are not stored within a field of a record, but within a different SQL table. Note that 'html_name' is NOT a valid argument to this function. For description of the generic field helper arguments, see help for ui.autofield{...}.
    23 --]]--
    25 function ui.multiselect(args)
    26   local style = args.style or "checkbox"
    27   local extra_args = { fetch_record = true }
    28   if not args.readonly and args.style == "checkbox" then
    29     extra_args.disable_label_for_id = true
    30   end
    31   ui.form_element(args, extra_args, function(args)
    32     local foreign_records = args.foreign_records
    33     if type(foreign_records) == "function" then
    34       foreign_records = foreign_records(args.record)
    35     end
    36     local connecting_records = args.connecting_records
    37     if type(connecting_records) == "function" then
    38       connecting_records = connecting_records(args.record)
    39     end
    40     local select_hash = {}
    41     if args.selected_ids then
    42       for idx, selected_id in ipairs(args.selected_ids) do
    43         select_hash[selected_id] = true
    44       end
    45     elseif args.own_reference then
    46       for idx, connecting_record in ipairs(args.connecting_records) do
    47         if connecting_record[args.own_reference] == args.record[args.own_id] then
    48           select_hash[connecting_record[args.foreign_reference]] = true
    49         end
    50       end
    51     else
    52       for idx, connecting_record in ipairs(args.connecting_records) do
    53         select_hash[connecting_record[args.foreign_reference]] = true
    54       end
    55     end
    56     local attr = table.new(args.attr)
    57     if not attr.class then
    58       attr.class = "ui_multi_selection"
    59     end
    60     if args.readonly then
    61       ui.tag{
    62         tag     = "ul",
    63         attr    = attr,
    64         content = function()
    65           for idx, record in ipairs(foreign_records) do
    66             if select_hash[record[args.foreign_id]] then
    67               ui.tag{
    68                 tag     = "li",
    69                 content = format.string(
    70                   record[args.foreign_name],
    71                   args.format_options
    72                 )
    73               }
    74             end
    75           end
    76         end
    77       }
    78     elseif style == "select" then
    79       attr.name     = args.name
    80       attr.multiple = "multiple"
    81       ui.tag{
    82         tag     = "select",
    83         attr    = attr,
    84         content = function()
    85           if args.nil_as then
    86             ui.tag{
    87               tag     = "option",
    88               attr    = { value = "" },
    89               content = format.string(
    90                 args.nil_as,
    91                 args.format_options
    92               )
    93             }
    94           end
    95           for idx, record in ipairs(foreign_records) do
    96             local key = record[args.foreign_id]
    97             local selected = select_hash[key]
    98             ui.tag{
    99               tag     = "option",
   100               attr    = {
   101                 value    = key,
   102                 selected = (selected and "selected" or nil)
   103               },
   104               content = format.string(
   105                 record[args.foreign_name],
   106                 args.format_options
   107               )
   108             }
   109           end
   110         end
   111       }
   112     elseif style == "checkbox" then
   113       attr.type = "checkbox"
   114       attr.name = args.name
   115       for idx, record in ipairs(foreign_records) do
   116         local key = record[args.foreign_id]
   117         local selected = select_hash[key]
   118         attr.id   = ui.create_unique_id()
   119         attr.value = key
   120         attr.checked = selected and "checked" or nil
   121         ui.container{
   122           label = format.string(
   123             record[args.foreign_name],
   124             args.format_options
   125           ),
   126           attr          = args.container2_attr or { class = "ui_checkbox_div" },
   127           label_for     = attr.id,
   128           label_attr    = args.label_attr or { class = "ui_checkbox_label" },
   129           content_first = true,
   130           content       = function()
   131             ui.tag{ tag  = "input", attr = attr }
   132           end
   133         }
   134       end
   135     else
   136       error("'style' attribute for ui.multiselect{...} must be set to \"select\", \"checkbox\" or nil.")
   137     end
   138   end)
   139 end
