summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2016-01-28 21:03:07 +0000
committerTed Trask <ttrask01@yahoo.com>2016-01-28 21:03:07 +0000
commitc1faf5f4c95a2e3b43e65e84880b6d12f9067925 (patch)
treed6f5b9fc449671857fa3d2e8e584732c7d09cb7c
parent14e3d4fca8dceadce3d6a6a5bf2cc9f1bd4ad31d (diff)
downloadacf-apk-tools-c1faf5f4c95a2e3b43e65e84880b6d12f9067925.tar.bz2
acf-apk-tools-c1faf5f4c95a2e3b43e65e84880b6d12f9067925.tar.xz
Add server-side sorting, filtering, and pagination for available, making use of tablesorter in the HTML view
-rw-r--r--apk-available-html.lsp126
-rw-r--r--apk-controller.lua4
-rw-r--r--apk-model.lua75
3 files changed, 174 insertions, 31 deletions
diff --git a/apk-available-html.lsp b/apk-available-html.lsp
index 3872667..bcf109f 100644
--- a/apk-available-html.lsp
+++ b/apk-available-html.lsp
@@ -11,12 +11,93 @@
<script type="text/javascript">
if (typeof $.tablesorter == 'undefined') {
document.write('<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery.tablesorter.js"><\/script>');
+ document.write('<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery.tablesorter.widgets.js"><\/script>');
+ document.write('<link href="<%= html.html_escape(page_info.wwwprefix..page_info.staticdir) %>/tablesorter/jquery.tablesorter.pager.css" rel="stylesheet">');
+ document.write('<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/widgets/widget-pager.js"><\/script>');
}
</script>
<script type="text/javascript">
$(document).ready(function() {
- $("#list").tablesorter({headers: {0:{sorter: false}}, widgets: ['zebra']});
+<% if viewlibrary.check_permission("install") or viewlibrary.check_permission("upgrade") or viewlibrary.check_permission("details") then %>
+ // The following is a hack to include a multiline string
+ var MultiString = function(f) {
+ return f.toString().split('\n').slice(1, -1).join('\n');
+ }
+ var actions = MultiString(function() {/**
+ <%
+ local packagecfe = cfe({ type="hidden", value="REPLACEME" })
+ --if viewlibrary.check_permission("install") and not packagetable.upgrade then
+ if viewlibrary.check_permission("install") then
+ htmlviewfunctions.displayitem(cfe({type="form", value={package=packagecfe}, label="", option="Install", action="install" }), page_info, -1)
+ end
+ --if viewlibrary.check_permission("upgrade") and packagetable.upgrade then
+ if viewlibrary.check_permission("upgrade") then
+ htmlviewfunctions.displayitem(cfe({type="form", value={package=packagecfe}, label="", option="Upgrade", action="upgrade" }), page_info, -1)
+ end
+ if viewlibrary.check_permission("details") then
+ htmlviewfunctions.displayitem(cfe({type="form", value={package=packagecfe}, label="", option="View", action="details" }), page_info, -1)
+ end
+ %>
+ **/});
+<% end %>
+
+ $("#list").tablesorter({widgets: ['zebra', 'filter', 'pager'], widgetOptions: {
+ // Filtering is handled by the server
+ filter_serversideFiltering: true,
+
+ // We can put the page number and size here, filtering and sorting handled by pager_customAjaxUrl
+ pager_ajaxUrl : '<%= html.html_escape(page_info.script .. page_info.orig_action) %>?viewtype=json&page={page+1}&pagesize={size}',
+
+ // Modify the url after all processing has been applied to handle filtering and sorting
+ pager_customAjaxUrl: function(table, url) {
+<% if viewlibrary.check_permission("install") or viewlibrary.check_permission("upgrade") or viewlibrary.check_permission("details") then %>
+ var columns = ["upgrade", "name", "version"];
+<% else %>
+ var columns = ["name", "version"];
+<% end %>
+ var directions = ["asc", "desc"];
+ for (var s=0; s<table.config.sortList.length; s++) {
+ // 0=column number, 1=direction(0 is asc)
+ if ((table.config.sortList[s][0] < columns.length) && (table.config.sortList[s][1] < directions.length)) {
+ url += "&orderby."+(s+1)+".column="+columns[table.config.sortList[s][0]]+"&orderby."+(s+1)+".direction="+directions[table.config.sortList[s][1]]
+ }
+ }
+ for (var f=0; f<table.config.pager.currentFilters.length; f++) {
+ var filter = table.config.pager.currentFilters[f];
+ if (filter.trim()) {
+ url += "&filter."+columns[f]+"="+encodeURIComponent(filter.trim());
+ }
+ }
+ return url;
+ },
+
+ // process ajax so that the following information is returned:
+ // [ total_rows (number), rows (array of arrays), headers (array; optional) ]
+ pager_ajaxProcessing: function(data){
+ if (data && data.value && data.value.result) {
+ rows = [];
+ for ( r=0; r<data.value.result.value.length; r++) {
+ row=[];
+<% if viewlibrary.check_permission("install") or viewlibrary.check_permission("upgrade") or viewlibrary.check_permission("details") then %>
+ var tmp = actions.replace(/REPLACEME/g, data.value.result.value[r].name);
+ if (data.value.result.value[r].upgrade) {
+ row[0] = tmp.replace(/action="install"[\s\S]*?<form /, "");
+ } else {
+ row[0] = tmp.replace(/action="upgrade"[\s\S]*?<form /, "");
+ }
+ row[1] = data.value.result.value[r].name;
+ row[2] = data.value.result.value[r].version;
+<% else %>
+ row[0] = data.value.result.value[r].name;
+ row[1] = data.value.result.value[r].version;
+<% end %>
+ rows.push(row);
+ }
+ return [ parseInt(data.value.rowcount.value), rows];
+ }
+ }
+ }});
});
</script>
@@ -25,33 +106,30 @@
<% local header_level = htmlviewfunctions.displaysectionstart(form, page_info) %>
<table id="list" class="tablesorter"><thead>
<tr>
- <% if viewlibrary.check_permission("install") or viewlibrary.check_permission("upgrade") then %>
- <th>Action</th>
+ <% if viewlibrary.check_permission("install") or viewlibrary.check_permission("upgrade") or viewlibrary.check_permission("details") then %>
+ <th class="filter-false remove">Action</th>
<% end %>
<th>Package Name</th>
<th>Version</th>
</tr>
</thead><tbody>
-<% local packagecfe = cfe({ type="hidden", value="" }) %>
-<% for i,packagetable in pairs(form.value) do %>
- <tr>
- <% if viewlibrary.check_permission("install") or viewlibrary.check_permission("upgrade") or viewlibrary.check_permission("details") then %>
- <% packagecfe.value = packagetable.name %>
- <td>
- <% if viewlibrary.check_permission("install") and not packagetable.upgrade then %>
- <% htmlviewfunctions.displayitem(cfe({type="form", value={package=packagecfe}, label="", option="Install", action="install" }), page_info, -1) %>
- <% end %>
- <% if viewlibrary.check_permission("upgrade") and packagetable.upgrade then %>
- <% htmlviewfunctions.displayitem(cfe({type="form", value={package=packagecfe}, label="", option="Upgrade", action="upgrade" }), page_info, -1) %>
- <% end %>
- <% if viewlibrary.check_permission("details") then %>
- <% htmlviewfunctions.displayitem(cfe({type="form", value={package=packagecfe}, label="", option="View", action="details" }), page_info, -1) %>
- <% end %>
- </td>
- <% end %>
- <td><%= html.html_escape(packagetable.name) %></td>
- <td><%= html.html_escape(packagetable.version) %></td>
- </tr>
-<% end %>
</tbody></table>
+
+<div id="pager" class="pager">
+ <form>
+ Page: <select class="gotoPage"></select>
+ <img src="<%= html.html_escape(page_info.wwwprefix..page_info.staticdir) %>/tablesorter/first.png" class="first"/>
+ <img src="<%= html.html_escape(page_info.wwwprefix..page_info.staticdir) %>/tablesorter/prev.png" class="prev"/>
+ <span class="pagedisplay"></span> <!-- this can be any element, including an input -->
+ <img src="<%= html.html_escape(page_info.wwwprefix..page_info.staticdir) %>/tablesorter/next.png" class="next"/>
+ <img src="<%= html.html_escape(page_info.wwwprefix..page_info.staticdir) %>/tablesorter/last.png" class="last"/>
+ <select class="pagesize">
+ <option selected="selected" value="10">10</option>
+ <option value="20">20</option>
+ <option value="30">30</option>
+ <option value="40">40</option>
+ </select>
+ </form>
+</div>
+
<% htmlviewfunctions.displaysectionend(header_level) %>
diff --git a/apk-controller.lua b/apk-controller.lua
index 70e82bf..674742a 100644
--- a/apk-controller.lua
+++ b/apk-controller.lua
@@ -4,11 +4,11 @@ local mymodule = {}
mymodule.default_action = "loaded"
mymodule.loaded = function(self)
- return self.model.get_loaded_packages()
+ return self.model.get_loaded_packages(self, self.clientdata)
end
mymodule.available = function(self)
- return self.model.get_available_packages()
+ return self.model.get_available_packages(self, self.clientdata)
end
mymodule.details = function(self)
diff --git a/apk-model.lua b/apk-model.lua
index f44e78d..e2626ce 100644
--- a/apk-model.lua
+++ b/apk-model.lua
@@ -172,21 +172,86 @@ mymodule.get_loaded_packages = function()
return cfe({ type="group", value={toplevel=top, dependent=depend}, label="Installed Packages" })
end
-mymodule.get_available_packages = function()
+mymodule.get_available_packages = function(self, clientdata)
repo = repository()
-- available are all except same version installed
- local available = cfe({ type="list", value={}, label="Available Packages" })
+ local retval = cfe({ type="group", value={}, label="Available Packages" })
+ retval.value.page = cfe({ value=0, label="Page Number", descr="0 indicates ALL", key=true })
+ retval.value.pagesize = cfe({ value=10, label="Page Size", key=true })
+ retval.value.rowcount = cfe({ value=0, label="Row Count" })
+ -- orderby must be an array of tables with column name and direction
+ retval.value.orderby = cfe({ type="structure", value={{column="name", direction="asc"}}, label="Order By", key=true })
+ -- filter is a table with a string filter for each column
+ retval.value.filter = cfe({ type="structure", value={name="", version=""}, label="Filter", key=true })
+ self.handle_clientdata(retval, clientdata)
+ retval.value.result = cfe({ type="structure", value={}, label="Available Packages" })
+
+ -- Process the incoming page data
+ local page = tonumber(retval.value.page.value) or 0
+ retval.value.page.value = page
+ local pagesize = tonumber(retval.value.pagesize.value) or 10
+ retval.value.pagesize.value = pagesize
+
+ local available = {}
for name,value in pairs(repo) do
if value.version and (not value.installed or value.upgrade) then
local temp = {}
temp.name = name
temp.version = value.version
temp.upgrade = value.upgrade
- available.value[#available.value + 1] = temp
+
+ -- Filter
+ for c,f in pairs(retval.value.filter.value) do
+ if temp[c] and f ~= "" and not string.find(temp[c], format.escapemagiccharacters(f)) then
+ temp = nil
+ break
+ end
+ end
+
+ available[#available + 1] = temp
+ end
+ end
+
+ -- Sort
+ if #available > 0 then
+ local function createsort(column, descending, equal)
+ return function(a,b)
+ if a[column] == b[column] then
+ return equal(a,b)
+ end
+ if descending then
+ return tostring(a[column]) > tostring(b[column])
+ end
+ return tostring(a[column]) < tostring(b[column])
+ end
end
+ local sortfunction = function(a,b) return false end
+ if #retval.value.orderby.value == 0 then
+ sortfunction = createsort("name", true, sortfunction)
+ else
+ local columns = {name=true, version=true, upgrade=true}
+ local directions = {desc=true, DESC=true}
+ for i=#retval.value.orderby.value,1,-1 do
+ local orderby = retval.value.orderby.value[i]
+ if columns[orderby.column] then
+ sortfunction = createsort(orderby.column, directions[orderby.direction], sortfunction)
+ end
+ end
+ end
+ table.sort(available, sortfunction)
+ end
+
+ -- Paginate
+ retval.value.rowcount.value = #available
+ if page > 0 then
+ for i=((page-1)*pagesize+1), (page*pagesize) do
+ retval.value.result.value[#retval.value.result.value+1] = available[i]
+ end
+ else
+ retval.value.result.value = available
end
- table.sort(available.value, function(a,b) return (a.name < b.name) end)
- return available
+
+ return retval
end
mymodule.get_delete_package = function(self, clientdata)