jbe/bsw@0: --[[-- jbe/bsw@0: ui.multiselect{ jbe/bsw@0: name = name, -- HTML name ('html_name' is NOT a valid argument for this function) jbe/bsw@0: container_attr = container_attr, -- extra HTML attributes for the container (div) enclosing field and label poelzi@35: container2_attr = container2_attr, -- extra HTML attributes for the container (div) of the real element (in checkbox case only) jbe/bsw@0: attr = attr, -- extra HTML attributes for the field jbe/bsw@0: label = label, -- text to be used as label for the input field jbe/bsw@0: label_attr = label_attr, -- extra HTML attributes for the label jbe/bsw@0: readonly = readonly_flag -- set to true, to force read-only mode jbe/bsw@0: foreign_records = foreign_records, -- list of records to be chosen from, or function returning such a list jbe/bsw@0: foreign_id = foreign_id, -- name of id field in foreign records jbe/bsw@0: foreign_name = foreign_name, -- name of field to be used as name in foreign records jbe/bsw@0: selected_ids = selected_ids, -- list of ids of currently selected foreign records jbe/bsw@0: connecting_records = connecting_records, -- list of connection entries, determining which foreign records are currently selected jbe/bsw@0: own_id = own_id, -- TODO documentation needed jbe/bsw@0: own_reference = own_reference, -- name of foreign key field in connecting records, which references the main record jbe/bsw@0: foreign_reference = foreign_reference, -- name of foreign key field in connecting records, which references foreign records jbe/bsw@0: format_options = format_options -- format options for format.string jbe/bsw@0: } jbe/bsw@0: jbe/bsw@0: 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: jbe/bsw@0: --]]-- jbe/bsw@0: jbe/bsw@0: function ui.multiselect(args) jbe/bsw@0: local style = args.style or "checkbox" jbe/bsw@0: local extra_args = { fetch_record = true } jbe/bsw@0: if not args.readonly and args.style == "checkbox" then jbe/bsw@0: extra_args.disable_label_for_id = true jbe/bsw@0: end jbe/bsw@0: ui.form_element(args, extra_args, function(args) jbe/bsw@0: local foreign_records = args.foreign_records jbe/bsw@0: if type(foreign_records) == "function" then jbe/bsw@0: foreign_records = foreign_records(args.record) jbe/bsw@0: end jbe/bsw@0: local connecting_records = args.connecting_records jbe/bsw@0: if type(connecting_records) == "function" then jbe/bsw@0: connecting_records = connecting_records(args.record) jbe/bsw@0: end jbe/bsw@0: local select_hash = {} jbe/bsw@0: if args.selected_ids then jbe/bsw@0: for idx, selected_id in ipairs(args.selected_ids) do jbe/bsw@0: select_hash[selected_id] = true jbe/bsw@0: end jbe/bsw@0: elseif args.own_reference then jbe/bsw@0: for idx, connecting_record in ipairs(args.connecting_records) do jbe/bsw@0: if connecting_record[args.own_reference] == args.record[args.own_id] then jbe/bsw@0: select_hash[connecting_record[args.foreign_reference]] = true jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: else jbe/bsw@0: for idx, connecting_record in ipairs(args.connecting_records) do jbe/bsw@0: select_hash[connecting_record[args.foreign_reference]] = true jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: local attr = table.new(args.attr) jbe/bsw@0: if not attr.class then jbe/bsw@0: attr.class = "ui_multi_selection" jbe/bsw@0: end jbe/bsw@0: if args.readonly then jbe/bsw@0: ui.tag{ jbe/bsw@0: tag = "ul", jbe/bsw@0: attr = attr, jbe/bsw@0: content = function() jbe/bsw@0: for idx, record in ipairs(foreign_records) do jbe/bsw@0: if select_hash[record[args.foreign_id]] then jbe/bsw@0: ui.tag{ jbe/bsw@0: tag = "li", jbe/bsw@0: content = format.string( jbe/bsw@0: record[args.foreign_name], jbe/bsw@0: args.format_options jbe/bsw@0: ) jbe/bsw@0: } jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: } jbe/bsw@0: elseif style == "select" then jbe/bsw@0: attr.name = args.name jbe/bsw@0: attr.multiple = "multiple" jbe/bsw@0: ui.tag{ jbe/bsw@0: tag = "select", jbe/bsw@0: attr = attr, jbe/bsw@0: content = function() jbe/bsw@0: if args.nil_as then jbe/bsw@0: ui.tag{ jbe/bsw@0: tag = "option", jbe/bsw@0: attr = { value = "" }, jbe/bsw@0: content = format.string( jbe/bsw@0: args.nil_as, jbe/bsw@0: args.format_options jbe/bsw@0: ) jbe/bsw@0: } jbe/bsw@0: end jbe/bsw@0: for idx, record in ipairs(foreign_records) do jbe/bsw@0: local key = record[args.foreign_id] jbe/bsw@0: local selected = select_hash[key] jbe/bsw@0: ui.tag{ jbe/bsw@0: tag = "option", jbe/bsw@0: attr = { jbe/bsw@0: value = key, jbe/bsw@0: selected = (selected and "selected" or nil) jbe/bsw@0: }, jbe/bsw@0: content = format.string( jbe/bsw@0: record[args.foreign_name], jbe/bsw@0: args.format_options jbe/bsw@0: ) jbe/bsw@0: } jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: } jbe/bsw@0: elseif style == "checkbox" then jbe/bsw@0: attr.type = "checkbox" jbe/bsw@0: attr.name = args.name jbe/bsw@0: for idx, record in ipairs(foreign_records) do jbe/bsw@0: local key = record[args.foreign_id] jbe/bsw@0: local selected = select_hash[key] jbe/bsw@0: attr.id = ui.create_unique_id() jbe/bsw@0: attr.value = key jbe/bsw@0: attr.checked = selected and "checked" or nil jbe/bsw@0: ui.container{ jbe/bsw@0: label = format.string( jbe/bsw@0: record[args.foreign_name], jbe/bsw@0: args.format_options jbe/bsw@0: ), poelzi@35: attr = args.container2_attr or { class = "ui_checkbox_div" }, jbe/bsw@0: label_for = attr.id, poelzi@35: label_attr = args.label_attr or { class = "ui_checkbox_label" }, jbe/bsw@0: content_first = true, jbe/bsw@0: content = function() jbe/bsw@0: ui.tag{ tag = "input", attr = attr } jbe/bsw@0: end jbe/bsw@0: } jbe/bsw@0: end jbe/bsw@0: else jbe/bsw@0: error("'style' attribute for ui.multiselect{...} must be set to \"select\", \"checkbox\" or nil.") jbe/bsw@0: end jbe/bsw@0: end) jbe/bsw@0: end