You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
changedetection.io/changedetectionio/static/js/tbltools.js

406 lines
12 KiB

// table tools
// must be a var for keyChar and keyCode use
var CONSTANT_ESCAPE_KEY = 27;
var CONSTANT_S_KEY = 83;
var CONSTANT_s_KEY = 115;
// globals
var loading;
var sort_column; // new window or tab is always last_changed
var sort_order; // new window or tab is always descending
// restore scroll position on submit/reload
document.addEventListener("DOMContentLoaded", function(event) {
load_functions();
var scrollpos = sessionStorage.getItem('scrollpos');
if (scrollpos) window.scrollTo(0, scrollpos);
});
// mobile scroll position retention
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
document.addEventListener("visibilitychange", function() {
storeScrollAndSearch();
});
} else {
// non-mobile scroll position retention
window.onbeforeunload = function(e) {
storeScrollAndSearch();
};
}
function storeScrollAndSearch() {
sessionStorage.setItem('scrollpos', window.pageYOffset);
sessionStorage.setItem('searchtxt', document.getElementById("txtInput").value);
}
// mobile positioning of checkbox-controls grid popup
document.addEventListener("touchstart", touchStartHandler, false);
var touchXY = {};
function touchStartHandler(event) {
var touches = event.changedTouches;
touchXY = {
clientX : touches[0].clientX,
clientY : touches[0].clientY
};
}
// (ctl)-alt-s search hotkey
document.onkeyup = function(e) {
var e = e || window.event; // for IE to cover IEs window event-object
if (e.altKey && (e.which == CONSTANT_S_KEY || e.which == CONSTANT_s_KEY)) {
document.getElementById("txtInput").focus();
return false;
}
}
// new window or tab loading
function load_functions() {
// loading
loading = true;
// retain checked items
checkChange();
// retrieve saved sorting
getSort();
// sort if not default
sortTable(sort_column);
// search
if (isSessionStorageSupported()) {
// retrieve search
if (sessionStorage.getItem("searchtxt") != null) {
document.getElementById("txtInput").value = sessionStorage.getItem("searchtxt");
tblSearch(this);
}
}
}
// sorting
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0,
sortimgs, sortableimgs;
table = document.getElementById("watch-table");
switching = true;
//Set the sorting direction, either default 9, 1 or saved
if (loading) {
getSort();
dir = (sort_order == 0) ? "asc" : "desc";
loading = false;
} else {
dir = "asc";
}
/*Make a loop that will continue until
no switching has been done:*/
while (switching) {
//start by saying: no switching is done:
switching = false;
rows = table.rows;
/*Loop through all table rows (except the
first, which contains table headers):*/
for (i = 1; i < (rows.length - 1); i++) {
//start by saying there should be no switching:
shouldSwitch = false;
/*Get the two elements you want to compare,
one from current row and one from the next:*/
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
x = x.innerHTML.toLowerCase();
y = y.innerHTML.toLowerCase();
if (!isNaN(x)) { // handle numeric columns
x = parseFloat(x);
y = parseFloat(y);
}
if (n == 1) { // handle play/pause column
x = rows[i].getElementsByTagName("TD")[n].getElementsByTagName("img")[0].src;
y = rows[i + 1].getElementsByTagName("TD")[n].getElementsByTagName("img")[0].src;
}
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x > y) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x < y) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
/*If a switch has been marked, make the switch
and mark that a switch has been done:*/
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
//Each time a switch is done, increase this count by 1:
switchcount++;
} else {
/*If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again.*/
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
// hide all asc/desc sort arrows
sortimgs = document.querySelectorAll('[id^="sort-"]');
for (i = 0; i < sortimgs.length; i++) {
sortimgs[i].style.display = "none";
}
// show current asc/desc sort arrow and set sort_order var
if (dir == "asc") {
document.getElementById("sort-" + n + "a").style.display = "";
} else {
document.getElementById("sort-" + n + "d").style.display = "";
}
// show all sortable indicators
sortableimgs = document.querySelectorAll('[id^="sortable-"]');
for (i = 0; i < sortableimgs.length; i++) {
sortableimgs[i].style.display = "";
}
// hide sortable indicator from current column
document.getElementById("sortable-" + n).style.display = "none";
// save sorting
sessionStorage.setItem("sort_column", n);
sessionStorage.setItem("sort_order", (dir == "asc") ? 0 : 1);
// restripe rows
restripe();
}
// check/uncheck all checkboxes
function checkAll(e) {
var elemID = event.srcElement.id;
if (!elemID) return;
var elem = document.getElementById(elemID);
var rect = elem.getBoundingClientRect();
var offsetLeft = document.documentElement.scrollLeft + rect.left;
var offsetTop;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
offsetTop = touchXY.clientY; // + rect.top;
}
else {
offsetTop = document.documentElement.scrollTop + rect.top;
}
var i;
var checkboxes = document.getElementsByName('check');
var checkboxFunctions = document.getElementById('checkbox-functions');
if (e.checked) {
for (i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = true;
}
checkboxFunctions.style.display = "";
checkboxFunctions.style.left = offsetLeft + 30 + "px";
checkboxFunctions.style.top = offsetTop + "px";
} else {
for (i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = false;
}
checkboxFunctions.style.display = "none";
}
}
// show/hide checkbox controls grid popup and check/uncheck checkall checkbox if all other checkboxes are checked/unchecked
function checkChange(e) {
var elemID = event.srcElement.id;
if (!elemID) return;
var elem = document.getElementById(elemID);
var rect = elem.getBoundingClientRect();
var offsetLeft = document.documentElement.scrollLeft + rect.left;
var offsetTop;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
offsetTop = touchXY.clientY; // + rect.top;
}
else {
offsetTop = document.documentElement.scrollTop + rect.top;
}
var i;
var totalCheckbox = document.querySelectorAll('input[name="check"]').length;
var totalChecked = document.querySelectorAll('input[name="check"]:checked').length;
var checkboxFunctions = document.getElementById('checkbox-functions');
if(totalCheckbox == totalChecked) {
document.getElementsByName("showhide")[0].checked=true;
}
else {
document.getElementsByName("showhide")[0].checked=false;
}
if (totalChecked > 0) {
checkboxFunctions.style.display = "";
checkboxFunctions.style.left = offsetLeft + 30 + "px";
if ( offsetTop > ( window.innerHeight - checkboxFunctions.offsetHeight) ) {
checkboxFunctions.style.top = (window.innerHeight - checkboxFunctions.offsetHeight) + "px";
}
else {
checkboxFunctions.style.top = offsetTop + "px";
}
} else {
checkboxFunctions.style.display = "none";
}
}
// search watches in Title column
function tblSearch(evt) {
var code = evt.charCode || evt.keyCode;
if (code == CONSTANT_ESCAPE_KEY) {
document.getElementById("txtInput").value = '';
}
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("txtInput");
filter = input.value.toUpperCase();
table = document.getElementById("watch-table");
tr = table.getElementsByTagName("tr");
for (i = 1; i < tr.length; i++) { // skip header
td = tr[i].getElementsByTagName("td")[3]; // col 3 is the hidden title/url column
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
// restripe rows
restripe();
if (code == CONSTANT_ESCAPE_KEY) {
document.getElementById("watch-table-wrapper").focus();
}
}
// restripe after searching or sorting
function restripe() {
var i, visrows = [];
var table = document.getElementById("watch-table");
var rows = table.getElementsByTagName("tr");
for (i = 1; i < rows.length; i++) { // skip header
if (rows[i].style.display !== "none") {
visrows.push(rows[i]);
}
}
for (i = 0; i < visrows.length; i++) {
var row = visrows[i];
if (i % 2 == 0) {
row.classList.remove('pure-table-odd');
row.classList.add('pure-table-even');
} else {
row.classList.remove('pure-table-even');
row.classList.add('pure-table-odd');
}
var cells = row.getElementsByTagName("td");
for (var j = 0; j < cells.length; j++) {
if (i % 2 == 0) {
cells[j].style.background = "#f2f2f2";
} else {
cells[j].style.background = "#ffffff";
}
}
// uncomment to renumber rows ascending: var cells = row.getElementsByTagName("td");
// uncomment to renumber rows ascending: cells[0].innerText = i+1;
}
}
// get checked or all uuids
function getChecked(items) {
var i, checkedArr, uuids = '';
if (items === undefined) {
checkedArr = document.querySelectorAll('input[name="check"]:checked');
} else {
checkedArr = document.querySelectorAll('input[name="check"]');
}
if (checkedArr.length > 0) {
let output = [];
for (i = 0; i < checkedArr.length; i++) {
output.push(checkedArr[i].parentNode.parentNode.getAttribute("id"));
}
for (i = 0; i < checkedArr.length; i++) {
if (i < checkedArr.length - 1) {
uuids += output[i] + ",";
} else {
uuids += output[i];
}
}
}
return uuids;
}
// process selected watches
function processChecked(func, tag) {
var uuids, result;
if (func == 'mark_all_notviewed') {
uuids = getChecked('all');
} else {
uuids = getChecked();
}
// confirm if deleting
if (func == 'delete_selected' && uuids.length > 0) {
result = confirm('Deletions cannot be undone.\n\nAre you sure you want to continue?');
if (result == false) {
return;
}
}
// href locations
var currenturl = window.location;
var posturl = location.protocol + '//' + location.host + '/api/process-selected';
// posting vars
const XHR = new XMLHttpRequest(),
FD = new FormData();
// fill form data
FD.append('func', func);
FD.append('tag', tag);
FD.append('uuids', uuids);
// success
XHR.addEventListener('load', function(event) {
window.location = currenturl;
});
// error
XHR.addEventListener(' error', function(event) {
alert('Error posting request.');
});
// set up request
XHR.open('POST', posturl);
// send
XHR.send(FD);
}
function clearSearch() {
document.getElementById("txtInput").value = '';
tblSearch(CONSTANT_ESCAPE_KEY);
}
function isSessionStorageSupported() {
var storage = window.sessionStorage;
try {
storage.setItem('test', 'test');
storage.removeItem('test');
return true;
} catch (e) {
return false;
}
}
function getSort() {
if (isSessionStorageSupported()) {
// retrieve sort settings if set
if (sessionStorage.getItem("sort_column") != null) {
sort_column = sessionStorage.getItem("sort_column");
sort_order = sessionStorage.getItem("sort_order");
} else {
sort_column = 7; // last changed
sort_order = 1; // desc
//alert("Your web browser does not support retaining sorting and page position.");
}
}
}
function closeGridDisplay() {
document.getElementsByName("showhide")[0].checked = false;
var checkboxes = document.getElementsByName('check');
for (i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = false;
}
document.getElementById("checkbox-functions").style.display = "none";
}