webmcp

annotate framework/env/ui/list.lua @ 386:e057f8d3f716

Callback of ui.list{...} receives index as second argument
author jbe
date Tue Dec 01 18:50:31 2015 +0100 (2015-12-01)
parents 10275e753a22
children
rev   line source
jbe/bsw@0 1 --[[--
jbe/bsw@0 2 ui.list{
jbe/bsw@0 3 label = list_label, -- optional label for the whole list
jbe/bsw@0 4 style = style, -- "table", "ulli" or "div"
jbe/bsw@0 5 prefix = prefix, -- prefix for HTML field names
jbe/bsw@0 6 records = records, -- array of records to be displayed as rows in the list
jbe/bsw@0 7 columns = {
jbe/bsw@0 8 {
jbe/bsw@0 9 label = column_label, -- label for the column
jbe/bsw@0 10 label_attr = label_attr, -- table with HTML attributes for the heading cell or div
jbe/bsw@0 11 field_attr = field_attr, -- table with HTML attributes for the data cell or div
jbe/bsw@0 12 name = name, -- name of the field in each record
jbe/bsw@0 13 html_name = html_name, -- optional html-name for writable fields (defaults to name)
jbe/bsw@0 14 ui_field_type = ui_field_type, -- name of the ui.field.* function to use
jbe/bsw@0 15 ...., -- other options for the given ui.field.* functions
jbe/bsw@0 16 format = format, -- name of the format function to be used (if not using ui_field_type)
jbe/bsw@0 17 format_options = format_options, -- options to be passed to the format function
jbe@386 18 content = content -- alternative function to output field data per record
jbe@386 19 -- (ignoring name, format, etc. when set)
jbe@386 20 -- (receives record as first and integer index as second argument)
jbe/bsw@0 21 },
jbe/bsw@0 22 { ... },
jbe/bsw@0 23 ...
jbe/bsw@0 24 }
jbe/bsw@0 25 }
jbe/bsw@0 26
jbe/bsw@0 27 This function takes an array of records to be displayed in a list. The whole list may have a label. The style's "table" (for <table>), "ulli" (for <ul><li>) and "div" (just using <div> tags) are supported. For each column several options must be specified.
jbe/bsw@0 28
jbe/bsw@0 29 --]]--
jbe/bsw@0 30
jbe/bsw@0 31 -- TODO: documentation of the prefix option
jbe/bsw@0 32 -- TODO: check short descriptions of fields in documentation
jbe/bsw@0 33 -- 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 34 -- TODO: use field information of record class, if no columns are given
jbe/bsw@0 35 -- TODO: callback to set row attr's for a specific row
jbe/bsw@0 36
jbe/bsw@0 37 function ui.list(args)
jbe/bsw@0 38 local args = args or {}
jbe/bsw@0 39 local label = args.label
jbe/bsw@0 40 local list_type = args.style or "table"
jbe/bsw@0 41 local prefix = args.prefix
jbe/bsw@0 42 local records = assert(args.records, "ui.list{...} needs records.")
jbe/bsw@0 43 local columns = assert(args.columns, "ui.list{...} needs column definitions.")
jbe/bsw@0 44 local outer_attr = table.new(args.attr)
jbe/bsw@0 45 local header_existent = false
jbe/bsw@0 46 for idx, column in ipairs(columns) do
jbe/bsw@0 47 if column.label then
jbe/bsw@0 48 header_existent = true
jbe/bsw@0 49 break
jbe/bsw@0 50 end
jbe/bsw@0 51 end
jbe/bsw@0 52 local slot_state = slot.get_state_table()
jbe@244 53 local outer_tag, head_tag, head_tag2, label_tag, body_tag, row_tag, field_tag
jbe/bsw@0 54 if list_type == "table" then
jbe/bsw@0 55 outer_tag = "table"
jbe/bsw@0 56 head_tag = "thead"
jbe/bsw@0 57 head_tag2 = "tr"
jbe/bsw@0 58 label_tag = "th"
jbe/bsw@0 59 body_tag = "tbody"
jbe/bsw@0 60 row_tag = "tr"
jbe/bsw@0 61 field_tag = "td"
jbe/bsw@0 62 elseif list_type == "ulli" then
jbe/bsw@0 63 outer_tag = "div"
jbe/bsw@0 64 head_tag = "div"
jbe/bsw@0 65 label_tag = "div"
jbe/bsw@0 66 body_tag = "ul"
jbe/bsw@0 67 row_tag = "li"
jbe/bsw@0 68 field_tag = "td"
jbe/bsw@0 69 elseif list_type == "div" then
jbe/bsw@0 70 outer_tag = "div"
jbe/bsw@0 71 head_tag = "div"
jbe/bsw@0 72 label_tag = "div"
jbe/bsw@0 73 body_tag = "div"
jbe/bsw@0 74 row_tag = "div"
jbe/bsw@0 75 field_tag = "div"
jbe/bsw@0 76 else
jbe/bsw@0 77 error("Unknown list type specified for ui.list{...}.")
jbe/bsw@0 78 end
jbe/bsw@0 79 outer_attr.class = outer_attr.class or "ui_list"
jbe/bsw@0 80 ui.container{
jbe/bsw@0 81 auto_args = args,
jbe/bsw@0 82 content = function()
jbe/bsw@0 83 ui.tag{
jbe/bsw@0 84 tag = outer_tag,
jbe/bsw@0 85 attr = outer_attr,
jbe/bsw@0 86 content = function()
jbe/bsw@0 87 if header_existent then
jbe/bsw@0 88 ui.tag{
jbe/bsw@0 89 tag = head_tag,
jbe/bsw@0 90 attr = { class = "ui_list_head" },
jbe/bsw@0 91 content = function()
jbe/bsw@0 92 local function header_content()
jbe/bsw@0 93 for idx, column in ipairs(columns) do
jbe/bsw@0 94 if column.ui_field_type ~= "hidden" then
jbe/bsw@0 95 local label_attr = table.new(column.label_attr)
jbe/bsw@0 96 label_attr.class =
jbe/bsw@0 97 label_attr.class or { class = "ui_list_label" }
jbe/bsw@0 98 ui.tag{
jbe/bsw@0 99 tag = label_tag,
jbe/bsw@0 100 attr = label_attr,
jbe/bsw@0 101 content = column.label or ""
jbe/bsw@0 102 }
jbe/bsw@0 103 end
jbe/bsw@0 104 end
jbe/bsw@0 105 end
jbe/bsw@0 106 if head_tag2 then
jbe/bsw@0 107 ui.tag{ tag = head_tag2, content = header_content }
jbe/bsw@0 108 else
jbe/bsw@0 109 header_content()
jbe/bsw@0 110 end
jbe/bsw@0 111 end
jbe/bsw@0 112 }
jbe/bsw@0 113 end
jbe/bsw@0 114 ui.tag{
jbe/bsw@0 115 tag = body_tag,
jbe/bsw@0 116 attr = { class = "ui_list_body" },
jbe/bsw@0 117 content = function()
jbe/bsw@0 118 for record_idx, record in ipairs(records) do
jbe/bsw@0 119 local row_class
jbe/bsw@0 120 if record_idx % 2 == 0 then
jbe/bsw@0 121 row_class = "ui_list_row ui_list_even"
jbe/bsw@0 122 else
jbe/bsw@0 123 row_class = "ui_list_row ui_list_odd"
jbe/bsw@0 124 end
jbe/bsw@0 125 ui.tag{
jbe/bsw@0 126 tag = row_tag,
jbe/bsw@0 127 attr = { class = row_class },
jbe/bsw@0 128 content = function()
jbe/bsw@0 129 local old_html_name_prefix, old_form_record
jbe/bsw@0 130 if prefix then
jbe/bsw@0 131 old_html_name_prefix = slot_state.html_name_prefix
jbe/bsw@0 132 old_form_record = slot_state.form_record
jbe/bsw@0 133 slot_state.html_name_prefix = prefix .. "[" .. record_idx .. "]"
jbe/bsw@0 134 slot_state.form_record = record
jbe/bsw@0 135 end
jbe/bsw@0 136 local first_column = true
jbe/bsw@0 137 for column_idx, column in ipairs(columns) do
jbe/bsw@0 138 if column.ui_field_type ~= "hidden" then
jbe/bsw@0 139 local field_attr = table.new(column.field_attr)
jbe/bsw@0 140 field_attr.class =
jbe/bsw@0 141 field_attr.class or { class = "ui_list_field" }
jbe/bsw@0 142 local field_content
jbe/bsw@0 143 if column.content then
jbe/bsw@0 144 field_content = function()
jbe@386 145 return column.content(record, record_idx)
jbe/bsw@0 146 end
jbe/bsw@0 147 elseif column.name then
jbe/bsw@0 148 if column.ui_field_type then
jbe/bsw@0 149 local ui_field_func = ui.field[column.ui_field_type]
jbe/bsw@0 150 if not ui_field_func then
jbe/bsw@0 151 error('Unknown ui_field_type "' .. column.ui_field_type .. '".')
jbe/bsw@0 152 end
jbe/bsw@0 153 local ui_field_options = table.new(column)
jbe/bsw@0 154 ui_field_options.record = record
jbe/bsw@0 155 ui_field_options.label = nil
jbe/bsw@0 156 if not prefix and ui_field_options.readonly == nil then
jbe/bsw@0 157 ui_field_options.readonly = true
jbe/bsw@0 158 end
jbe/bsw@0 159 field_content = function()
jbe/bsw@0 160 return ui.field[column.ui_field_type](ui_field_options)
jbe/bsw@0 161 end
jbe/bsw@0 162 elseif column.format then
jbe/bsw@0 163 local formatter = format[column.format]
jbe/bsw@0 164 if not formatter then
jbe/bsw@0 165 error('Unknown format "' .. column.format .. '".')
jbe/bsw@0 166 end
jbe/bsw@0 167 field_content = formatter(
jbe/bsw@0 168 record[column.name], column.format_options
jbe/bsw@0 169 )
jbe/bsw@0 170 else
jbe/bsw@0 171 field_content = function()
jbe/bsw@0 172 return ui.autofield{
jbe/bsw@0 173 record = record,
jbe/bsw@0 174 name = column.name,
jbe/bsw@0 175 html_name = column.html_name
jbe/bsw@0 176 }
jbe/bsw@0 177 end
jbe/bsw@0 178 end
jbe/bsw@0 179 else
jbe/bsw@0 180 error("Each column needs either a 'content' or a 'name'.")
jbe/bsw@0 181 end
jbe/bsw@0 182 local extended_field_content
jbe/bsw@0 183 if first_column then
jbe/bsw@0 184 first_column = false
jbe/bsw@0 185 extended_field_content = function()
jbe/bsw@0 186 for column_idx, column in ipairs(columns) do
jbe/bsw@0 187 if column.ui_field_type == "hidden" then
jbe/bsw@0 188 local ui_field_options = table.new(column)
jbe/bsw@0 189 ui_field_options.record = record
jbe/bsw@0 190 ui_field_options.label = nil
jbe/bsw@0 191 if not prefix and ui_field_options.readonly == nil then
jbe/bsw@0 192 ui_field_options.readonly = true
jbe/bsw@0 193 end
jbe/bsw@0 194 ui.field.hidden(ui_field_options)
jbe/bsw@0 195 end
jbe/bsw@0 196 end
jbe/bsw@0 197 field_content()
jbe/bsw@0 198 end
jbe/bsw@0 199 else
jbe/bsw@0 200 extended_field_content = field_content
jbe/bsw@0 201 end
jbe/bsw@0 202 ui.tag{
jbe/bsw@0 203 tag = field_tag,
jbe/bsw@0 204 attr = field_attr,
jbe/bsw@0 205 content = extended_field_content
jbe/bsw@0 206 }
jbe/bsw@0 207 end
jbe/bsw@0 208 end
jbe/bsw@0 209 if prefix then
jbe/bsw@0 210 slot_state.html_name_prefix = old_html_name_prefix
jbe/bsw@0 211 slot_state.form_record = old_form_record
jbe/bsw@0 212 end
jbe/bsw@0 213 end
jbe/bsw@0 214 }
jbe/bsw@0 215 end
jbe/bsw@0 216 end
jbe/bsw@0 217 }
jbe/bsw@0 218 end
jbe/bsw@0 219 }
jbe/bsw@0 220 end
jbe/bsw@0 221 }
jbe/bsw@0 222 if prefix then
jbe/bsw@0 223 -- ui.field.hidden is used instead of ui.hidden_field to suppress output in case of read-only mode.
jbe/bsw@0 224 ui.field.hidden{
jbe/bsw@0 225 html_name = prefix .. "[len]",
jbe/bsw@0 226 value = #records
jbe/bsw@0 227 }
jbe/bsw@0 228 end
jbe/bsw@0 229 end

Impressum / About Us