webmcp

view framework/env/ui/form.lua @ 58:e2b8f9dcc4a6

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

Impressum / About Us