webmcp
view framework/env/ui/form.lua @ 11:d76a8857ba62
Added ui.partial and other functions, which allow partial content replacement using XMLHttpRequests; Image support for ui.link
Also includes following changes:
- Fix for rocketcgi library to accept POST data content-types, which contain additional charset information.
- Support arrays passed as params to encode.url (only for keys ending with "[]")
- Version information changed to "1.0.7"
Documentation for added functions is not yet complete.
Also includes following changes:
- Fix for rocketcgi library to accept POST data content-types, which contain additional charset information.
- Support arrays passed as params to encode.url (only for keys ending with "[]")
- Version information changed to "1.0.7"
Documentation for added functions is not yet complete.
author | jbe/bsw |
---|---|
date | Fri Feb 12 18:40:22 2010 +0100 (2010-02-12) |
parents | 9fdfb27f8e67 |
children | f3d3203cd2e4 |
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 external = external, -- external URL to be used as HTML form action
6 module = module, -- module name to be used for HTML form action
7 view = view, -- view name to be used for HTML form action
8 action = action, -- action name to be used for HTML form action
9 routing = {
10 default = { -- default routing for called action
11 mode = mode, -- "forward" or "redirect"
12 module = module, -- optional module name, defaults to current module
13 view = view, -- view name
14 id = id, -- optional id to be passed to the view
15 params = params -- optional params to be passed to the view
16 },
17 ok = { ... }, -- routing when "ok" is returned by the called action
18 error = { ... }, -- routing when "error" is returned by the called action
19 ... = { ... } -- routing when "..." is returned by the called action
20 }
21 content = function()
22 ... -- code creating the contents of the form
23 end
24 }
26 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.
28 --]]--
30 local function prepare_routing_params(params, routing, default_module)
31 local routing_default_given = false
32 if routing then
33 for status, settings in pairs(routing) do
34 if status == "default" then
35 routing_default_given = true
36 end
37 local module = settings.module or default_module or request.get_module()
38 assert(settings.mode, "No mode specified in routing entry.")
39 assert(settings.view, "No view specified in routing entry.")
40 params["_webmcp_routing." .. status .. ".mode"] = settings.mode
41 params["_webmcp_routing." .. status .. ".module"] = module
42 params["_webmcp_routing." .. status .. ".view"] = settings.view
43 params["_webmcp_routing." .. status .. ".id"] = settings.id
44 if settings.params then
45 for key, value in pairs(settings.params) do
46 params["_webmcp_routing." .. status .. ".params." .. key] = value
47 end
48 end
49 end
50 end
51 if not routing_default_given then
52 params["_webmcp_routing.default.mode"] = "forward"
53 params["_webmcp_routing.default.module"] = request.get_module()
54 params["_webmcp_routing.default.view"] = request.get_view()
55 end
56 return params
57 end
59 function ui.form(args)
60 local args = args or {}
61 local slot_state = slot.get_state_table()
62 local old_record = slot_state.form_record
63 local old_readonly = slot_state.form_readonly
64 slot_state.form_record = args.record
65 if args.readonly then
66 slot_state.form_readonly = true
67 ui.container{ attr = args.attr, content = args.content }
68 else
69 slot_state.form_readonly = false
70 local params = table.new(args.params)
71 prepare_routing_params(params, args.routing, args.module)
72 params._webmcp_csrf_secret = request.get_csrf_secret()
73 local attr = table.new(args.attr)
74 attr.action = encode.url{
75 external = args.external,
76 module = args.module or request.get_module(),
77 view = args.view,
78 action = args.action,
79 }
80 attr.method = args.method and string.upper(args.method) or "POST"
81 if ui.is_partial_loading_enabled() and args.partial then
82 attr.onsubmit = slot.use_temporary(function()
83 local partial_mode = "form_normal"
84 if args.action then
85 partial_mode = "form_action"
86 slot.put(
87 'var element; ',
88 'var formElements = []; ',
89 'for (var i=0; i<this.elements.length; i++) { ',
90 'formElements[formElements.length] = this.elements[i]; ',
91 '} ',
92 'for (i=0; i<formElements.length; i++) { ',
93 'element = formElements[i]; ',
94 'if (element.name.search(/^_webmcp_routing\\./) >= 0) { ',
95 'element.parentNode.removeChild(element); ',
96 '} ',
97 '}'
98 )
99 local routing_params = {}
100 prepare_routing_params(
101 routing_params,
102 args.partial.routing,
103 args.partial.module
104 )
105 for key, value in pairs(routing_params) do
106 slot.put(
107 ' ',
108 'element = document.createElement("input"); ',
109 'element.setAttribute("type", "hidden"); ',
110 'element.setAttribute("name", ', encode.json(key), '); ',
111 'element.setAttribute("value", ', encode.json(value), '); ',
112 'this.appendChild(element);'
113 )
114 end
115 slot.put(' ')
116 end
117 slot.put(ui._partial_load_js(args.partial, partial_mode))
118 end)
119 end
120 if slot_state.form_opened then
121 error("Cannot open a non-readonly form inside a non-readonly form.")
122 end
123 slot_state.form_opened = true
124 ui.tag {
125 tag = "form",
126 attr = attr,
127 content = function()
128 if args.id then
129 ui.hidden_field{ name = "_webmcp_id", value = args.id }
130 end
131 for key, value in pairs(params) do
132 ui.hidden_field{ name = key, value = value }
133 end
134 if args.content then
135 args.content()
136 end
137 end
138 }
139 slot_state.form_opened = false
140 end
141 slot_state.form_readonly = old_readonly
142 slot_state.form_record = old_record
143 end