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