| 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/bsw@0 | 23   content = function() | 
| jbe/bsw@0 | 24     ...                   -- code creating the contents of the form | 
| jbe/bsw@0 | 25   end | 
| jbe/bsw@0 | 26 } | 
| jbe/bsw@0 | 27 | 
| jbe/bsw@0 | 28 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 | 29 | 
| jbe/bsw@0 | 30 --]]-- | 
| jbe/bsw@0 | 31 | 
| jbe/bsw@11 | 32 local function prepare_routing_params(params, routing, default_module) | 
| jbe/bsw@11 | 33   local routing_default_given = false | 
| jbe/bsw@11 | 34   if routing then | 
| jbe/bsw@11 | 35     for status, settings in pairs(routing) do | 
| jbe/bsw@11 | 36       if status == "default" then | 
| jbe/bsw@11 | 37         routing_default_given = true | 
| jbe/bsw@11 | 38       end | 
| jbe/bsw@11 | 39       local module = settings.module or default_module or request.get_module() | 
| jbe/bsw@11 | 40       assert(settings.mode, "No mode specified in routing entry.") | 
| jbe/bsw@11 | 41       assert(settings.view, "No view specified in routing entry.") | 
| jbe/bsw@11 | 42       params["_webmcp_routing." .. status .. ".mode"]   = settings.mode | 
| jbe/bsw@11 | 43       params["_webmcp_routing." .. status .. ".module"] = module | 
| jbe/bsw@11 | 44       params["_webmcp_routing." .. status .. ".view"]   = settings.view | 
| jbe/bsw@11 | 45       params["_webmcp_routing." .. status .. ".id"]     = settings.id | 
| jbe@113 | 46       params["_webmcp_routing." .. status .. ".anchor"] = settings.anchor | 
| jbe/bsw@11 | 47       if settings.params then | 
| jbe/bsw@11 | 48         for key, value in pairs(settings.params) do | 
| jbe/bsw@11 | 49           params["_webmcp_routing." .. status .. ".params." .. key] = value | 
| jbe/bsw@11 | 50         end | 
| jbe/bsw@11 | 51       end | 
| jbe/bsw@11 | 52     end | 
| jbe/bsw@11 | 53   end | 
| jbe/bsw@11 | 54   if not routing_default_given then | 
| jbe/bsw@11 | 55     params["_webmcp_routing.default.mode"]   = "forward" | 
| jbe/bsw@11 | 56     params["_webmcp_routing.default.module"] = request.get_module() | 
| jbe/bsw@11 | 57     params["_webmcp_routing.default.view"]   = request.get_view() | 
| jbe/bsw@11 | 58   end | 
| jbe/bsw@11 | 59   return params | 
| jbe/bsw@11 | 60 end | 
| jbe/bsw@11 | 61 | 
| jbe/bsw@0 | 62 function ui.form(args) | 
| jbe/bsw@0 | 63   local args = args or {} | 
| jbe/bsw@0 | 64   local slot_state = slot.get_state_table() | 
| jbe@56 | 65   local old_record      = slot_state.form_record | 
| jbe@56 | 66   local old_readonly    = slot_state.form_readonly | 
| jbe@56 | 67   local old_file_upload = slot_state.form_file_upload | 
| jbe/bsw@0 | 68   slot_state.form_record = args.record | 
| jbe/bsw@0 | 69   if args.readonly then | 
| jbe/bsw@0 | 70     slot_state.form_readonly = true | 
| jbe/bsw@0 | 71     ui.container{ attr = args.attr, content = args.content } | 
| jbe/bsw@0 | 72   else | 
| jbe/bsw@0 | 73     slot_state.form_readonly = false | 
| jbe/bsw@0 | 74     local params = table.new(args.params) | 
| jbe/bsw@11 | 75     prepare_routing_params(params, args.routing, args.module) | 
| jbe/bsw@0 | 76     params._webmcp_csrf_secret = request.get_csrf_secret() | 
| jbe/bsw@0 | 77     local attr = table.new(args.attr) | 
| bsw@58 | 78     if attr.enctype=="multipart/form-data" or args.file_upload then | 
| jbe@56 | 79       slot_state.form_file_upload = true | 
| jbe@56 | 80       if attr.enctype == nil then | 
| jbe@56 | 81         attr.enctype = "multipart/form-data" | 
| jbe@56 | 82       end | 
| jbe@56 | 83     end | 
| jbe/bsw@0 | 84     attr.action = encode.url{ | 
| jbe/bsw@0 | 85       external  = args.external, | 
| jbe/bsw@0 | 86       module    = args.module or request.get_module(), | 
| jbe/bsw@0 | 87       view      = args.view, | 
| jbe/bsw@0 | 88       action    = args.action, | 
| jbe/bsw@0 | 89     } | 
| jbe/bsw@0 | 90     attr.method = args.method and string.upper(args.method) or "POST" | 
| jbe/bsw@0 | 91     if slot_state.form_opened then | 
| jbe/bsw@0 | 92       error("Cannot open a non-readonly form inside a non-readonly form.") | 
| jbe/bsw@0 | 93     end | 
| jbe/bsw@0 | 94     slot_state.form_opened = true | 
| jbe/bsw@0 | 95     ui.tag { | 
| jbe/bsw@0 | 96       tag     = "form", | 
| jbe/bsw@0 | 97       attr    = attr, | 
| jbe/bsw@0 | 98       content = function() | 
| jbe/bsw@0 | 99         if args.id then | 
| jbe/bsw@0 | 100           ui.hidden_field{ name = "_webmcp_id", value = args.id } | 
| jbe/bsw@0 | 101         end | 
| jbe/bsw@0 | 102         for key, value in pairs(params) do | 
| jbe/bsw@0 | 103           ui.hidden_field{ name = key, value = value } | 
| jbe/bsw@0 | 104         end | 
| jbe/bsw@0 | 105         if args.content then | 
| jbe/bsw@0 | 106           args.content() | 
| jbe/bsw@0 | 107         end | 
| jbe/bsw@0 | 108       end | 
| jbe/bsw@0 | 109     } | 
| jbe/bsw@0 | 110     slot_state.form_opened = false | 
| jbe/bsw@0 | 111   end | 
| jbe@56 | 112   slot_state.form_file_upload = old_file_upload | 
| jbe@56 | 113   slot_state.form_readonly    = old_readonly | 
| jbe@56 | 114   slot_state.form_record      = old_record | 
| jbe/bsw@0 | 115 end |