webmcp

view framework/env/ui/list.lua @ 244:10275e753a22

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

Impressum / About Us