* Major CBI improvements
This commit is contained in:
parent
3f1064b919
commit
077db659bb
21 changed files with 260 additions and 116 deletions
7
Makefile
7
Makefile
|
@ -20,18 +20,11 @@ all: compile
|
||||||
dist-compile: compile dist
|
dist-compile: compile dist
|
||||||
dist-source: source dist
|
dist-source: source dist
|
||||||
|
|
||||||
examples-compile: compile examples
|
|
||||||
examples-source: source examples
|
|
||||||
|
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
cp src/ffluci/controller/* dist/ffluci/controller/ -R
|
cp src/ffluci/controller/* dist/ffluci/controller/ -R
|
||||||
cp src/ffluci/i18n/* dist/ffluci/i18n/
|
cp src/ffluci/i18n/* dist/ffluci/i18n/
|
||||||
cp src/ffluci/view/* dist/ffluci/view/ -R
|
cp src/ffluci/view/* dist/ffluci/view/ -R
|
||||||
cp src/ffluci/model/cbi/* dist/ffluci/model/cbi/ -R
|
cp src/ffluci/model/cbi/* dist/ffluci/model/cbi/ -R
|
||||||
|
|
||||||
examples:
|
|
||||||
cp examples/* dist/ -R
|
|
||||||
|
|
||||||
compile:
|
compile:
|
||||||
mkdir -p $(DIRECTORIES)
|
mkdir -p $(DIRECTORIES)
|
||||||
|
|
|
@ -4,13 +4,13 @@ config core main
|
||||||
|
|
||||||
|
|
||||||
config public contact
|
config public contact
|
||||||
option nickname -
|
option nickname
|
||||||
option name -
|
option name
|
||||||
option mail -
|
option mail
|
||||||
option phone -
|
option phone
|
||||||
option location -
|
option location
|
||||||
option geo -
|
option geo
|
||||||
option note -
|
option note
|
||||||
|
|
||||||
|
|
||||||
config event uci_oncommit
|
config event uci_oncommit
|
||||||
|
|
|
@ -179,27 +179,31 @@ code {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-section-create {
|
.cbi-section-remove {
|
||||||
margin-bottom: 3em;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-value-title {
|
.cbi-value-title {
|
||||||
line-height: 1.75em;
|
line-height: 1.75em;
|
||||||
|
width: 15em;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-value-field {
|
.cbi-value-field {
|
||||||
margin-left: 10em;
|
text-align: left;
|
||||||
text-align: center;
|
|
||||||
line-height: 1.75em;
|
line-height: 1.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-value-field input, .cbi-value-field select, .cbi-optionals select, .cbi-optionals input {
|
.cbi-value-field input, .cbi-value-field select,
|
||||||
|
.cbi-optionals select, .cbi-optionals input,
|
||||||
|
.cbi-section-remove input, .cbi-section-create input {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-value-description {
|
.cbi-value-description {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-form-separator {
|
.cbi-form-separator {
|
||||||
|
@ -211,6 +215,7 @@ code {
|
||||||
background: #f7f7f7;
|
background: #f7f7f7;
|
||||||
border: 1px solid #d7d7d7;
|
border: 1px solid #d7d7d7;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
margn-bottom: 0%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-section-node h3 {
|
.cbi-section-node h3 {
|
||||||
|
@ -220,10 +225,12 @@ code {
|
||||||
.cbi-error {
|
.cbi-error {
|
||||||
color: red;
|
color: red;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
font-size: 0.8em;
|
||||||
|
margin-bottom: 0.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-optionals {
|
.cbi-optionals {
|
||||||
margin-top: 2em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cbi-optionals option {
|
.cbi-optionals option {
|
||||||
|
|
36
contrib/media/cbi.js
Normal file
36
contrib/media/cbi.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
var cbi_d = {};
|
||||||
|
|
||||||
|
function cbi_d_add(field, target, value) {
|
||||||
|
if (!cbi_d[target]) {
|
||||||
|
cbi_d[target] = {};
|
||||||
|
}
|
||||||
|
if (!cbi_d[target][value]) {
|
||||||
|
cbi_d[target][value] = [];
|
||||||
|
}
|
||||||
|
cbi_d[target][value].push(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cbi_d_update(target) {
|
||||||
|
if (!cbi_d[target]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var x in cbi_d[target]) {
|
||||||
|
for (var i=0; i<cbi_d[target][x].length; i++) {
|
||||||
|
document.getElementById(cbi_d[target][x][i]).style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var t = document.getElementById(target);
|
||||||
|
if (t && t.value && cbi_d[target][t.value]) {
|
||||||
|
for (var i=0; i<cbi_d[target][t.value].length; i++) {
|
||||||
|
document.getElementById(cbi_d[target][t.value][i]).style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cbi_d_init() {
|
||||||
|
for (var x in cbi_d) {
|
||||||
|
cbi_d_update(x);
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ define Package/ffluci/install
|
||||||
$(INSTALL_DIR) $(1)/usr/lib/lua
|
$(INSTALL_DIR) $(1)/usr/lib/lua
|
||||||
$(INSTALL_DIR) $(1)/www/cgi-bin
|
$(INSTALL_DIR) $(1)/www/cgi-bin
|
||||||
$(INSTALL_DIR) $(1)/www/ffluci
|
$(INSTALL_DIR) $(1)/www/ffluci
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
$(CP) $(PKG_BUILD_DIR)/dist/* $(1)/usr/lib/lua/ -R
|
$(CP) $(PKG_BUILD_DIR)/dist/* $(1)/usr/lib/lua/ -R
|
||||||
$(CP) $(PKG_BUILD_DIR)/contrib/media $(1)/www/ffluci/ -R
|
$(CP) $(PKG_BUILD_DIR)/contrib/media $(1)/www/ffluci/ -R
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/ffluci $(1)/www/cgi-bin
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/ffluci $(1)/www/cgi-bin
|
||||||
|
|
|
@ -218,7 +218,6 @@ function AbstractSection.parse_optionals(self, section)
|
||||||
for k,v in ipairs(self.children) do
|
for k,v in ipairs(self.children) do
|
||||||
if v.optional and not v:cfgvalue(section) then
|
if v.optional and not v:cfgvalue(section) then
|
||||||
if field == v.option then
|
if field == v.option then
|
||||||
self.map:set(section, field, v.default)
|
|
||||||
field = nil
|
field = nil
|
||||||
else
|
else
|
||||||
table.insert(self.optionals[section], v)
|
table.insert(self.optionals[section], v)
|
||||||
|
@ -328,18 +327,30 @@ end
|
||||||
TypedSection - A (set of) configuration section(s) defined by the type
|
TypedSection - A (set of) configuration section(s) defined by the type
|
||||||
addremove: Defines whether the user can add/remove sections of this type
|
addremove: Defines whether the user can add/remove sections of this type
|
||||||
anonymous: Allow creating anonymous sections
|
anonymous: Allow creating anonymous sections
|
||||||
valid: a list of names or a validation function for creating sections
|
validate: a validation function returning nil if the section is invalid
|
||||||
scope: a list of names or a validation function for editing sections
|
|
||||||
]]--
|
]]--
|
||||||
TypedSection = class(AbstractSection)
|
TypedSection = class(AbstractSection)
|
||||||
|
|
||||||
function TypedSection.__init__(self, ...)
|
function TypedSection.__init__(self, ...)
|
||||||
AbstractSection.__init__(self, ...)
|
AbstractSection.__init__(self, ...)
|
||||||
self.template = "cbi/tsection"
|
self.template = "cbi/tsection"
|
||||||
|
self.deps = {}
|
||||||
|
self.excludes = {}
|
||||||
|
|
||||||
self.anonymous = false
|
self.anonymous = false
|
||||||
self.valid = nil
|
end
|
||||||
self.scope = nil
|
|
||||||
|
-- Return all matching UCI sections for this TypedSection
|
||||||
|
function TypedSection.cfgsections(self)
|
||||||
|
local sections = {}
|
||||||
|
for k, v in pairs(self.map:get()) do
|
||||||
|
if v[".type"] == self.sectiontype then
|
||||||
|
if self:checkscope(k) then
|
||||||
|
sections[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return sections
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Creates a new section of this type with the given name (or anonymous)
|
-- Creates a new section of this type with the given name (or anonymous)
|
||||||
|
@ -357,6 +368,16 @@ function TypedSection.create(self, name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Limits scope to sections that have certain option => value pairs
|
||||||
|
function TypedSection.depends(self, option, value)
|
||||||
|
table.insert(self.deps, {option=option, value=value})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Excludes several sections by name
|
||||||
|
function TypedSection.exclude(self, field)
|
||||||
|
self.excludes[field] = true
|
||||||
|
end
|
||||||
|
|
||||||
function TypedSection.parse(self)
|
function TypedSection.parse(self)
|
||||||
if self.addremove then
|
if self.addremove then
|
||||||
-- Create
|
-- Create
|
||||||
|
@ -368,10 +389,17 @@ function TypedSection.parse(self)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if name then
|
if name then
|
||||||
name = ffluci.util.validate(name, self.valid)
|
-- Ignore if it already exists
|
||||||
|
if self:cfgvalue(name) then
|
||||||
|
name = nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
name = self:checkscope(name)
|
||||||
|
|
||||||
if not name then
|
if not name then
|
||||||
self.err_invalid = true
|
self.err_invalid = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if name and name:len() > 0 then
|
if name and name:len() > 0 then
|
||||||
self:create(name)
|
self:create(name)
|
||||||
end
|
end
|
||||||
|
@ -383,7 +411,7 @@ function TypedSection.parse(self)
|
||||||
name = ffluci.http.formvalue(crval)
|
name = ffluci.http.formvalue(crval)
|
||||||
if type(name) == "table" then
|
if type(name) == "table" then
|
||||||
for k,v in pairs(name) do
|
for k,v in pairs(name) do
|
||||||
if ffluci.util.validate(k, self.valid) then
|
if self:cfgvalue(k) and self:checkscope(k) then
|
||||||
self:remove(k)
|
self:remove(k)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -404,20 +432,37 @@ function TypedSection.render_children(self, section)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Return all matching UCI sections for this TypedSection
|
-- Verifies scope of sections
|
||||||
function TypedSection.cfgsections(self)
|
function TypedSection.checkscope(self, section)
|
||||||
local sections = {}
|
-- Check if we are not excluded
|
||||||
for k, v in pairs(self.map:get()) do
|
if self.excludes[section] then
|
||||||
if v[".type"] == self.sectiontype then
|
return nil
|
||||||
if ffluci.util.validate(k, self.scope) then
|
end
|
||||||
sections[k] = v
|
|
||||||
|
-- Check if at least one dependency is met
|
||||||
|
if #self.deps > 0 and self:cfgvalue(section) then
|
||||||
|
local stat = false
|
||||||
|
|
||||||
|
for k, v in ipairs(self.deps) do
|
||||||
|
if self:cfgvalue(section)[v.option] == v.value then
|
||||||
|
stat = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not stat then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return sections
|
|
||||||
|
return self:validate(section)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Dummy validate function
|
||||||
|
function TypedSection.validate(self, section)
|
||||||
|
return section
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
AbstractValue - An abstract Value Type
|
AbstractValue - An abstract Value Type
|
||||||
|
@ -437,14 +482,25 @@ 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.deps = {}
|
||||||
|
|
||||||
self.valid = nil
|
self.rmempty = false
|
||||||
self.depends = nil
|
self.default = nil
|
||||||
self.default = " "
|
|
||||||
self.size = nil
|
self.size = nil
|
||||||
self.optional = false
|
self.optional = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add a dependencie to another section field
|
||||||
|
function AbstractValue.depends(self, field, value)
|
||||||
|
table.insert(self.deps, {field=field, value=value})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return whether this object should be created
|
||||||
|
function AbstractValue.formcreated(self, section)
|
||||||
|
local key = "cbi.opt."..self.config.."."..section
|
||||||
|
return (ffluci.http.formvalue(key) == self.option)
|
||||||
|
end
|
||||||
|
|
||||||
-- Returns the formvalue for this object
|
-- Returns the formvalue for this object
|
||||||
function AbstractValue.formvalue(self, section)
|
function AbstractValue.formvalue(self, section)
|
||||||
local key = "cbid."..self.map.config.."."..section.."."..self.option
|
local key = "cbid."..self.map.config.."."..section.."."..self.option
|
||||||
|
@ -453,12 +509,8 @@ end
|
||||||
|
|
||||||
function AbstractValue.parse(self, section)
|
function AbstractValue.parse(self, section)
|
||||||
local fvalue = self:formvalue(section)
|
local fvalue = self:formvalue(section)
|
||||||
if fvalue == "" then
|
|
||||||
fvalue = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if fvalue and fvalue ~= "" then -- If we have a form value, write it to UCI
|
||||||
if fvalue then -- If we have a form value, validate it and write it to UCI
|
|
||||||
fvalue = self:validate(fvalue)
|
fvalue = self:validate(fvalue)
|
||||||
if not fvalue then
|
if not fvalue then
|
||||||
self.tag_invalid[section] = true
|
self.tag_invalid[section] = true
|
||||||
|
@ -469,16 +521,14 @@ function AbstractValue.parse(self, section)
|
||||||
elseif ffluci.http.formvalue("cbi.submit") then -- Unset the UCI or error
|
elseif ffluci.http.formvalue("cbi.submit") then -- 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)
|
||||||
else
|
|
||||||
self.tag_invalid[section] = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Render if this value exists or if it is mandatory
|
-- Render if this value exists or if it is mandatory
|
||||||
function AbstractValue.render(self, section)
|
function AbstractValue.render(self, s)
|
||||||
if not self.optional or self:cfgvalue(section) then
|
if not self.optional or self:cfgvalue(s) or self:formcreated(s) then
|
||||||
ffluci.template.render(self.template, {self=self, section=section})
|
ffluci.template.render(self.template, {self=self, section=s})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -488,8 +538,8 @@ function AbstractValue.cfgvalue(self, section)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Validate the form value
|
-- Validate the form value
|
||||||
function AbstractValue.validate(self, val)
|
function AbstractValue.validate(self, value)
|
||||||
return ffluci.util.validate(val, self.valid)
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Write to UCI
|
-- Write to UCI
|
||||||
|
@ -529,7 +579,7 @@ function Value.validate(self, val)
|
||||||
val = nil
|
val = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
return ffluci.util.validate(val, self.valid, self.isnumber, self.isinteger)
|
return ffluci.util.validate(val, self.isnumber, self.isinteger)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -585,7 +635,7 @@ function ListValue.__init__(self, ...)
|
||||||
self.widget = "select"
|
self.widget = "select"
|
||||||
end
|
end
|
||||||
|
|
||||||
function ListValue.add_value(self, key, val)
|
function ListValue.value(self, key, val)
|
||||||
val = val or key
|
val = val or key
|
||||||
table.insert(self.keylist, tostring(key))
|
table.insert(self.keylist, tostring(key))
|
||||||
table.insert(self.vallist, tostring(val))
|
table.insert(self.vallist, tostring(val))
|
||||||
|
@ -618,7 +668,7 @@ function MultiValue.__init__(self, ...)
|
||||||
self.delimiter = " "
|
self.delimiter = " "
|
||||||
end
|
end
|
||||||
|
|
||||||
function MultiValue.add_value(self, key, val)
|
function MultiValue.value(self, key, val)
|
||||||
val = val or key
|
val = val or key
|
||||||
table.insert(self.keylist, tostring(key))
|
table.insert(self.keylist, tostring(key))
|
||||||
table.insert(self.vallist, tostring(val))
|
table.insert(self.vallist, tostring(val))
|
||||||
|
|
|
@ -5,6 +5,7 @@ menu = {
|
||||||
order = 20,
|
order = 20,
|
||||||
entries = {
|
entries = {
|
||||||
{action = "vlan", descr = "VLAN"},
|
{action = "vlan", descr = "VLAN"},
|
||||||
{action = "ifaces", descr = "Schnittstellen"}
|
{action = "ifaces", descr = "Schnittstellen"},
|
||||||
|
{action = "ptp", descr = "PPPoE / PPTP"},
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ function action_apply()
|
||||||
|
|
||||||
-- Collect files to be applied
|
-- Collect files to be applied
|
||||||
for i, line in ipairs(ffluci.util.split(changes)) do
|
for i, line in ipairs(ffluci.util.split(changes)) do
|
||||||
local r = line:match("^[^.]+")
|
local r = line:match("^-?([^.]+)")
|
||||||
if r then
|
if r then
|
||||||
apply[r] = true
|
apply[r] = true
|
||||||
end
|
end
|
||||||
|
@ -41,7 +41,7 @@ function action_revert()
|
||||||
|
|
||||||
-- Collect files to be reverted
|
-- Collect files to be reverted
|
||||||
for i, line in ipairs(ffluci.util.split(changes)) do
|
for i, line in ipairs(ffluci.util.split(changes)) do
|
||||||
local r = line:match("^[^.]+")
|
local r = line:match("^-?([^.]+)")
|
||||||
if r then
|
if r then
|
||||||
revert[r] = true
|
revert[r] = true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,32 @@
|
||||||
|
-- ToDo: Translate, Add descriptions and help texts
|
||||||
m = Map("network", "Schnittstellen")
|
m = Map("network", "Schnittstellen")
|
||||||
|
|
||||||
s = m:section(TypedSection, "interface")
|
s = m:section(TypedSection, "interface")
|
||||||
s.addremove = true
|
s.addremove = true
|
||||||
|
s:exclude("loopback")
|
||||||
|
s:depends("proto", "static")
|
||||||
|
s:depends("proto", "dhcp")
|
||||||
|
|
||||||
p = s:option(ListValue, "proto", "Protokoll")
|
p = s:option(ListValue, "proto", "Protokoll")
|
||||||
p:add_value("static", "statisch")
|
p:value("static", "statisch")
|
||||||
p:add_value("dhcp", "DHCP")
|
p:value("dhcp", "DHCP")
|
||||||
s:option(Value, "ipaddr", "IP-Adresse").optional = 1
|
|
||||||
s:option(Value, "netmask", "Netzmaske").optional = 1
|
s:option(Value, "ifname", "Schnittstelle")
|
||||||
s:option(Value, "gateway", "Gateway").optional = 1
|
|
||||||
s:option(Value, "dns", "DNS").optional = 1
|
s:option(Value, "ipaddr", "IP-Adresse")
|
||||||
s:option(Value, "mtu", "MTU").optional = 1
|
|
||||||
|
s:option(Value, "netmask", "Netzmaske"):depends("proto", "static")
|
||||||
|
|
||||||
|
gw = s:option(Value, "gateway", "Gateway")
|
||||||
|
gw:depends("proto", "static")
|
||||||
|
gw.rmempty = true
|
||||||
|
|
||||||
|
dns = s:option(Value, "dns", "DNS-Server")
|
||||||
|
dns:depends("proto", "static")
|
||||||
|
dns.optional = true
|
||||||
|
|
||||||
|
mtu = s:option(Value, "mtu", "MTU")
|
||||||
|
mtu.optional = true
|
||||||
|
mtu.isinteger = true
|
||||||
|
|
||||||
return m
|
return m
|
31
src/ffluci/model/cbi/admin_network/ptp.lua
Normal file
31
src/ffluci/model/cbi/admin_network/ptp.lua
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
-- ToDo: Translate, Add descriptions and help texts
|
||||||
|
m = Map("network", "Punkt-zu-Punkt Verbindungen")
|
||||||
|
|
||||||
|
s = m:section(TypedSection, "interface")
|
||||||
|
s.addremove = true
|
||||||
|
s:depends("proto", "pppoe")
|
||||||
|
s:depends("proto", "pptp")
|
||||||
|
|
||||||
|
p = s:option(ListValue, "proto", "Protokoll")
|
||||||
|
p:value("pppoe", "PPPoE")
|
||||||
|
p:value("pptp", "PPTP")
|
||||||
|
p.default = "pppoe"
|
||||||
|
|
||||||
|
s:option(Value, "ifname", "Schnittstelle")
|
||||||
|
|
||||||
|
s:option(Value, "username", "Benutzername")
|
||||||
|
s:option(Value, "password", "Passwort")
|
||||||
|
|
||||||
|
s:option(Value, "keepalive", "Keep-Alive").optional = true
|
||||||
|
|
||||||
|
s:option(Value, "demand", "Dial on Demand (idle time)").optional = true
|
||||||
|
|
||||||
|
srv = s:option(Value, "server", "PPTP-Server")
|
||||||
|
srv:depends("proto", "pptp")
|
||||||
|
srv.optional = true
|
||||||
|
|
||||||
|
mtu = s:option(Value, "mtu", "MTU")
|
||||||
|
mtu.optional = true
|
||||||
|
mtu.isinteger = true
|
||||||
|
|
||||||
|
return m
|
|
@ -1,12 +1,10 @@
|
||||||
|
-- ToDo: Autodetect things, maybe use MultiValue instead, Translate, Add descriptions
|
||||||
m = Map("network", "VLAN", "Konfguriert den Switch des Routers.")
|
m = Map("network", "VLAN", "Konfguriert den Switch des Routers.")
|
||||||
|
|
||||||
s = m:section(TypedSection, "switch")
|
s = m:section(TypedSection, "switch")
|
||||||
|
|
||||||
-- ToDo: Autodetect things, maybe use MultiValue instead
|
|
||||||
for i = 0, 15 do
|
for i = 0, 15 do
|
||||||
local c = s:option(Value, "vlan"..i, "vlan"..i)
|
s:option(Value, "vlan"..i, "vlan"..i).optional = true
|
||||||
c.default = "5"
|
|
||||||
c.optional = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
|
@ -7,6 +7,9 @@ is comparable to the syntax of the uci application
|
||||||
|
|
||||||
Any return value of false or nil can be interpreted as an error
|
Any return value of false or nil can be interpreted as an error
|
||||||
|
|
||||||
|
|
||||||
|
ToDo: Reimplement in Lua
|
||||||
|
|
||||||
FileId:
|
FileId:
|
||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- Validates a variable
|
-- Validates a variable
|
||||||
function validate(value, valid, cast_number, cast_int)
|
function validate(value, cast_number, cast_int)
|
||||||
if cast_number or cast_int then
|
if cast_number or cast_int then
|
||||||
value = tonumber(value)
|
value = tonumber(value)
|
||||||
end
|
end
|
||||||
|
@ -212,15 +212,6 @@ function validate(value, valid, cast_number, cast_int)
|
||||||
value = nil
|
value = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if type(valid) == "function" then
|
|
||||||
value = valid(value)
|
|
||||||
elseif type(valid) == "table" then
|
|
||||||
if not contains(valid, value) then
|
|
||||||
value = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<input type="submit" value="<%:save Speichern%>" />
|
<input type="submit" value="<%:save Speichern%>" />
|
||||||
<input type="reset" value="<%:reset Zurücksetzen%>" />
|
<input type="reset" value="<%:reset Zurücksetzen%>" />
|
||||||
|
<script type="text/javascript">cbi_d_init();</script>
|
||||||
</form>
|
</form>
|
||||||
<%+footer%>
|
<%+footer%>
|
|
@ -1,10 +1,11 @@
|
||||||
<div class="cbi-value">
|
<div class="cbi-value" id="cbi-<%=self.config.."-"..section.."-"..self.option%>">
|
||||||
<div class="left">
|
<div class="cbi-value-title left"><%=self.title%></div>
|
||||||
<div class="cbi-value-title"><%=self.title%></div>
|
|
||||||
<div class="cbi-value-description"><%=self.description%></div>
|
|
||||||
</div>
|
|
||||||
<div class="cbi-value-field">
|
<div class="cbi-value-field">
|
||||||
<input type="checkbox" name="cbid.<%=self.config.."."..section.."."..self.option%>"<% if self:cfgvalue(section) == self.enabled then %> checked="checked"<% end %> value="1" />
|
<input onchange="cbi_d_update(this.id)" type="checkbox" id="cbid.<%=self.config.."."..section.."."..self.option%>" name="cbid.<%=self.config.."."..section.."."..self.option%>"<% if self:cfgvalue(section) == self.enabled then %> checked="checked"<% end %> value="1" />
|
||||||
|
<div class="cbi-value-description inline"><%=self.description%></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
</div>
|
||||||
</div>
|
<% if #self.deps > 0 then %><script type="text/javascript">
|
||||||
|
<% for j, d in ipairs(self.deps) do %>cbi_d_add("cbi-<%=self.config.."-"..section.."-"..self.option%>", "cbid.<%=self.config.."."..section.."."..d.field%>", "<%=d.value%>");
|
||||||
|
<% end %>
|
||||||
|
</script><% end %>
|
|
@ -1,4 +1,5 @@
|
||||||
<%+header%>
|
<%+header%>
|
||||||
<form method="post" action="<%=os.getenv("REQUEST_URI")%>">
|
<form method="post" action="<%=os.getenv("REQUEST_URI")%>">
|
||||||
|
<script type="text/javascript" src="<%=media%>/cbi.js"></script>
|
||||||
<input type="hidden" name="cbi.submit" value="1" />
|
<input type="hidden" name="cbi.submit" value="1" />
|
||||||
<input type="submit" value="<%:cbi_save Speichern%>" class="hidden" />
|
<input type="submit" value="<%:cbi_save Speichern%>" class="hidden" />
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
<div class="cbi-value">
|
<div class="cbi-value" id="cbi-<%=self.config.."-"..section.."-"..self.option%>">
|
||||||
<div class="cbi-value-title left"><%=self.title%></div>
|
<div class="cbi-value-title left"><%=self.title%></div>
|
||||||
<div class="cbi-value-description right"><%=self.description%></div>
|
|
||||||
<div class="cbi-value-field">
|
<div class="cbi-value-field">
|
||||||
<% if self.widget == "select" then %>
|
<% if self.widget == "select" then %>
|
||||||
<select name="cbid.<%=self.config.."."..section.."."..self.option%>"<% if self.size then %> size="<%=self.size%>"<% end %>>
|
<select onchange="cbi_d_update(this.id)" id="cbid.<%=self.config.."."..section.."."..self.option%>" name="cbid.<%=self.config.."."..section.."."..self.option%>"<% if self.size then %> size="<%=self.size%>"<% end %>>
|
||||||
<%for i, key in pairs(self.keylist) do%>
|
<%for i, key in pairs(self.keylist) do%>
|
||||||
<option<% if self:cfgvalue(section) == key then %> selected="selected"<% end %> value="<%=key%>"><%=self.vallist[i]%></option>
|
<option<% if self:cfgvalue(section) == key then %> selected="selected"<% end %> value="<%=key%>"><%=self.vallist[i]%></option>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -16,6 +15,10 @@
|
||||||
<% if c == self.size then c = 0 %><br />
|
<% if c == self.size then c = 0 %><br />
|
||||||
<% end end %>
|
<% end end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<div class="cbi-value-description inline"><%=self.description%></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
</div>
|
||||||
</div>
|
<% if #self.deps > 0 then %><script type="text/javascript">
|
||||||
|
<% for j, d in ipairs(self.deps) do %>cbi_d_add("cbi-<%=self.config.."-"..section.."-"..self.option%>", "cbid.<%=self.config.."."..section.."."..d.field%>", "<%=d.value%>");
|
||||||
|
<% end %>
|
||||||
|
</script><% end %>
|
|
@ -1,11 +1,8 @@
|
||||||
<%
|
<%
|
||||||
local v = self:valuelist(section)
|
local v = self:valuelist(section)
|
||||||
%>
|
%>
|
||||||
<div class="cbi-value">
|
<div class="cbi-value" id="cbi-<%=self.config.."-"..section.."-"..self.option%>">
|
||||||
<div class="left">
|
<div class="cbi-value-title left"><%=self.title%></div>
|
||||||
<div class="cbi-value-title"><%=self.title%></div>
|
|
||||||
<div class="cbi-value-description"><%=self.description%></div>
|
|
||||||
</div>
|
|
||||||
<div class="cbi-value-field">
|
<div class="cbi-value-field">
|
||||||
<% if self.widget == "select" then %>
|
<% if self.widget == "select" then %>
|
||||||
<select multiple="multiple" name="cbid.<%=self.config.."."..section.."."..self.option%>[]"<% if self.size then %> size="<%=self.size%>"<% end %>>
|
<select multiple="multiple" name="cbid.<%=self.config.."."..section.."."..self.option%>[]"<% if self.size then %> size="<%=self.size%>"<% end %>>
|
||||||
|
@ -21,6 +18,10 @@ local v = self:valuelist(section)
|
||||||
<% if c == self.size then c = 0 %><br />
|
<% if c == self.size then c = 0 %><br />
|
||||||
<% end end %>
|
<% end end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<div class="cbi-value-description inline"><%=self.description%></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
</div>
|
||||||
</div>
|
<% if #self.deps > 0 then %><script type="text/javascript">
|
||||||
|
<% for j, d in ipairs(self.deps) do %>cbi_d_add("cbi-<%=self.config.."-"..section.."-"..self.option%>", "cbid.<%=self.config.."."..section.."."..d.field%>", "<%=d.value%>");
|
||||||
|
<% end %>
|
||||||
|
</script><% end %>
|
|
@ -2,27 +2,30 @@
|
||||||
<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>">
|
<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>">
|
||||||
<h2><%=self.title%></h2>
|
<h2><%=self.title%></h2>
|
||||||
<div class="cbi-section-descr"><%=self.description%></div>
|
<div class="cbi-section-descr"><%=self.description%></div>
|
||||||
|
<% if self.addremove then %><div class="cbi-section-remove">
|
||||||
|
<input type="submit" name="cbi.rns.<%=self.config%>.<%=self.section%>" value="<%:cbi_del Eintrag entfernen%>" />
|
||||||
|
</div><% end %>
|
||||||
<fieldset class="cbi-section-node">
|
<fieldset class="cbi-section-node">
|
||||||
<% self:render_children(self.section) %>
|
<% self:render_children(self.section) %>
|
||||||
<% if #self.optionals[self.section] > 0 or self.dynamic then %>
|
<% if #self.optionals[self.section] > 0 or self.dynamic then %>
|
||||||
<div class="cbi-optionals">
|
<div class="cbi-optionals">
|
||||||
|
<input type="submit" value="<%:cbi_addopt Feld hinzufügen%>" />
|
||||||
<% if self.dynamic then %>
|
<% if self.dynamic then %>
|
||||||
<input type="text" name="cbi.opt.<%=self.config%>.<%=self.section%>" />
|
<input type="text" name="cbi.opt.<%=self.config%>.<%=self.section%>" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<select name="cbi.opt.<%=self.config%>.<%=self.section%>">
|
<select name="cbi.opt.<%=self.config%>.<%=self.section%>">
|
||||||
<option><%:cbi_selopt *** Zusätzliche Parameter ***%></option>
|
<option><%:cbi_selopt *** Zusätzliche Parameter ***%></option>
|
||||||
<% for key, val in pairs(self.optionals[self.section]) do %>
|
<% for key, val in pairs(self.optionals[self.section]) do %>
|
||||||
<option value="<%=val.option%>"><%=val.title%></option>
|
<option id="cbi-<%=self.config.."-"..self.section.."-"..val.option%>" value="<%=val.option%>"><%=val.title%></option>
|
||||||
|
<% if #val.deps > 0 then %><script type="text/javascript">
|
||||||
|
<% for j, d in ipairs(val.deps) do %>cbi_d_add("cbi-<%=self.config.."-"..self.section.."-"..val.option%>", "cbid.<%=self.config.."."..self.section.."."..d.field%>", "<%=d.value%>");
|
||||||
|
<% end %>
|
||||||
|
</script><% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</select>
|
</select>
|
||||||
<% end %>
|
<% end %>
|
||||||
<input type="submit" value="<%:cbi_addopt Feld hinzufügen%>" />
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<br />
|
|
||||||
<% if self.addremove then %>
|
|
||||||
<input type="submit" name="cbi.rns.<%=self.config%>.<%=self.section%>" value="<%:cbi_del Eintrag entfernen%>" />
|
|
||||||
<% end %>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<% elseif self.addremove then %>
|
<% elseif self.addremove then %>
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
<h2><%=self.title%></h2>
|
<h2><%=self.title%></h2>
|
||||||
<div class="cbi-section-descr"><%=self.description%></div>
|
<div class="cbi-section-descr"><%=self.description%></div>
|
||||||
<% for k, v in pairs(self:cfgsections()) do%>
|
<% for k, v in pairs(self:cfgsections()) do%>
|
||||||
<fieldset class="cbi-section-node" id="cbi-<%=self.config%>-<%=k%>">
|
<% if self.addremove then %><div class="cbi-section-remove right">
|
||||||
|
<input type="submit" name="cbi.rts.<%=self.config%>.<%=k%>" value="<%:cbi_del Eintrag entfernen%>" />
|
||||||
|
</div><% end %>
|
||||||
<% if not self.anonymous then %><h3><%=k%></h3><% end %>
|
<% if not self.anonymous then %><h3><%=k%></h3><% end %>
|
||||||
|
<fieldset class="cbi-section-node" id="cbi-<%=self.config%>-<%=k%>">
|
||||||
<% self:render_children(k) %>
|
<% self:render_children(k) %>
|
||||||
<% if #self.optionals[k] > 0 or self.dynamic then %>
|
<% if #self.optionals[k] > 0 or self.dynamic then %>
|
||||||
<div class="cbi-optionals">
|
<div class="cbi-optionals">
|
||||||
|
@ -11,19 +14,19 @@
|
||||||
<input type="text" name="cbi.opt.<%=self.config%>.<%=k%>" />
|
<input type="text" name="cbi.opt.<%=self.config%>.<%=k%>" />
|
||||||
<% else %>
|
<% else %>
|
||||||
<select name="cbi.opt.<%=self.config%>.<%=k%>">
|
<select name="cbi.opt.<%=self.config%>.<%=k%>">
|
||||||
<option><%:cbi_selopt *** Zusätzliche Parameter ***%></option>
|
<option><%:cbi_addopt -- Feld --%></option>
|
||||||
<% for key, val in pairs(self.optionals[k]) do %>
|
<% for key, val in pairs(self.optionals[k]) do %>
|
||||||
<option value="<%=val.option%>"><%=val.title%></option>
|
<option id="cbi-<%=self.config.."-"..k.."-"..val.option%>" value="<%=val.option%>"><%=val.title%></option>
|
||||||
|
<% if #val.deps > 0 then %><script type="text/javascript">
|
||||||
|
<% for j, d in ipairs(val.deps) do %>cbi_d_add("cbi-<%=self.config.."-"..k.."-"..val.option%>", "cbid.<%=self.config.."."..k.."."..d.field%>", "<%=d.value%>");
|
||||||
|
<% end %>
|
||||||
|
</script><% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</select>
|
</select>
|
||||||
<% end %>
|
<% end %>
|
||||||
<input type="submit" value="<%:cbi_addopt Feld hinzufügen%>" />
|
<input type="submit" value="<%:add hinzufügen%>" />
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<br />
|
|
||||||
<% if self.addremove then %>
|
|
||||||
<input type="submit" name="cbi.rts.<%=self.config%>.<%=k%>" value="<%:cbi_del Eintrag entfernen%>" />
|
|
||||||
<% end %>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<br />
|
<br />
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<div class="cbi-value">
|
<div class="cbi-value clear" id="cbi-<%=self.config.."-"..section.."-"..self.option%>">
|
||||||
<div class="cbi-value-title left"><%=self.title%></div>
|
<div class="cbi-value-title left"><%=self.title%></div>
|
||||||
<div class="cbi-value-description right"><%=self.description%></div>
|
|
||||||
<div class="cbi-value-field">
|
<div class="cbi-value-field">
|
||||||
<input type="text" <% if self.size then %>size="<%=self.size%>" <% end %><% if self.maxlength then %>maxlength="<%=self.maxlength%>" <% end %>name="cbid.<%=self.config.."."..section.."."..self.option%>" value="<%=(self:cfgvalue(section) or "")%>" />
|
<input type="text" onchange="cbi_d_update(this.id)" <% if self.size then %>size="<%=self.size%>" <% end %><% if self.maxlength then %>maxlength="<%=self.maxlength%>" <% end %>name="cbid.<%=self.config.."."..section.."."..self.option%>" value="<%=(self:cfgvalue(section) or "")%>" />
|
||||||
|
<div class="cbi-value-description inline"><%=self.description%></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
|
||||||
<% if self.tag_invalid[section] then %><div class="cbi-error"><%:cbi_invalid Fehler: Ungültige Eingabe%></div><% end %>
|
<% if self.tag_invalid[section] then %><div class="cbi-error"><%:cbi_invalid Fehler: Ungültige Eingabe%></div><% end %>
|
||||||
</div>
|
</div>
|
||||||
|
<% if #self.deps > 0 then %><script type="text/javascript">
|
||||||
|
<% for j, d in ipairs(self.deps) do %>cbi_d_add("cbi-<%=self.config.."-"..section.."-"..self.option%>", "cbid.<%=self.config.."."..section.."."..d.field%>", "<%=d.value%>");
|
||||||
|
<% end %>
|
||||||
|
</script><% end %>
|
||||||
|
|
Loading…
Reference in a new issue