libs/cbi: Major Improvements
Added initial support for non-UCI-based forms (luci.cbi.SimpleForm) Minor API improvements Now correctly tagging "empty mandatory field" errors
This commit is contained in:
parent
b71825db91
commit
bdb4bbde13
8 changed files with 169 additions and 7 deletions
|
@ -1,6 +1,7 @@
|
|||
cbi_add = "Add entry"
|
||||
cbi_del = "Remove entry"
|
||||
cbi_invalid = "Error: Invalid input value"
|
||||
cbi_missing = "Error: This field is mandatory"
|
||||
cbi_addopt = "-- Additional Field --"
|
||||
cbi_optional = " (optional)"
|
||||
cbi_sectempty = "This section contains no values yet"
|
||||
|
|
|
@ -89,6 +89,7 @@ settings = "Settings"
|
|||
start = "Start"
|
||||
static = "static"
|
||||
statistics = "Statistics"
|
||||
submit = "Submit"
|
||||
syslog = "System Log"
|
||||
system = "System"
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
cbi_add = "Eintrag hinzufügen"
|
||||
cbi_del = "Eintrag entfernen"
|
||||
cbi_invalid = "Error: Ungültige Eingabe"
|
||||
cbi_invalid = "Fehler: Ungültige Eingabe"
|
||||
cbi_missing = "Fehler: Dieses Feld muss ausgefüllt werden"
|
||||
cbi_addopt = "-- Zusätzliches Feld --"
|
||||
cbi_sectempty = "Diese Sektion enthält noch keine Einträge"
|
||||
cbi_manual = "-- benutzerdefiniert --"
|
||||
|
|
|
@ -90,6 +90,7 @@ settings = "Einstellungen"
|
|||
start = "Start"
|
||||
static = "statisch"
|
||||
statistics = "Statistiken"
|
||||
submit = "Absenden"
|
||||
syslog = "Systemprotokoll"
|
||||
system = "System"
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@ local uci = luci.model.uci
|
|||
local class = luci.util.class
|
||||
local instanceof = luci.util.instanceof
|
||||
|
||||
FORM_NODATA = 0
|
||||
FORM_VALID = 1
|
||||
FORM_INVALID = -1
|
||||
|
||||
-- Loads a CBI map from given file, creating an environment and returns it
|
||||
function load(cbimap, ...)
|
||||
|
@ -61,7 +64,7 @@ function load(cbimap, ...)
|
|||
local maps = {func()}
|
||||
|
||||
for i, map in ipairs(maps) do
|
||||
if not instanceof(map, Map) then
|
||||
if not instanceof(map, Node) then
|
||||
error("CBI map returns no valid map object!")
|
||||
return nil
|
||||
end
|
||||
|
@ -231,6 +234,68 @@ function Map.get(self, section, option)
|
|||
end
|
||||
|
||||
|
||||
--[[
|
||||
SimpleForm - A Simple non-UCI form
|
||||
]]--
|
||||
SimpleForm = class(Node)
|
||||
|
||||
function SimpleForm.__init__(self, config, title, description, data)
|
||||
Node.__init__(self, title, description)
|
||||
self.config = config
|
||||
self.data = data or {}
|
||||
self.template = "cbi/simpleform"
|
||||
self.dorender = true
|
||||
end
|
||||
|
||||
function SimpleForm.parse(self, ...)
|
||||
Node.parse(self, 1, ...)
|
||||
|
||||
local valid = true
|
||||
for i, v in ipairs(self.children) do
|
||||
valid = valid and not v.tag_missing[1] and not v.tag_invalid[1]
|
||||
end
|
||||
|
||||
local state =
|
||||
not luci.http.formvalue("cbi.submit") and 0
|
||||
or valid and 1
|
||||
or -1
|
||||
|
||||
self.dorender = self:handle(state)
|
||||
end
|
||||
|
||||
function SimpleForm.render(self, ...)
|
||||
if self.dorender then
|
||||
Node.render(self, ...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Creates a child section
|
||||
function SimpleForm.field(self, class, ...)
|
||||
if instanceof(class, AbstractValue) then
|
||||
local obj = class(self, ...)
|
||||
self:append(obj)
|
||||
return obj
|
||||
else
|
||||
error("class must be a descendent of AbstractValue")
|
||||
end
|
||||
end
|
||||
|
||||
function SimpleForm.set(self, section, option, value)
|
||||
self.data[option] = value
|
||||
end
|
||||
|
||||
|
||||
function SimpleForm.del(self, section, option)
|
||||
self.data[option] = nil
|
||||
end
|
||||
|
||||
|
||||
function SimpleForm.get(self, section, option)
|
||||
return self.data[option]
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
AbstractSection
|
||||
]]--
|
||||
|
@ -534,12 +599,13 @@ function AbstractValue.__init__(self, map, option, ...)
|
|||
self.map = map
|
||||
self.config = map.config
|
||||
self.tag_invalid = {}
|
||||
self.tag_missing = {}
|
||||
self.deps = {}
|
||||
|
||||
self.rmempty = false
|
||||
self.default = nil
|
||||
self.size = nil
|
||||
self.optional = false
|
||||
self.rmempty = false
|
||||
self.default = nil
|
||||
self.size = nil
|
||||
self.optional = false
|
||||
end
|
||||
|
||||
-- Add a dependencie to another section field
|
||||
|
@ -559,11 +625,20 @@ function AbstractValue.formvalue(self, section)
|
|||
return luci.http.formvalue(key)
|
||||
end
|
||||
|
||||
function AbstractValue.additional(self, value)
|
||||
self.optional = value
|
||||
end
|
||||
|
||||
function AbstractValue.mandatory(self, value)
|
||||
self.rmempty = not value
|
||||
end
|
||||
|
||||
function AbstractValue.parse(self, section)
|
||||
local fvalue = self:formvalue(section)
|
||||
local cvalue = self:cfgvalue(section)
|
||||
|
||||
if fvalue and fvalue ~= "" then -- If we have a form value, write it to UCI
|
||||
fvalue = self:validate(fvalue)
|
||||
fvalue = self:transform(self:validate(fvalue))
|
||||
if not fvalue then
|
||||
self.tag_invalid[section] = true
|
||||
end
|
||||
|
@ -573,6 +648,8 @@ function AbstractValue.parse(self, section)
|
|||
else -- Unset the UCI or error
|
||||
if self.rmempty or self.optional then
|
||||
self:remove(section)
|
||||
elseif not fvalue or fvalue ~= cvalue then
|
||||
self.tag_missing[section] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -618,6 +695,9 @@ function AbstractValue.validate(self, value)
|
|||
return value
|
||||
end
|
||||
|
||||
AbstractValue.transform = AbstractValue.validate
|
||||
|
||||
|
||||
-- Write to UCI
|
||||
function AbstractValue.write(self, section, value)
|
||||
return self.map:set(section, self.option, value)
|
||||
|
|
|
@ -21,6 +21,9 @@ $Id$
|
|||
<% if self.tag_invalid[section] then -%>
|
||||
<div class="cbi-error"><%:cbi_invalid%></div>
|
||||
<%- end %>
|
||||
<% if self.tag_missing[section] then -%>
|
||||
<div class="cbi-error"><%:cbi_missing%></div>
|
||||
<%- end %>
|
||||
</div>
|
||||
|
||||
<% if #self.deps > 0 then -%>
|
||||
|
|
46
libs/cbi/luasrc/view/cbi/simpleform.htm
Normal file
46
libs/cbi/luasrc/view/cbi/simpleform.htm
Normal file
|
@ -0,0 +1,46 @@
|
|||
<%#
|
||||
LuCI - Lua Configuration Interface
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
|
||||
-%>
|
||||
|
||||
<form method="post" action="<%=luci.http.getenv("REQUEST_URI")%>">
|
||||
<div>
|
||||
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
|
||||
<input type="hidden" name="cbi.submit" value="1" />
|
||||
<input type="submit" value="<%:save%>" class="hidden" />
|
||||
</div>
|
||||
<div class="cbi-map" id="cbi-<%=self.config%>">
|
||||
<h1><%=self.title%></h1>
|
||||
<div class="cbi-map-descr"><%=self.description%></div>
|
||||
<fieldset class="cbi-section">
|
||||
<div class="cbi-section-node">
|
||||
<% self:render_children(1, scope or {}) %>
|
||||
</div>
|
||||
<br />
|
||||
</fieldset>
|
||||
<br />
|
||||
</div>
|
||||
<div>
|
||||
<%- if self.submit ~= false then %>
|
||||
<input type="submit" value="
|
||||
<%- if not self.submit then -%><%-:submit-%><%-else-%><%=self.submit%><%end%>
|
||||
" />
|
||||
<% end %>
|
||||
<%- if self.reset ~= false then %>
|
||||
<input type="reset" value="
|
||||
<%- if not self.reset then -%><%-:reset-%><%-else-%><%=self.reset%><%end%>
|
||||
" />
|
||||
<% end %>
|
||||
<script type="text/javascript">cbi_d_init();</script>
|
||||
</div>
|
||||
</form>
|
|
@ -461,3 +461,32 @@ function cbi(model)
|
|||
luci.template.render("cbi/footer")
|
||||
end
|
||||
end
|
||||
|
||||
--- Create a CBI form model dispatching target.
|
||||
-- @param model CBI form model tpo be rendered
|
||||
function form(model)
|
||||
require("luci.cbi")
|
||||
require("luci.template")
|
||||
|
||||
return function(...)
|
||||
local stat, maps = luci.util.copcall(luci.cbi.load, model, ...)
|
||||
if not stat then
|
||||
error500(maps)
|
||||
return true
|
||||
end
|
||||
|
||||
for i, res in ipairs(maps) do
|
||||
local stat, err = luci.util.copcall(res.parse, res)
|
||||
if not stat then
|
||||
error500(err)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
luci.template.render("header")
|
||||
for i, res in ipairs(maps) do
|
||||
res:render()
|
||||
end
|
||||
luci.template.render("footer")
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue