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_add = "Add entry"
|
||||||
cbi_del = "Remove entry"
|
cbi_del = "Remove entry"
|
||||||
cbi_invalid = "Error: Invalid input value"
|
cbi_invalid = "Error: Invalid input value"
|
||||||
|
cbi_missing = "Error: This field is mandatory"
|
||||||
cbi_addopt = "-- Additional Field --"
|
cbi_addopt = "-- Additional Field --"
|
||||||
cbi_optional = " (optional)"
|
cbi_optional = " (optional)"
|
||||||
cbi_sectempty = "This section contains no values yet"
|
cbi_sectempty = "This section contains no values yet"
|
||||||
|
|
|
@ -89,6 +89,7 @@ settings = "Settings"
|
||||||
start = "Start"
|
start = "Start"
|
||||||
static = "static"
|
static = "static"
|
||||||
statistics = "Statistics"
|
statistics = "Statistics"
|
||||||
|
submit = "Submit"
|
||||||
syslog = "System Log"
|
syslog = "System Log"
|
||||||
system = "System"
|
system = "System"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
cbi_add = "Eintrag hinzufügen"
|
cbi_add = "Eintrag hinzufügen"
|
||||||
cbi_del = "Eintrag entfernen"
|
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_addopt = "-- Zusätzliches Feld --"
|
||||||
cbi_sectempty = "Diese Sektion enthält noch keine Einträge"
|
cbi_sectempty = "Diese Sektion enthält noch keine Einträge"
|
||||||
cbi_manual = "-- benutzerdefiniert --"
|
cbi_manual = "-- benutzerdefiniert --"
|
||||||
|
|
|
@ -90,6 +90,7 @@ settings = "Einstellungen"
|
||||||
start = "Start"
|
start = "Start"
|
||||||
static = "statisch"
|
static = "statisch"
|
||||||
statistics = "Statistiken"
|
statistics = "Statistiken"
|
||||||
|
submit = "Absenden"
|
||||||
syslog = "Systemprotokoll"
|
syslog = "Systemprotokoll"
|
||||||
system = "System"
|
system = "System"
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@ local uci = luci.model.uci
|
||||||
local class = luci.util.class
|
local class = luci.util.class
|
||||||
local instanceof = luci.util.instanceof
|
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
|
-- Loads a CBI map from given file, creating an environment and returns it
|
||||||
function load(cbimap, ...)
|
function load(cbimap, ...)
|
||||||
|
@ -61,7 +64,7 @@ function load(cbimap, ...)
|
||||||
local maps = {func()}
|
local maps = {func()}
|
||||||
|
|
||||||
for i, map in ipairs(maps) do
|
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!")
|
error("CBI map returns no valid map object!")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@ -231,6 +234,68 @@ function Map.get(self, section, option)
|
||||||
end
|
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
|
AbstractSection
|
||||||
]]--
|
]]--
|
||||||
|
@ -534,12 +599,13 @@ function AbstractValue.__init__(self, map, option, ...)
|
||||||
self.map = map
|
self.map = map
|
||||||
self.config = map.config
|
self.config = map.config
|
||||||
self.tag_invalid = {}
|
self.tag_invalid = {}
|
||||||
|
self.tag_missing = {}
|
||||||
self.deps = {}
|
self.deps = {}
|
||||||
|
|
||||||
self.rmempty = false
|
self.rmempty = false
|
||||||
self.default = nil
|
self.default = nil
|
||||||
self.size = nil
|
self.size = nil
|
||||||
self.optional = false
|
self.optional = false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add a dependencie to another section field
|
-- Add a dependencie to another section field
|
||||||
|
@ -559,11 +625,20 @@ function AbstractValue.formvalue(self, section)
|
||||||
return luci.http.formvalue(key)
|
return luci.http.formvalue(key)
|
||||||
end
|
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)
|
function AbstractValue.parse(self, section)
|
||||||
local fvalue = self:formvalue(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
|
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
|
if not fvalue then
|
||||||
self.tag_invalid[section] = true
|
self.tag_invalid[section] = true
|
||||||
end
|
end
|
||||||
|
@ -573,6 +648,8 @@ function AbstractValue.parse(self, section)
|
||||||
else -- Unset the UCI or error
|
else -- Unset the UCI or error
|
||||||
if self.rmempty or self.optional then
|
if self.rmempty or self.optional then
|
||||||
self:remove(section)
|
self:remove(section)
|
||||||
|
elseif not fvalue or fvalue ~= cvalue then
|
||||||
|
self.tag_missing[section] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -618,6 +695,9 @@ function AbstractValue.validate(self, value)
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
AbstractValue.transform = AbstractValue.validate
|
||||||
|
|
||||||
|
|
||||||
-- Write to UCI
|
-- Write to UCI
|
||||||
function AbstractValue.write(self, section, value)
|
function AbstractValue.write(self, section, value)
|
||||||
return self.map:set(section, self.option, value)
|
return self.map:set(section, self.option, value)
|
||||||
|
|
|
@ -21,6 +21,9 @@ $Id$
|
||||||
<% if self.tag_invalid[section] then -%>
|
<% if self.tag_invalid[section] then -%>
|
||||||
<div class="cbi-error"><%:cbi_invalid%></div>
|
<div class="cbi-error"><%:cbi_invalid%></div>
|
||||||
<%- end %>
|
<%- end %>
|
||||||
|
<% if self.tag_missing[section] then -%>
|
||||||
|
<div class="cbi-error"><%:cbi_missing%></div>
|
||||||
|
<%- end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if #self.deps > 0 then -%>
|
<% 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")
|
luci.template.render("cbi/footer")
|
||||||
end
|
end
|
||||||
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