webmcp

annotate framework/env/ui/form.lua @ 56:36ebcae1cde3

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

Impressum / About Us