diff options
author | Jo-Philipp Wich <jo@mein.io> | 2019-11-03 20:49:31 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2019-11-03 20:49:31 +0100 |
commit | d5dff8f9a5ca85d197cbb6037f95053bc55941e5 (patch) | |
tree | eeb9271b96ba7b52bad777841ca4ebd452b1a2b0 /modules/luci-compat/luasrc/view/cbi | |
parent | 9e57fbb2c3f9c44cdf0a57e6fb9c1df32c84d52b (diff) |
treewide: move server side CBI support to luci-compat
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules/luci-compat/luasrc/view/cbi')
32 files changed, 1013 insertions, 0 deletions
diff --git a/modules/luci-compat/luasrc/view/cbi/browser.htm b/modules/luci-compat/luasrc/view/cbi/browser.htm new file mode 100644 index 0000000000..eb47ffafe6 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/browser.htm @@ -0,0 +1,10 @@ +<%+cbi/valueheader%> + +<input class="cbi-input-text" type="text"<%= + attr("id", cbid) .. + attr("name", cbid) .. + attr("value", self:cfgvalue(section) or self.default) .. + attr("data-browser", self.default_path or "") +%> /> + +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/button.htm b/modules/luci-compat/luasrc/view/cbi/button.htm new file mode 100644 index 0000000000..6ccba58f23 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/button.htm @@ -0,0 +1,7 @@ +<%+cbi/valueheader%> + <% if self:cfgvalue(section) ~= false then %> + <input class="cbi-button cbi-button-<%=self.inputstyle or "button" %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> /> + <% else %> + - + <% end %> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/cell_valuefooter.htm b/modules/luci-compat/luasrc/view/cbi/cell_valuefooter.htm new file mode 100644 index 0000000000..bdd6bc9687 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/cell_valuefooter.htm @@ -0,0 +1,2 @@ +</div> +</div> diff --git a/modules/luci-compat/luasrc/view/cbi/cell_valueheader.htm b/modules/luci-compat/luasrc/view/cbi/cell_valueheader.htm new file mode 100644 index 0000000000..4b70957543 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/cell_valueheader.htm @@ -0,0 +1,12 @@ +<%- + local title = luci.util.trim(striptags(self.title)) + local descr = luci.util.trim(striptags(self.description)) + local ftype = self.typename or (self.template and self.template:gsub("^.+/", "")) +-%> +<div class="td cbi-value-field<% if self.error and self.error[section] then %> cbi-value-error<% end %><% if self.password then %> nowrap<% end %>"<%= + attr("data-name", self.option) .. + ifattr(ftype and #ftype > 0, "data-type", ftype) .. + ifattr(title and #title > 0, "data-title", title, true) .. + ifattr(descr and #descr > 0, "data-description", descr, true) +%>> +<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>"> diff --git a/modules/luci-compat/luasrc/view/cbi/compound.htm b/modules/luci-compat/luasrc/view/cbi/compound.htm new file mode 100644 index 0000000000..12d02bb1d8 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/compound.htm @@ -0,0 +1 @@ +<%- self:render_children() %> diff --git a/modules/luci-compat/luasrc/view/cbi/delegator.htm b/modules/luci-compat/luasrc/view/cbi/delegator.htm new file mode 100644 index 0000000000..4fd19265d8 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/delegator.htm @@ -0,0 +1,24 @@ +<%- self.active:render() %> + <div class="cbi-page-actions"> + <input type="hidden" name="cbi.delg.current" value="<%=self.current%>" /> +<% for _, x in ipairs(self.chain) do %> + <input type="hidden" name="cbi.delg.path" value="<%=x%>" /> +<% end %> +<% if not self.disallow_pageactions then %> +<% if self.allow_finish and not self:get_next(self.current) then %> + <input class="cbi-button cbi-button-finish" type="submit" value="<%:Finish%>" /> +<% elseif self:get_next(self.current) then %> + <input class="cbi-button cbi-button-next" type="submit" value="<%:Next »%>" /> +<% end %> +<% if self.allow_cancel then %> + <input class="cbi-button cbi-button-cancel" type="submit" name="cbi.cancel" value="<%:Cancel%>" /> +<% end %> +<% if self.allow_reset then %> + <input class="cbi-button cbi-button-reset" type="reset" value="<%:Reset%>" /> +<% end %> +<% if self.allow_back and self:get_prev(self.current) then %> + <input class="cbi-button cbi-button-back" type="submit" name="cbi.delg.back" value="<%:« Back%>" /> +<% end %> +<% end %> + <script type="text/javascript">cbi_d_update();</script> + </div> diff --git a/modules/luci-compat/luasrc/view/cbi/dropdown.htm b/modules/luci-compat/luasrc/view/cbi/dropdown.htm new file mode 100644 index 0000000000..927ecf2396 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/dropdown.htm @@ -0,0 +1,19 @@ +<%+cbi/valueheader%> +<div<%=attr("data-ui-widget", luci.util.serialize_json({ + "Dropdown", self:cfgvalue(section) or self.default, self:choices(), { + id = cbid, + name = cbid, + sort = self.keylist, + multiple = self.multiple, + datatype = self.datatype, + optional = self.optional or self.rmempty, + readonly = self.readonly, + maxlength = self.maxlength, + placeholder = self.placeholder, + display_items = self.display or self.size or 3, + dropdown_items = self.dropdown or self.display or self.size or 5, + custom_placeholder = self.custom or + (self.multiple and translate("Enter custom values") or translate("Enter custom value")) + } +}))%>></div> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/dvalue.htm b/modules/luci-compat/luasrc/view/cbi/dvalue.htm new file mode 100644 index 0000000000..78e6f323d7 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/dvalue.htm @@ -0,0 +1,13 @@ +<%+cbi/valueheader%> +<% if self.href then %><a href="<%=self.href%>"><% end -%> + <% + local val = self:cfgvalue(section) or self.default or "" + if not self.rawhtml then + write(pcdata(val)) + else + write(val) + end + %> +<%- if self.href then %></a><%end%> +<input type="hidden" id="<%=cbid%>" value="<%=pcdata(self:cfgvalue(section) or self.default or "")%>" /> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/dynlist.htm b/modules/luci-compat/luasrc/view/cbi/dynlist.htm new file mode 100644 index 0000000000..2a3da67ff9 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/dynlist.htm @@ -0,0 +1,12 @@ +<%+cbi/valueheader%> +<div<%=attr("data-ui-widget", luci.util.serialize_json({ + "DynamicList", self:cfgvalue(section) or self.default, self:choices(), { + name = cbid, + size = self.size, + sort = self.keylist, + datatype = self.datatype, + optional = self.optional or self.rmempty, + placeholder = self.placeholder + } +}))%>></div> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/error.htm b/modules/luci-compat/luasrc/view/cbi/error.htm new file mode 100644 index 0000000000..75ec1082aa --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/error.htm @@ -0,0 +1,19 @@ +<div class="cbi-map" id="cbi-<%=self.config%>"> + <% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %> + <% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %> + + <p class="alert-message danger"> + <%: The configuration file could not be loaded due to the following error: %><br /> + <code><%=pcdata(self.error)%></code> + </p> + + <textarea name="cbi.source" style="width:100%; margin-bottom:1em" rows="<%=math.max(self.source:cmatch("\n"), 10)%>"><%=pcdata(self.source)%></textarea> + + <p class="alert-message"> + <%: Edit the raw configuration data above to fix any error and hit "Save" to reload the page. %> + </p> + + <div class="cbi-page-actions"> + <input class="cbi-button cbi-button-apply" type="submit" name="cbi.save" value="<%:Save%>" /> + </div> +</div> diff --git a/modules/luci-compat/luasrc/view/cbi/footer.htm b/modules/luci-compat/luasrc/view/cbi/footer.htm new file mode 100644 index 0000000000..ed632202ce --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/footer.htm @@ -0,0 +1,41 @@ +<% + local display_back = (redirect and not flow.hidebackbtn) + local display_skip = (flow.skip) + local display_apply = (not autoapply and not flow.hideapplybtn) + local display_save = (not flow.hidesavebtn) + local display_reset = (not flow.hideresetbtn) + + if pageaction and + (display_back or display_skip or display_apply or display_save or display_reset) + then + %><div class="cbi-page-actions"><% + + if display_back then + %><input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <% + end + + if display_skip then + %><input class="cbi-button cbi-button-skip" type="button" value="<%:Skip%>" onclick="cbi_submit(this, 'cbi.skip')" /> <% + end + + if display_apply then + %><input class="cbi-button cbi-button-apply" type="button" value="<%:Save & Apply%>" onclick="cbi_submit(this, 'cbi.apply')" /> <% + end + + if display_save then + %><input class="cbi-button cbi-button-save" type="submit" value="<%:Save%>" /> <% + end + + if display_reset then + %><input class="cbi-button cbi-button-reset" type="button" value="<%:Reset%>" onclick="location.href='<%=REQUEST_URI%>'" /> <% + end + + %></div><% + end +%> + +</form> + +<script type="text/javascript">cbi_init();</script> + +<%+footer%> diff --git a/modules/luci-compat/luasrc/view/cbi/full_valuefooter.htm b/modules/luci-compat/luasrc/view/cbi/full_valuefooter.htm new file mode 100644 index 0000000000..d4ad093efa --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/full_valuefooter.htm @@ -0,0 +1,12 @@ + <% if self.description and #self.description > 0 then -%> + <% if not luci.util.instanceof(self, luci.cbi.DynamicList) and (not luci.util.instanceof(self, luci.cbi.Flag) or self.orientation == "horizontal") then -%> + <br /> + <%- end %> + <div class="cbi-value-description"> + <%=self.description%> + </div> + <%- end %> + <%- if self.title and #self.title > 0 then -%> + </div> + <%- end -%> +</div> diff --git a/modules/luci-compat/luasrc/view/cbi/full_valueheader.htm b/modules/luci-compat/luasrc/view/cbi/full_valueheader.htm new file mode 100644 index 0000000000..1d9ebeba94 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/full_valueheader.htm @@ -0,0 +1,9 @@ +<div class="cbi-value<% if self.error and self.error[section] then %> cbi-value-error<% end %><% if self.last_child then %> cbi-value-last<% end %><% if self.password then %> nowrap<% end %>" id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>"> + <%- if self.title and #self.title > 0 then -%> + <label class="cbi-value-title"<%= attr("for", cbid) %>> + <%- if self.titleref then -%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=self.titleref%>"><%- end -%> + <%-=self.title-%> + <%- if self.titleref then -%></a><%- end -%> + </label> + <div class="cbi-value-field"> + <%- end -%> diff --git a/modules/luci-compat/luasrc/view/cbi/fvalue.htm b/modules/luci-compat/luasrc/view/cbi/fvalue.htm new file mode 100644 index 0000000000..7f975b95e1 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/fvalue.htm @@ -0,0 +1,12 @@ +<%+cbi/valueheader%> +<div<%=attr("data-ui-widget", luci.util.serialize_json({ + "Checkbox", self:cfgvalue(section) or self.default, { + id = cbid, + name = cbid, + readonly = self.readonly, + hiddenname = "cbi.cbe." .. self.config .. "." .. section .. "." .. self.option, + value_enabled = self.enabled or 1, + value_disabled = self.disabled or 0 + } +}))%>></div> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/header.htm b/modules/luci-compat/luasrc/view/cbi/header.htm new file mode 100644 index 0000000000..821fa3efae --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/header.htm @@ -0,0 +1,18 @@ +<%+header%> +<form method="post" name="cbi" action="<%=REQUEST_URI%>" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, '<%:Some fields are invalid, cannot save values!%>')"<%= + attr("data-strings", luci.util.serialize_json({ + label = { + choose = translate('-- Please choose --'), + custom = translate('-- custom --'), + }, + path = { + resource = resource, + browser = url("admin/filebrowser") + } + })) +%>> + <div> + <input type="hidden" name="token" value="<%=token%>" /> + <input type="hidden" name="cbi.submit" value="1" /> + <input type="submit" value="<%:Save%>" class="hidden" /> + </div> diff --git a/modules/luci-compat/luasrc/view/cbi/ipaddr.htm b/modules/luci-compat/luasrc/view/cbi/ipaddr.htm new file mode 100644 index 0000000000..1c924e1544 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/ipaddr.htm @@ -0,0 +1,27 @@ +<%+cbi/valueheader%> + <script type="text/javascript"> + function switchToCIDRList(ev) { + var input = ev.target.previousElementSibling, + usecidr = document.getElementById(input.id + '_usecidr'); + + ev.preventDefault(); + + usecidr.value = '1'; + cbi_d_update(); + } + </script> + <input data-update="change"<%= + attr("id", cbid) .. + attr("name", cbid) .. + attr("type", "text") .. + attr("class", "cbi-input-text") .. + attr("value", self:cfgvalue(section) or self.default) .. + ifattr(self.size, "size") .. + ifattr(self.placeholder, "placeholder") .. + ifattr(self.datatype, "data-type", self.datatype) .. + ifattr(self.datatype, "data-optional", self.optional or self.rmempty) .. + ifattr(self.combobox_manual, "data-manual", self.combobox_manual) .. + ifattr(#self.keylist > 0, "data-choices", { self.keylist, self.vallist }) + %> /><!-- + --><button class="cbi-button cbi-button-neutral" title="<%:Switch to CIDR list notation%>" aria-label="<%:Switch to CIDR list notation%>" onclick="switchToCIDRList(event)">…</button> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/lvalue.htm b/modules/luci-compat/luasrc/view/cbi/lvalue.htm new file mode 100644 index 0000000000..28141472f4 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/lvalue.htm @@ -0,0 +1,14 @@ +<%+cbi/valueheader%> +<div<%=attr("data-ui-widget", luci.util.serialize_json({ + "Select", self:cfgvalue(section) or self.default, self:choices(), { + id = cbid, + name = cbid, + size = self.size, + sort = self.keylist, + widget = self.widget, + datatype = self.datatype, + optional = self.optional, + placeholder = self.placeholder + } +}))%>></div> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/map.htm b/modules/luci-compat/luasrc/view/cbi/map.htm new file mode 100644 index 0000000000..cda4d3530c --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/map.htm @@ -0,0 +1,40 @@ +<%- if firstmap and messages then local msg; for _, msg in ipairs(messages) do -%> + <div class="alert-message warning"><%=pcdata(msg)%></div> +<%- end end -%> + +<div class="cbi-map" id="cbi-<%=self.config%>"> + <% if self.title and #self.title > 0 then %> + <h2 name="content"><%=self.title%></h2> + <% end %> + <% if self.description and #self.description > 0 then %> + <div class="cbi-map-descr"><%=self.description%></div> + <% end %> + <% if self.tabbed then %> + <div> + <% for i, section in ipairs(self.children) do + tab = section.section or section.sectiontype %> + <div class="cbi-tabcontainer"<%= + attr("id", "container.m-%s.%s" %{ self.config, tab }) .. + attr("data-tab", tab) .. + attr("data-tab-title", section.title or tab) + %>> + <% section:render() %> + </div> + <% end %> + </div> + + <% if not self.save then -%> + <div class="cbi-section-error"> + <% for _, section in ipairs(self.children) do %> + <% if section.error and section.error[section.section] then -%> + <ul><li> + <%:One or more invalid/required values on tab%>: <%=section.title or section.section or section.sectiontype%> + </li></ul> + <%- end %> + <% end %> + </div> + <%- end %> + <% else %> + <%- self:render_children() %> + <% end %> +</div> diff --git a/modules/luci-compat/luasrc/view/cbi/mvalue.htm b/modules/luci-compat/luasrc/view/cbi/mvalue.htm new file mode 100644 index 0000000000..1f4f4dbcc6 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/mvalue.htm @@ -0,0 +1,24 @@ +<%+cbi/valueheader%> +<% + local util = require "luci.util" + local values = {} + local value + for value in util.imatch(self:cfgvalue(section) or self.default) do + values[#values+1] = value + end +%> +<div<%=attr("data-ui-widget", luci.util.serialize_json({ + "Select", values, self:choices(), { + id = cbid, + name = cbid, + size = self.size, + sort = self.keylist, + multiple = true, + widget = self.widget, + datatype = self.datatype, + optional = self.optional or self.rmempty, + readonly = self.readonly, + placeholder = self.placeholder + } +}))%>></div> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/nsection.htm b/modules/luci-compat/luasrc/view/cbi/nsection.htm new file mode 100644 index 0000000000..14232e3d94 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/nsection.htm @@ -0,0 +1,29 @@ +<% if self:cfgvalue(self.section) then section = self.section %> + <div class="cbi-section"> + <% if self.title and #self.title > 0 then -%> + <legend><%=self.title%></legend> + <%- end %> + <% if self.description and #self.description > 0 then -%> + <div class="cbi-section-descr"><%=self.description%></div> + <%- end %> + <% if self.addremove then -%> + <div class="cbi-section-remove right"> + <input type="submit" class="cbi-button" name="cbi.rns.<%=self.config%>.<%=section%>" value="<%:Delete%>" /> + </div> + <%- end %> + <div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>"> + <%+cbi/ucisection%> + </div> + </div> +<% elseif self.addremove then %> + <% if self.template_addremove then include(self.template_addremove) else -%> + <div class="cbi-section" id="cbi-<%=self.config%>-<%=self.section%>"> + <% if self.title and #self.title > 0 then -%> + <legend><%=self.title%></legend> + <%- end %> + <div class="cbi-section-descr"><%=self.description%></div> + <input type="submit" class="cbi-button cbi-button-add" name="cbi.cns.<%=self.config%>.<%=self.section%>" value="<%:Add%>" /> + </div> + <%- end %> +<% end %> +<!-- /nsection --> diff --git a/modules/luci-compat/luasrc/view/cbi/nullsection.htm b/modules/luci-compat/luasrc/view/cbi/nullsection.htm new file mode 100644 index 0000000000..7230719d19 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/nullsection.htm @@ -0,0 +1,37 @@ +<div class="cbi-section"> + <% if self.title and #self.title > 0 then -%> + <legend><%=self.title%></legend> + <%- end %> + <% if self.description and #self.description > 0 then -%> + <div class="cbi-section-descr"><%=self.description%></div> + <%- end %> + <div class="cbi-section-node"> + <div id="cbi-<%=self.config%>-<%=tostring(self):sub(8)%>"> + <% self:render_children(1, scope or {}) %> + </div> + <% if self.error and self.error[1] then -%> + <div class="cbi-section-error"> + <ul><% for _, e in ipairs(self.error[1]) do -%> + <li> + <%- if e == "invalid" then -%> + <%:One or more fields contain invalid values!%> + <%- elseif e == "missing" then -%> + <%:One or more required fields have no value!%> + <%- else -%> + <%=pcdata(e)%> + <%- end -%> + </li> + <%- end %></ul> + </div> + <%- end %> + </div> +</div> +<%- + if type(self.hidden) == "table" then + for k, v in pairs(self.hidden) do +-%> + <input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" /> +<%- + end + end +%> diff --git a/modules/luci-compat/luasrc/view/cbi/simpleform.htm b/modules/luci-compat/luasrc/view/cbi/simpleform.htm new file mode 100644 index 0000000000..3e10724ec5 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/simpleform.htm @@ -0,0 +1,77 @@ +<% + if not self.embedded then + %><form method="post" enctype="multipart/form-data" action="<%=REQUEST_URI%>"> + <input type="hidden" name="token" value="<%=token%>" /> + <input type="hidden" name="cbi.submit" value="1" /><% + end + + %><div class="cbi-map" id="cbi-<%=self.config%>"><% + + if self.title and #self.title > 0 then + %><h2 name="content"><%=self.title%></h2><% + end + + if self.description and #self.description > 0 then + %><div class="cbi-map-descr"><%=self.description%></div><% + end + + self:render_children() + + %></div><% + + if self.message then + %><div class="alert-message notice"><%=self.message%></div><% + end + + if self.errmessage then + %><div class="alert-message warning"><%=self.errmessage%></div><% + end + + if not self.embedded then + if type(self.hidden) == "table" then + local k, v + for k, v in pairs(self.hidden) do + %><input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" /><% + end + end + + local display_back = (redirect) + local display_cancel = (self.cancel ~= false and self.on_cancel) + local display_skip = (self.flow and self.flow.skip) + local display_submit = (self.submit ~= false) + local display_reset = (self.reset ~= false) + + if display_back or display_cancel or display_skip or display_submit or display_reset then + %><div class="cbi-page-actions"><% + + if display_back then + %><input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" /> <% + end + + if display_cancel then + local label = pcdata(self.cancel or translate("Cancel")) + %><input class="cbi-button cbi-button-link" type="button" value="<%=label%>" onclick="cbi_submit(this, 'cbi.cancel')" /> <% + end + + if display_skip then + %><input class="cbi-button cbi-button-neutral" type="button" value="<%:Skip%>" onclick="cbi_submit(this, 'cbi.skip')" /> <% + end + + if display_submit then + local label = pcdata(self.submit or translate("Submit")) + %><input class="cbi-button cbi-button-save" type="submit" value="<%=label%>" /> <% + end + + if display_reset then + local label = pcdata(self.reset or translate("Reset")) + %><input class="cbi-button cbi-button-reset" type="reset" value="<%=label%>" /> <% + end + + %></div><% + end + + %></form><% + end +%> + +<script type="text/javascript">cbi_init();</script> diff --git a/modules/luci-compat/luasrc/view/cbi/tabcontainer.htm b/modules/luci-compat/luasrc/view/cbi/tabcontainer.htm new file mode 100644 index 0000000000..7fcb835783 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/tabcontainer.htm @@ -0,0 +1,14 @@ +<% for _, tab in ipairs(self.tab_names) do data = self.tabs[tab] %> + <div class="cbi-tabcontainer"<%= + attr("id", "container.%s.%s.%s" %{ self.config, section, tab }) .. + attr("data-tab", tab) .. + attr("data-tab-title", data.title) .. + attr("data-tab-active", tostring(tab == self.selected_tab)) + %>> + <% if data.description then %> + <div class="cbi-tab-descr"><%=data.description%></div> + <% end %> + + <% self:render_tab(tab, section, scope or {}) %> + </div> +<% end %> diff --git a/modules/luci-compat/luasrc/view/cbi/tblsection.htm b/modules/luci-compat/luasrc/view/cbi/tblsection.htm new file mode 100644 index 0000000000..11c2206d8c --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/tblsection.htm @@ -0,0 +1,203 @@ +<%- +local rowcnt = 0 + +function rowstyle() + rowcnt = rowcnt + 1 + if rowcnt % 2 == 0 then + return " cbi-rowstyle-1" + else + return " cbi-rowstyle-2" + end +end + +function width(o) + if o.width then + if type(o.width) == 'number' then + return ' style="width:%dpx"' % o.width + end + return ' style="width:%s"' % o.width + end + return '' +end + +local has_titles = false +local has_descriptions = false + +local anonclass = (not self.anonymous or self.sectiontitle) and "named" or "anonymous" +local titlename = ifattr(not self.anonymous or self.sectiontitle, "data-title", translate("Name")) + +local i, k +for i, k in pairs(self.children) do + if not k.typename then + k.typename = k.template and k.template:gsub("^.+/", "") or "" + end + + if not has_titles and k.title and #k.title > 0 then + has_titles = true + end + + if not has_descriptions and k.description and #k.description > 0 then + has_descriptions = true + end +end + +function render_titles() + if not has_titles then + return + end + + %><div class="tr cbi-section-table-titles <%=anonclass%>"<%=titlename%>><% + + local i, k + for i, k in ipairs(self.children) do + if not k.optional then + %><div class="th cbi-section-table-cell"<%= + width(k) .. attr('data-type', k.typename) %>><% + + if k.titleref then + %><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><% + end + + write(k.title) + + if k.titleref then + %></a><% + end + + %></div><% + end + end + + if self.sortable or self.extedit or self.addremove then + %><div class="th cbi-section-table-cell cbi-section-actions"></div><% + end + + %></div><% + + rowcnt = rowcnt + 1 +end + +function render_descriptions() + if not has_descriptions then + return + end + + %><div class="tr cbi-section-table-descr <%=anonclass%>"><% + + local i, k + for i, k in ipairs(self.children) do + if not k.optional then + %><div class="th cbi-section-table-cell"<%= + width(k) .. attr("data-type", k.typename) %>><% + + write(k.description) + + %></div><% + end + end + + if self.sortable or self.extedit or self.addremove then + %><div class="th cbi-section-table-cell cbi-section-actions"></div><% + end + + %></div><% + + rowcnt = rowcnt + 1 +end + +-%> + +<!-- tblsection --> +<div class="cbi-section cbi-tblsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>"> + <% if self.title and #self.title > 0 then -%> + <h3><%=self.title%></h3> + <%- end %> + <%- if self.sortable then -%> + <input type="hidden" id="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" name="cbi.sts.<%=self.config%>.<%=self.sectiontype%>" value="" /> + <%- end -%> + <div class="cbi-section-descr"><%=self.description%></div> + <div class="table cbi-section-table"> + <%- + render_titles() + render_descriptions() + + local isempty, section, i, k = true, nil, nil + for i, k in ipairs(self:cfgsections()) do + isempty = false + section = k + + local sectionname = striptags((type(self.sectiontitle) == "function") and self:sectiontitle(section) or k) + local sectiontitle = ifattr(sectionname and (not self.anonymous or self.sectiontitle), "data-title", sectionname, true) + local colorclass = (self.extedit or self.rowcolors) and rowstyle() or "" + local scope = { + valueheader = "cbi/cell_valueheader", + valuefooter = "cbi/cell_valuefooter" + } + -%> + <div class="tr cbi-section-table-row<%=colorclass%>" id="cbi-<%=self.config%>-<%=section%>"<%=sectiontitle%>> + <%- + local node + for k, node in ipairs(self.children) do + if not node.optional then + node:render(section, scope or {}) + end + end + -%> + + <%- if self.sortable or self.extedit or self.addremove then -%> + <div class="td cbi-section-table-cell nowrap cbi-section-actions"> + <div> + <%- if self.sortable then -%> + <input class="cbi-button cbi-button-up" type="button" value="<%:Up%>" onclick="return cbi_row_swap(this, true, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move up%>" /> + <input class="cbi-button cbi-button-down" type="button" value="<%:Down%>" onclick="return cbi_row_swap(this, false, 'cbi.sts.<%=self.config%>.<%=self.sectiontype%>')" title="<%:Move down%>" /> + <% end; if self.extedit then -%> + <input class="cbi-button cbi-button-edit" type="button" value="<%:Edit%>" + <%- if type(self.extedit) == "string" then + %> onclick="location.href='<%=self.extedit:format(section)%>'" + <%- elseif type(self.extedit) == "function" then + %> onclick="location.href='<%=self:extedit(section)%>'" + <%- end + %> alt="<%:Edit%>" title="<%:Edit%>" /> + <% end; if self.addremove then %> + <input class="cbi-button cbi-button-remove" type="submit" value="<%:Delete%>" onclick="this.form.cbi_state='del-section'; return true" name="cbi.rts.<%=self.config%>.<%=k%>" alt="<%:Delete%>" title="<%:Delete%>" /> + <%- end -%> + </div> + </div> + <%- end -%> + </div> + <%- end -%> + + <%- if isempty then -%> + <div class="tr cbi-section-table-row placeholder"> + <div class="td"><em><%:This section contains no values yet%></em></div> + </div> + <%- end -%> + </div> + + <% if self.error then %> + <div class="cbi-section-error"> + <ul><% for _, c in pairs(self.error) do for _, e in ipairs(c) do -%> + <li><%=pcdata(e):gsub("\n","<br />")%></li> + <%- end end %></ul> + </div> + <% end %> + + <%- if self.addremove then -%> + <% if self.template_addremove then include(self.template_addremove) else -%> + <div class="cbi-section-create cbi-tblsection-create"> + <% if self.anonymous then %> + <input class="cbi-button cbi-button-add" type="submit" value="<%:Add%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" title="<%:Add%>" /> + <% else %> + <% if self.invalid_cts then -%> + <div class="cbi-section-error"><%:Invalid%></div> + <%- end %> + <div> + <input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" data-type="uciname" data-optional="true" /> + </div> + <input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" /> + <% end %> + </div> + <%- end %> + <%- end -%> +</div> +<!-- /tblsection --> diff --git a/modules/luci-compat/luasrc/view/cbi/tsection.htm b/modules/luci-compat/luasrc/view/cbi/tsection.htm new file mode 100644 index 0000000000..8f3b7f0ffb --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/tsection.htm @@ -0,0 +1,52 @@ +<div class="cbi-section" id="cbi-<%=self.config%>-<%=self.sectiontype%>"> + <% if self.title and #self.title > 0 then -%> + <legend><%=self.title%></legend> + <%- end %> + <% if self.error_msg and #self.error_msg > 0 then -%> + <div class="cbi-section-error"> + <%=self.error_msg%> + </div> + <%- end %> + <% if self.description and #self.description > 0 then -%> + <div class="cbi-section-descr"><%=self.description%></div> + <%- end %> + <% local isempty = true for i, k in ipairs(self:cfgsections()) do -%> + <% if self.addremove then -%> + <div class="cbi-section-remove right"> + <input type="submit" name="cbi.rts.<%=self.config%>.<%=k%>" onclick="this.form.cbi_state='del-section'; return true" value="<%:Delete%>" class="cbi-button" /> + </div> + <%- end %> + + <%- section = k; isempty = false -%> + + <% if not self.anonymous then -%> + <h3><%=section:upper()%></h3> + <%- end %> + + <div class="cbi-section-node<% if self.tabs then %> cbi-section-node-tabbed<% end %>" id="cbi-<%=self.config%>-<%=section%>"> + <%+cbi/ucisection%> + </div> + <%- end %> + + <% if isempty then -%> + <em><%:This section contains no values yet%><br /><br /></em> + <%- end %> + + <% if self.addremove then -%> + <% if self.template_addremove then include(self.template_addremove) else -%> + <div class="cbi-section-create"> + <% if self.anonymous then -%> + <input type="submit" class="cbi-button cbi-button-add" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>.<%=section%>" value="<%:Add%>" /> + <%- else -%> + <% if self.invalid_cts then -%> + <div class="cbi-section-error"><%:Invalid%></div> + <%- end %> + <div> + <input type="text" class="cbi-section-create-name" id="cbi.cts.<%=self.config%>.<%=self.sectiontype%>." name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>." data-type="uciname" data-optional="true" /> + </div> + <input class="cbi-button cbi-button-add" type="submit" onclick="this.form.cbi_state='add-section'; return true" value="<%:Add%>" title="<%:Add%>" /> + <%- end %> + </div> + <%- end %> + <%- end %> +</div> diff --git a/modules/luci-compat/luasrc/view/cbi/tvalue.htm b/modules/luci-compat/luasrc/view/cbi/tvalue.htm new file mode 100644 index 0000000000..f3b12bd094 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/tvalue.htm @@ -0,0 +1,5 @@ +<%+cbi/valueheader%> + <textarea class="cbi-input-textarea" <% if not self.size then %> style="width: 100%"<% else %> cols="<%=self.size%>"<% end %> data-update="change"<%= attr("name", cbid) .. attr("id", cbid) .. ifattr(self.rows, "rows") .. ifattr(self.wrap, "wrap") .. ifattr(self.readonly, "readonly") %>> + <%-=pcdata(self:cfgvalue(section) or self.default)-%> + </textarea> +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/ucisection.htm b/modules/luci-compat/luasrc/view/cbi/ucisection.htm new file mode 100644 index 0000000000..8fa11d68f8 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/ucisection.htm @@ -0,0 +1,56 @@ +<%- + if type(self.hidden) == "table" then + for k, v in pairs(self.hidden) do +-%> + <input type="hidden" id="<%=k%>" name="<%=k%>" value="<%=pcdata(v)%>" /> +<%- + end + end +%> + +<% if self.tabs then %> + <%+cbi/tabcontainer%> +<% else %> + <% self:render_children(section, scope or {}) %> +<% end %> + +<% if self.error and self.error[section] then -%> + <div class="cbi-section-error" data-index="<%=#self.children + 1%>"> + <ul><% for _, e in ipairs(self.error[section]) do -%> + <li> + <%- if e == "invalid" then -%> + <%:One or more fields contain invalid values!%> + <%- elseif e == "missing" then -%> + <%:One or more required fields have no value!%> + <%- else -%> + <%=pcdata(e)%> + <%- end -%> + </li> + <%- end %></ul> + </div> +<%- end %> + +<% if self.optionals[section] and #self.optionals[section] > 0 or self.dynamic then %> + <div class="cbi-optionals" data-index="<%=#self.children + 1%>"> + <%- + if self.dynamic then + local keys, vals, name, opt = { }, { } + for name, opt in pairs(self.optionals[section]) do + keys[#keys+1] = name + vals[#vals+1] = opt.title + end + -%> + <input type="text" id="cbi.opt.<%=self.config%>.<%=section%>" name="cbi.opt.<%=self.config%>.<%=section%>" data-type="uciname" data-optional="true"<%= + ifattr(#keys > 0, "data-choices", luci.util.json_encode({keys, vals})) + %> /> + <%- else -%> + <select id="cbi.opt.<%=self.config%>.<%=section%>" name="cbi.opt.<%=self.config%>.<%=section%>" data-optionals="true"> + <option><%: -- Additional Field -- %></option> + <% for key, val in pairs(self.optionals[section]) do -%> + <option id="cbi-<%=self.config.."-"..section.."-"..val.option%>" value="<%=val.option%>" data-index="<%=val.index%>" data-depends="<%=pcdata(val:deplist2json(section))%>"><%=striptags(val.title)%></option> + <%- end %> + </select> + <%- end -%> + <input type="submit" class="cbi-button cbi-button-fieldadd" value="<%:Add%>" /> + </div> +<% end %> diff --git a/modules/luci-compat/luasrc/view/cbi/upload.htm b/modules/luci-compat/luasrc/view/cbi/upload.htm new file mode 100644 index 0000000000..e610495380 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/upload.htm @@ -0,0 +1,14 @@ +<%+cbi/valueheader%> + +<div<%=attr("data-ui-widget", luci.util.serialize_json({ + "FileUpload", self:cfgvalue(section) or self.default, { + id = cbid, + name = cbid, + show_hidden = self.show_hidden, + enable_remove = self.enable_remove, + enable_upload = self.enable_upload, + root_directory = "/" --self.root_directory + } +}))%>></div> + +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/value.htm b/modules/luci-compat/luasrc/view/cbi/value.htm new file mode 100644 index 0000000000..6060310b19 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/value.htm @@ -0,0 +1,35 @@ +<%+cbi/valueheader%> + +<% local choices = self:choices() + if choices then %> + <div<%=attr("data-ui-widget", luci.util.serialize_json({ + "Combobox", self:cfgvalue(section) or self.default, choices, { + id = cbid, + name = cbid, + size = self.size, + sort = self.keylist, + datatype = self.datatype, + optional = self.optional or self.rmempty, + readonly = self.readonly, + maxlength = self.maxlength, + placeholder = self.placeholder, + custom_placeholder = self.combobox_manual + } + }))%>></div> +<% else %> + <div<%=attr("data-ui-widget", luci.util.serialize_json({ + "Textfield", self:cfgvalue(section) or self.default, { + id = cbid, + name = cbid, + size = self.size, + datatype = self.datatype, + optional = self.optional or self.rmempty, + password = self.password, + readonly = self.readonly, + maxlength = self.maxlength, + placeholder = self.placeholder + } + }))%>></div> +<% end %> + +<%+cbi/valuefooter%> diff --git a/modules/luci-compat/luasrc/view/cbi/valuefooter.htm b/modules/luci-compat/luasrc/view/cbi/valuefooter.htm new file mode 100644 index 0000000000..805312e451 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/valuefooter.htm @@ -0,0 +1 @@ +<% include( valuefooter or "cbi/full_valuefooter" ) %> diff --git a/modules/luci-compat/luasrc/view/cbi/valueheader.htm b/modules/luci-compat/luasrc/view/cbi/valueheader.htm new file mode 100644 index 0000000000..761a54aed0 --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/valueheader.htm @@ -0,0 +1 @@ +<% include( valueheader or "cbi/full_valueheader" ) %> diff --git a/modules/luci-compat/luasrc/view/cbi/wireless_modefreq.htm b/modules/luci-compat/luasrc/view/cbi/wireless_modefreq.htm new file mode 100644 index 0000000000..eeb1d5c5cb --- /dev/null +++ b/modules/luci-compat/luasrc/view/cbi/wireless_modefreq.htm @@ -0,0 +1,173 @@ +<%+cbi/valueheader%> + +<script type="text/javascript">//<![CDATA[ + var freqlist = <%= luci.http.write_json(self.iwinfo.freqlist) %>; + var hwmodes = <%= luci.http.write_json(self.iwinfo.hwmodelist or {}) %>; + var htmodes = <%= luci.http.write_json(self.iwinfo.htmodelist) %>; + var acs = <%= luci.http.write_json(self.hostapd_acs or 0) %>; + + var channels = { + '11g': [ + 'auto', 'auto', true + ], + '11a': [ + 'auto', 'auto', true + ] + }; + + if (acs < 1) { + channels[(freqlist[freqlist.length - 1].mhz > 2484) ? '11a' : '11g'].length = 0; + } + + for (var i = 0; i < freqlist.length; i++) + channels[(freqlist[i].mhz > 2484) ? '11a' : '11g'].push( + freqlist[i].channel, + '%d (%d MHz)'.format(freqlist[i].channel, freqlist[i].mhz), + !freqlist[i].restricted + ); + + var modes = [ + '', 'Legacy', true, + 'n', 'N', hwmodes.n, + 'ac', 'AC', hwmodes.ac + ]; + + var htmodes = { + '': [ + '', '-', true + ], + 'n': [ + 'HT20', '20 MHz', htmodes.HT20, + 'HT40', '40 MHz', htmodes.HT40 + ], + 'ac': [ + 'VHT20', '20 MHz', htmodes.VHT20, + 'VHT40', '40 MHz', htmodes.VHT40, + 'VHT80', '80 MHz', htmodes.VHT80, + 'VHT160', '160 MHz', htmodes.VHT160 + ] + }; + + var bands = { + '': [ + '11g', '2.4 GHz', (channels['11g'].length > 3), + '11a', '5 GHz', (channels['11a'].length > 3) + ], + 'n': [ + '11g', '2.4 GHz', (channels['11g'].length > 3), + '11a', '5 GHz', (channels['11a'].length > 3) + ], + 'ac': [ + '11a', '5 GHz', true + ] + }; + + function cbi_set_values(sel, vals) + { + if (sel.vals) + sel.vals.selected = sel.selectedIndex; + + while (sel.options[0]) + sel.remove(0); + + for (var i = 0; vals && i < vals.length; i += 3) + { + if (!vals[i+2]) + continue; + + var opt = document.createElement('option'); + opt.value = vals[i+0]; + opt.text = vals[i+1]; + + sel.add(opt); + } + + if (!isNaN(vals.selected)) + sel.selectedIndex = vals.selected; + + sel.parentNode.style.display = (sel.options.length <= 1) ? 'none' : ''; + sel.vals = vals; + } + + function cbi_toggle_wifi_mode(id) + { + cbi_toggle_wifi_htmode(id); + cbi_toggle_wifi_band(id); + } + + function cbi_toggle_wifi_htmode(id) + { + var mode = document.getElementById(id + '.mode'); + var bwdt = document.getElementById(id + '.htmode'); + + cbi_set_values(bwdt, htmodes[mode.value]); + } + + function cbi_toggle_wifi_band(id) + { + var mode = document.getElementById(id + '.mode'); + var band = document.getElementById(id + '.band'); + + cbi_set_values(band, bands[mode.value]); + cbi_toggle_wifi_channel(id); + } + + function cbi_toggle_wifi_channel(id) + { + var band = document.getElementById(id + '.band'); + var chan = document.getElementById(id + '.channel'); + + cbi_set_values(chan, channels[band.value]); + } + + function cbi_init_wifi(id) + { + var mode = document.getElementById(id + '.mode'); + var band = document.getElementById(id + '.band'); + var chan = document.getElementById(id + '.channel'); + var bwdt = document.getElementById(id + '.htmode'); + + cbi_set_values(mode, modes); + + if (/VHT20|VHT40|VHT80|VHT160/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>)) + mode.value = 'ac'; + else if (/HT20|HT40/.test(<%= luci.http.write_json(self.map:get(section, "htmode")) %>)) + mode.value = 'n'; + else + mode.value = ''; + + cbi_toggle_wifi_mode(id); + + if (/a/.test(<%= luci.http.write_json(self.map:get(section, "hwmode")) %>)) + band.value = '11a'; + else + band.value = '11g'; + + cbi_toggle_wifi_band(id); + + bwdt.value = <%= luci.http.write_json(self.map:get(section, "htmode")) %>; + chan.value = <%= luci.http.write_json(self.map:get(section, "channel")) %>; + } +//]]></script> + +<label style="float:left; margin-right:3px"> + <%:Mode%><br /> + <select style="width:auto" id="<%= cbid %>.mode" name="<%= cbid %>.mode" onchange="cbi_toggle_wifi_mode('<%= cbid %>')"></select> +</label> +<label style="float:left; margin-right:3px"> + <%:Band%><br /> + <select style="width:auto" id="<%= cbid %>.band" name="<%= cbid %>.band" onchange="cbi_toggle_wifi_band('<%= cbid %>')"></select> +</label> +<label style="float:left; margin-right:3px"> + <%:Channel%><br /> + <select style="width:auto" id="<%= cbid %>.channel" name="<%= cbid %>.channel"></select> +</label> +<label style="float:left; margin-right:3px"> + <%:Width%><br /> + <select style="width:auto" id="<%= cbid %>.htmode" name="<%= cbid %>.htmode"></select> +</label> +<br style="clear:left" /> + +<script type="text/javascript">cbi_init_wifi('<%= cbid %>');</script> + +<%+cbi/valuefooter%> |