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