| 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
 |