webmcp
annotate framework/env/ui/list.lua @ 506:83b3882dc31b
New functions moonhash.shake128(data, len, alphabet), moonhash.shake256(data, len, alphabet)
Removed moonhash.shake128_128(...)
Removed moonhash.shake128_128(...)
author | jbe |
---|---|
date | Wed Aug 16 00:31:11 2017 +0200 (2017-08-16) |
parents | e057f8d3f716 |
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 |