) and "div" (just using tags) are supported. For each column several options must be specified.
jbe/bsw@0:
jbe/bsw@0: --]]--
jbe/bsw@0:
jbe/bsw@0: -- TODO: documentation of the prefix option
jbe/bsw@0: -- TODO: check short descriptions of fields in documentation
jbe/bsw@0: -- TODO: field_attr is used for the OUTER html tag's attributes, while attr is used for the INNER html tag's attributes (produced by ui.field.*), is that okay?
jbe/bsw@0: -- TODO: use field information of record class, if no columns are given
jbe/bsw@0: -- TODO: callback to set row attr's for a specific row
jbe/bsw@0:
jbe/bsw@0: function ui.list(args)
jbe/bsw@0: local args = args or {}
jbe/bsw@0: local label = args.label
jbe/bsw@0: local list_type = args.style or "table"
jbe/bsw@0: local prefix = args.prefix
jbe/bsw@0: local records = assert(args.records, "ui.list{...} needs records.")
jbe/bsw@0: local columns = assert(args.columns, "ui.list{...} needs column definitions.")
jbe/bsw@0: local outer_attr = table.new(args.attr)
jbe/bsw@0: local header_existent = false
jbe/bsw@0: for idx, column in ipairs(columns) do
jbe/bsw@0: if column.label then
jbe/bsw@0: header_existent = true
jbe/bsw@0: break
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: local slot_state = slot.get_state_table()
jbe@244: local outer_tag, head_tag, head_tag2, label_tag, body_tag, row_tag, field_tag
jbe/bsw@0: if list_type == "table" then
jbe/bsw@0: outer_tag = "table"
jbe/bsw@0: head_tag = "thead"
jbe/bsw@0: head_tag2 = "tr"
jbe/bsw@0: label_tag = "th"
jbe/bsw@0: body_tag = "tbody"
jbe/bsw@0: row_tag = "tr"
jbe/bsw@0: field_tag = "td"
jbe/bsw@0: elseif list_type == "ulli" then
jbe/bsw@0: outer_tag = "div"
jbe/bsw@0: head_tag = "div"
jbe/bsw@0: label_tag = "div"
jbe/bsw@0: body_tag = "ul"
jbe/bsw@0: row_tag = "li"
jbe/bsw@0: field_tag = "td"
jbe/bsw@0: elseif list_type == "div" then
jbe/bsw@0: outer_tag = "div"
jbe/bsw@0: head_tag = "div"
jbe/bsw@0: label_tag = "div"
jbe/bsw@0: body_tag = "div"
jbe/bsw@0: row_tag = "div"
jbe/bsw@0: field_tag = "div"
jbe/bsw@0: else
jbe/bsw@0: error("Unknown list type specified for ui.list{...}.")
jbe/bsw@0: end
jbe/bsw@0: outer_attr.class = outer_attr.class or "ui_list"
jbe/bsw@0: ui.container{
jbe/bsw@0: auto_args = args,
jbe/bsw@0: content = function()
jbe/bsw@0: ui.tag{
jbe/bsw@0: tag = outer_tag,
jbe/bsw@0: attr = outer_attr,
jbe/bsw@0: content = function()
jbe/bsw@0: if header_existent then
jbe/bsw@0: ui.tag{
jbe/bsw@0: tag = head_tag,
jbe/bsw@0: attr = { class = "ui_list_head" },
jbe/bsw@0: content = function()
jbe/bsw@0: local function header_content()
jbe/bsw@0: for idx, column in ipairs(columns) do
jbe/bsw@0: if column.ui_field_type ~= "hidden" then
jbe/bsw@0: local label_attr = table.new(column.label_attr)
jbe/bsw@0: label_attr.class =
jbe/bsw@0: label_attr.class or { class = "ui_list_label" }
jbe/bsw@0: ui.tag{
jbe/bsw@0: tag = label_tag,
jbe/bsw@0: attr = label_attr,
jbe/bsw@0: content = column.label or ""
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: if head_tag2 then
jbe/bsw@0: ui.tag{ tag = head_tag2, content = header_content }
jbe/bsw@0: else
jbe/bsw@0: header_content()
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: ui.tag{
jbe/bsw@0: tag = body_tag,
jbe/bsw@0: attr = { class = "ui_list_body" },
jbe/bsw@0: content = function()
jbe/bsw@0: for record_idx, record in ipairs(records) do
jbe/bsw@0: local row_class
jbe/bsw@0: if record_idx % 2 == 0 then
jbe/bsw@0: row_class = "ui_list_row ui_list_even"
jbe/bsw@0: else
jbe/bsw@0: row_class = "ui_list_row ui_list_odd"
jbe/bsw@0: end
jbe/bsw@0: ui.tag{
jbe/bsw@0: tag = row_tag,
jbe/bsw@0: attr = { class = row_class },
jbe/bsw@0: content = function()
jbe/bsw@0: local old_html_name_prefix, old_form_record
jbe/bsw@0: if prefix then
jbe/bsw@0: old_html_name_prefix = slot_state.html_name_prefix
jbe/bsw@0: old_form_record = slot_state.form_record
jbe/bsw@0: slot_state.html_name_prefix = prefix .. "[" .. record_idx .. "]"
jbe/bsw@0: slot_state.form_record = record
jbe/bsw@0: end
jbe/bsw@0: local first_column = true
jbe/bsw@0: for column_idx, column in ipairs(columns) do
jbe/bsw@0: if column.ui_field_type ~= "hidden" then
jbe/bsw@0: local field_attr = table.new(column.field_attr)
jbe/bsw@0: field_attr.class =
jbe/bsw@0: field_attr.class or { class = "ui_list_field" }
jbe/bsw@0: local field_content
jbe/bsw@0: if column.content then
jbe/bsw@0: field_content = function()
jbe/bsw@0: return column.content(record)
jbe/bsw@0: end
jbe/bsw@0: elseif column.name then
jbe/bsw@0: if column.ui_field_type then
jbe/bsw@0: local ui_field_func = ui.field[column.ui_field_type]
jbe/bsw@0: if not ui_field_func then
jbe/bsw@0: error('Unknown ui_field_type "' .. column.ui_field_type .. '".')
jbe/bsw@0: end
jbe/bsw@0: local ui_field_options = table.new(column)
jbe/bsw@0: ui_field_options.record = record
jbe/bsw@0: ui_field_options.label = nil
jbe/bsw@0: if not prefix and ui_field_options.readonly == nil then
jbe/bsw@0: ui_field_options.readonly = true
jbe/bsw@0: end
jbe/bsw@0: field_content = function()
jbe/bsw@0: return ui.field[column.ui_field_type](ui_field_options)
jbe/bsw@0: end
jbe/bsw@0: elseif column.format then
jbe/bsw@0: local formatter = format[column.format]
jbe/bsw@0: if not formatter then
jbe/bsw@0: error('Unknown format "' .. column.format .. '".')
jbe/bsw@0: end
jbe/bsw@0: field_content = formatter(
jbe/bsw@0: record[column.name], column.format_options
jbe/bsw@0: )
jbe/bsw@0: else
jbe/bsw@0: field_content = function()
jbe/bsw@0: return ui.autofield{
jbe/bsw@0: record = record,
jbe/bsw@0: name = column.name,
jbe/bsw@0: html_name = column.html_name
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: else
jbe/bsw@0: error("Each column needs either a 'content' or a 'name'.")
jbe/bsw@0: end
jbe/bsw@0: local extended_field_content
jbe/bsw@0: if first_column then
jbe/bsw@0: first_column = false
jbe/bsw@0: extended_field_content = function()
jbe/bsw@0: for column_idx, column in ipairs(columns) do
jbe/bsw@0: if column.ui_field_type == "hidden" then
jbe/bsw@0: local ui_field_options = table.new(column)
jbe/bsw@0: ui_field_options.record = record
jbe/bsw@0: ui_field_options.label = nil
jbe/bsw@0: if not prefix and ui_field_options.readonly == nil then
jbe/bsw@0: ui_field_options.readonly = true
jbe/bsw@0: end
jbe/bsw@0: ui.field.hidden(ui_field_options)
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: field_content()
jbe/bsw@0: end
jbe/bsw@0: else
jbe/bsw@0: extended_field_content = field_content
jbe/bsw@0: end
jbe/bsw@0: ui.tag{
jbe/bsw@0: tag = field_tag,
jbe/bsw@0: attr = field_attr,
jbe/bsw@0: content = extended_field_content
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: if prefix then
jbe/bsw@0: slot_state.html_name_prefix = old_html_name_prefix
jbe/bsw@0: slot_state.form_record = old_form_record
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: end
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: }
jbe/bsw@0: if prefix then
jbe/bsw@0: -- ui.field.hidden is used instead of ui.hidden_field to suppress output in case of read-only mode.
jbe/bsw@0: ui.field.hidden{
jbe/bsw@0: html_name = prefix .. "[len]",
jbe/bsw@0: value = #records
jbe/bsw@0: }
jbe/bsw@0: end
jbe/bsw@0: end