[luci] Please help with validating unique vlaues
Jo-Philipp Wich
xm at subsignal.org
Wed Feb 24 09:00:49 CET 2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi Chris.
Now it's getting a bit hairy :)
First a few words on the program flow:
When a CBI map is rendered after a form submit, the associated
controller calls m:parse() which triggers form value fetching and
validation across all sections within the map, each section in turn does
validation on each fields within it.
If one of the field validation functions fail, the whole map is flagged
invalid by setting .save = false on the map object.
When a validation error occurs on a per-field or per-section level, the
associated error handling sets the property .error to a table value to
flag the error condition in a specific field (or section) - this is used
by the templates later on to highlight failed options (for example make
them red and print an error text next to it).
The error structure looks like this:
.error = {
[section_id_1] = "Error message string",
[section_id_2] = "Another error message"
}
The format is the same for per-section and per-option errors. The
variables section_id_1 and section_id_2 are the uci identifiers of the
underlying section e.g. "lan" for "config interface lan" and
"cfg12ab23f" for "config foo" (anonymous section).
To complicate it further, sections of the type TypedSection are not 1:1
mapped to the CBI model, one TypeSection declaration may result in
multiple actual section blocks rendered in the form so you need to treat
it correctly when traversing the map->sections->options tree.
With that in mind, you can hijack the Map's .parse function to implement
some kind of global validation:
local utl = require "luci.util"
m = Map("config", ...)
function m.parse(self, ...) -- NB: "..." actually means ellipsis here
-- call the original parse implementation
Map.parse(self, ...)
-- do custom processing
local sobj
for _, sobj in ipairs(self.children) do
local sids
-- check section type
if utl.instanceof(sobj, NamedSection) then
-- this is a named section,
-- the uci id of this section is
-- stored in sobj.section
sids = { sobj.section }
elseif utl.instanceof(sobj, TypedSection) then
-- this is a typed section,
-- it may map to multiple uci ids
sids = sobj:cfgsections()
end
-- now validate the fields within this section
-- for each associated config section
local sid, fld
for _, sid in ipairs(sids) do
for _, fld in ipairs(sobj.children) do
-- get the value for a specific field in
-- a specific section
local val = fld:formvalue(sid)
-- do some custom checks on val,
-- e.g. compare against :cfgvalue(),
-- some global structure etc.
if not is_valid(val, other_stuff) then
-- failed, flag map (self == m)
self.save = false
-- create field error for
-- template highlight
fld.error = {
[sid] = "Error foobar"
}
end
end
end
end
end
~ JoW
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkuE3LEACgkQdputYINPTPOK0wCaAyJaSl8EbzH5kfnx/hz/KRCj
ZcgAn2hXEAka/Cl/9TuNZqeY39abdJZ5
=prtZ
-----END PGP SIGNATURE-----
More information about the luci
mailing list