diff options
author | Ted Trask <ttrask01@yahoo.com> | 2016-01-28 21:03:07 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2016-01-28 21:03:07 +0000 |
commit | c1faf5f4c95a2e3b43e65e84880b6d12f9067925 (patch) | |
tree | d6f5b9fc449671857fa3d2e8e584732c7d09cb7c | |
parent | 14e3d4fca8dceadce3d6a6a5bf2cc9f1bd4ad31d (diff) | |
download | acf-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.lsp | 126 | ||||
-rw-r--r-- | apk-controller.lua | 4 | ||||
-rw-r--r-- | apk-model.lua | 75 |
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) |