rev |
line source |
jbe/bsw@0
|
1 --[[--
|
jbe/bsw@0
|
2 ui.form{
|
jbe@56
|
3 record = record, -- optional record to be used
|
jbe@56
|
4 read_only = read_only, -- set to true, if form should be read-only (no submit button)
|
jbe@56
|
5 file_upload = file_upload, -- must be set to true, if form contains file upload element
|
jbe@56
|
6 external = external, -- external URL to be used as HTML form action
|
jbe@56
|
7 module = module, -- module name to be used for HTML form action
|
jbe@56
|
8 view = view, -- view name to be used for HTML form action
|
jbe@56
|
9 action = action, -- action name to be used for HTML form action
|
jbe/bsw@0
|
10 routing = {
|
jbe/bsw@0
|
11 default = { -- default routing for called action
|
jbe/bsw@0
|
12 mode = mode, -- "forward" or "redirect"
|
jbe/bsw@0
|
13 module = module, -- optional module name, defaults to current module
|
jbe/bsw@0
|
14 view = view, -- view name
|
jbe/bsw@0
|
15 id = id, -- optional id to be passed to the view
|
jbe@113
|
16 params = params, -- optional params to be passed to the view
|
jbe@113
|
17 anchor = anchor -- optional anchor for URL
|
jbe/bsw@0
|
18 },
|
jbe/bsw@0
|
19 ok = { ... }, -- routing when "ok" is returned by the called action
|
jbe/bsw@0
|
20 error = { ... }, -- routing when "error" is returned by the called action
|
jbe/bsw@0
|
21 ... = { ... } -- routing when "..." is returned by the called action
|
jbe@12
|
22 },
|
jbe@56
|
23 partial = { -- parameters for partial loading, see below
|
jbe@12
|
24 module = module,
|
jbe@12
|
25 view = view,
|
jbe@12
|
26 id = id,
|
jbe@12
|
27 params = params,
|
jbe@12
|
28 target = target
|
jbe@12
|
29 },
|
jbe/bsw@0
|
30 content = function()
|
jbe/bsw@0
|
31 ... -- code creating the contents of the form
|
jbe/bsw@0
|
32 end
|
jbe/bsw@0
|
33 }
|
jbe/bsw@0
|
34
|
jbe/bsw@0
|
35 This functions creates a web form, which encloses the content created by the given 'content' function. When a 'record' is given, ui.field.* helper functions will be able to automatically determine field values by using the given record. If 'read_only' is set to true, then a call of ui.submit{...} will be ignored, and ui.field.* helper functions will behave differently.
|
jbe/bsw@0
|
36
|
jbe@12
|
37 When passing a table as "partial" argument, AND if partial loading has been enabled by calling ui.enable_partial_loading(), then ui._partial_load_js is
|
jbe@12
|
38 used to create an onsubmit event. The "partial" setting table is passed to ui._partial_load_js as first argument. See ui._partial_load_js(...) for
|
jbe@12
|
39 further documentation.
|
jbe@12
|
40
|
jbe/bsw@0
|
41 --]]--
|
jbe/bsw@0
|
42
|
jbe/bsw@11
|
43 local function prepare_routing_params(params, routing, default_module)
|
jbe/bsw@11
|
44 local routing_default_given = false
|
jbe/bsw@11
|
45 if routing then
|
jbe/bsw@11
|
46 for status, settings in pairs(routing) do
|
jbe/bsw@11
|
47 if status == "default" then
|
jbe/bsw@11
|
48 routing_default_given = true
|
jbe/bsw@11
|
49 end
|
jbe/bsw@11
|
50 local module = settings.module or default_module or request.get_module()
|
jbe/bsw@11
|
51 assert(settings.mode, "No mode specified in routing entry.")
|
jbe/bsw@11
|
52 assert(settings.view, "No view specified in routing entry.")
|
jbe/bsw@11
|
53 params["_webmcp_routing." .. status .. ".mode"] = settings.mode
|
jbe/bsw@11
|
54 params["_webmcp_routing." .. status .. ".module"] = module
|
jbe/bsw@11
|
55 params["_webmcp_routing." .. status .. ".view"] = settings.view
|
jbe/bsw@11
|
56 params["_webmcp_routing." .. status .. ".id"] = settings.id
|
jbe@113
|
57 params["_webmcp_routing." .. status .. ".anchor"] = settings.anchor
|
jbe/bsw@11
|
58 if settings.params then
|
jbe/bsw@11
|
59 for key, value in pairs(settings.params) do
|
jbe/bsw@11
|
60 params["_webmcp_routing." .. status .. ".params." .. key] = value
|
jbe/bsw@11
|
61 end
|
jbe/bsw@11
|
62 end
|
jbe/bsw@11
|
63 end
|
jbe/bsw@11
|
64 end
|
jbe/bsw@11
|
65 if not routing_default_given then
|
jbe/bsw@11
|
66 params["_webmcp_routing.default.mode"] = "forward"
|
jbe/bsw@11
|
67 params["_webmcp_routing.default.module"] = request.get_module()
|
jbe/bsw@11
|
68 params["_webmcp_routing.default.view"] = request.get_view()
|
jbe/bsw@11
|
69 end
|
jbe/bsw@11
|
70 return params
|
jbe/bsw@11
|
71 end
|
jbe/bsw@11
|
72
|
jbe/bsw@0
|
73 function ui.form(args)
|
jbe/bsw@0
|
74 local args = args or {}
|
jbe/bsw@0
|
75 local slot_state = slot.get_state_table()
|
jbe@56
|
76 local old_record = slot_state.form_record
|
jbe@56
|
77 local old_readonly = slot_state.form_readonly
|
jbe@56
|
78 local old_file_upload = slot_state.form_file_upload
|
jbe/bsw@0
|
79 slot_state.form_record = args.record
|
jbe/bsw@0
|
80 if args.readonly then
|
jbe/bsw@0
|
81 slot_state.form_readonly = true
|
jbe/bsw@0
|
82 ui.container{ attr = args.attr, content = args.content }
|
jbe/bsw@0
|
83 else
|
jbe/bsw@0
|
84 slot_state.form_readonly = false
|
jbe/bsw@0
|
85 local params = table.new(args.params)
|
jbe/bsw@11
|
86 prepare_routing_params(params, args.routing, args.module)
|
jbe/bsw@0
|
87 params._webmcp_csrf_secret = request.get_csrf_secret()
|
jbe/bsw@0
|
88 local attr = table.new(args.attr)
|
bsw@58
|
89 if attr.enctype=="multipart/form-data" or args.file_upload then
|
jbe@56
|
90 slot_state.form_file_upload = true
|
jbe@56
|
91 if attr.enctype == nil then
|
jbe@56
|
92 attr.enctype = "multipart/form-data"
|
jbe@56
|
93 end
|
jbe@56
|
94 end
|
jbe/bsw@0
|
95 attr.action = encode.url{
|
jbe/bsw@0
|
96 external = args.external,
|
jbe/bsw@0
|
97 module = args.module or request.get_module(),
|
jbe/bsw@0
|
98 view = args.view,
|
jbe/bsw@0
|
99 action = args.action,
|
jbe/bsw@0
|
100 }
|
jbe/bsw@0
|
101 attr.method = args.method and string.upper(args.method) or "POST"
|
jbe/bsw@11
|
102 if ui.is_partial_loading_enabled() and args.partial then
|
jbe/bsw@11
|
103 attr.onsubmit = slot.use_temporary(function()
|
jbe/bsw@11
|
104 local partial_mode = "form_normal"
|
jbe/bsw@11
|
105 if args.action then
|
jbe/bsw@11
|
106 partial_mode = "form_action"
|
jbe/bsw@11
|
107 slot.put(
|
jbe/bsw@11
|
108 'var element; ',
|
jbe/bsw@11
|
109 'var formElements = []; ',
|
jbe/bsw@11
|
110 'for (var i=0; i<this.elements.length; i++) { ',
|
jbe/bsw@11
|
111 'formElements[formElements.length] = this.elements[i]; ',
|
jbe/bsw@11
|
112 '} ',
|
jbe/bsw@11
|
113 'for (i=0; i<formElements.length; i++) { ',
|
jbe/bsw@11
|
114 'element = formElements[i]; ',
|
jbe/bsw@11
|
115 'if (element.name.search(/^_webmcp_routing\\./) >= 0) { ',
|
jbe/bsw@11
|
116 'element.parentNode.removeChild(element); ',
|
jbe/bsw@11
|
117 '} ',
|
jbe/bsw@11
|
118 '}'
|
jbe/bsw@11
|
119 )
|
jbe/bsw@11
|
120 local routing_params = {}
|
jbe/bsw@11
|
121 prepare_routing_params(
|
jbe/bsw@11
|
122 routing_params,
|
jbe/bsw@11
|
123 args.partial.routing,
|
jbe/bsw@11
|
124 args.partial.module
|
jbe/bsw@11
|
125 )
|
jbe/bsw@11
|
126 for key, value in pairs(routing_params) do
|
jbe/bsw@11
|
127 slot.put(
|
jbe/bsw@11
|
128 ' ',
|
jbe/bsw@11
|
129 'element = document.createElement("input"); ',
|
jbe/bsw@11
|
130 'element.setAttribute("type", "hidden"); ',
|
jbe/bsw@11
|
131 'element.setAttribute("name", ', encode.json(key), '); ',
|
jbe/bsw@11
|
132 'element.setAttribute("value", ', encode.json(value), '); ',
|
jbe/bsw@11
|
133 'this.appendChild(element);'
|
jbe/bsw@11
|
134 )
|
jbe/bsw@11
|
135 end
|
jbe/bsw@11
|
136 slot.put(' ')
|
jbe/bsw@11
|
137 end
|
jbe/bsw@11
|
138 slot.put(ui._partial_load_js(args.partial, partial_mode))
|
jbe/bsw@11
|
139 end)
|
jbe/bsw@11
|
140 end
|
jbe/bsw@0
|
141 if slot_state.form_opened then
|
jbe/bsw@0
|
142 error("Cannot open a non-readonly form inside a non-readonly form.")
|
jbe/bsw@0
|
143 end
|
jbe/bsw@0
|
144 slot_state.form_opened = true
|
jbe/bsw@0
|
145 ui.tag {
|
jbe/bsw@0
|
146 tag = "form",
|
jbe/bsw@0
|
147 attr = attr,
|
jbe/bsw@0
|
148 content = function()
|
jbe/bsw@0
|
149 if args.id then
|
jbe/bsw@0
|
150 ui.hidden_field{ name = "_webmcp_id", value = args.id }
|
jbe/bsw@0
|
151 end
|
jbe/bsw@0
|
152 for key, value in pairs(params) do
|
jbe/bsw@0
|
153 ui.hidden_field{ name = key, value = value }
|
jbe/bsw@0
|
154 end
|
jbe/bsw@0
|
155 if args.content then
|
jbe/bsw@0
|
156 args.content()
|
jbe/bsw@0
|
157 end
|
jbe/bsw@0
|
158 end
|
jbe/bsw@0
|
159 }
|
jbe/bsw@0
|
160 slot_state.form_opened = false
|
jbe/bsw@0
|
161 end
|
jbe@56
|
162 slot_state.form_file_upload = old_file_upload
|
jbe@56
|
163 slot_state.form_readonly = old_readonly
|
jbe@56
|
164 slot_state.form_record = old_record
|
jbe/bsw@0
|
165 end
|