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