Javascript CSS display not working when called from an onClick event dynamically added - javascript

I am creating an HTML table dynamically and adding an onClick event in each title cell dynamically as well. (The goal of my project is re order the columns of the html table using the onClick event).
The event is being called perfectly, however if I try to set the display of a div inside that function the display event never fires or only fires once the function ends. In my case I am trying to show a loading image while my function executes.
Please see here my code, any help is most than welcome.
HTML:
<div class="container body">
<div class="report_main_container">
<div class="table-responsive table-responsive-lg text-center new-rprt-chgs loading-container">
<div class="loading-over" id="loading-over">
<img src="loading.gif">
</div>
<table class="table table-striped" id="main_report_table" style="display: none">
<thead id="fixedHeader"></thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
Javascript:
var row_head = '';
var row_head_reporte = [];
row_head += '<tr>';
for (let i = 0; i < my_report["columns"].length; i++) {
// console.log(my_report["columns"][i]);
if (my_report["columns"][i]["VISIBLE"] == "YES") {
row_head += '<th onclick="sortTable(' + i + ')">' + my_report["columns"][i]["NAME"] + '</th>';
}
}
row_head += '</tr>';
$("#main_report_table thead").append(row_head);
function sortTable(n) {
$(".loading-over").show(); // This never fires!!!!
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("main_report_table");
switching = true;
// Set the sorting direction to ascending:
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];
/* Check if the two rows should switch place,
based on the direction, asc or desc: */
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
// If so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
// 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;
}
}
}
$(".loading-over").hide();
}

Related

Sorting and unsorting function

I made script for sorting (A to Z)
My question is what I need to add to this to have unsort function, I mean set to default (how it was before you sort them).
Code:
function sortList() {
document.getElementById('sortedtxt').innerHTML = 'Sorted A-Z';
document.getElementById('sortedtitle').innerHTML = 'BFMAS - Sorted A-Z';
var list, i, switching, b, shouldSwitch;
list = document.getElementById("sortingUL");
switching = true;
while (switching) {
switching = false;
b = list.getElementsByTagName("LI");
for (i = 0; i < (b.length - 1); i++) {
shouldSwitch = false;
if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
b[i].parentNode.insertBefore(b[i + 1], b[i]);
switching = true;
}
}
}
Please use this code JS & HTML
let globalList, temp = [], sorted = true;
document.getElementById("sort").addEventListener('click', sortList);
document.getElementById("unsorted").addEventListener('click', UnsortedList);
function UnsortedList() {
let currentList = document.getElementById("countries");
currentList.innerHTML = '';
temp.forEach(function (item) {
let li = document.createElement('li');
currentList.appendChild(li);
li.innerHTML += item;
});
sorted = true;
}
function getTempArray(pList) {
globalList = pList.getElementsByTagName("li");
temp = [];
for (let j = 0; j < globalList.length; j++) {
temp.push(globalList[j].innerText);
}
}
function sortList() {
let list, i, switching, b, shouldSwitch;
list = document.getElementById("countries");
if (sorted === true) {
getTempArray(list);
sorted = false;
}
switching = true;
while (switching) {
switching = false;
b = list.getElementsByTagName("li");
for (i = 0; i < (b.length - 1); i++) {
shouldSwitch = false;
if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
b[i].parentNode.insertBefore(b[i + 1], b[i]);
switching = true;
}
}
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Pues </title>
</head>
<body>
<p>Click the button to sort the list alphabetically 🙂</p>
<button id="sort"><b>Sort</b></button>
<button id="unsorted"><i>Unsorted</i></button>
<ul id="countries">
<li>Peru</li>
<li>Argentina</li>
<li>Brazil</li>
<li>Colombia</li>
<li>Paraguay</li>
<li>Bolivia</li>
</ul>
</body>
</html>
First, it seems kind crazy that you are sorting DOM elements in situ (in place), rather than having a separate list data structure (e.g. an array) and treating the DOM as a view... i.e. rendering the list data into the DOM as needed (i.e. after it updates or after you sort it).
Recommendation:
Move the sortedtxt data into an array.
Keep a copy of the array for the original sort order.
create and call a function that renders the array elements into the DOM, e.g. into the appropriate <ul>, <ol> or <table>.
On a user action that changes the sort order or restores the original, apply that to the array and then call the above function again.
Benefits:
Better webpage performance.
Cleaner, simpler that separates data from presentation code.
You can implement fancier sort features such as Sort array of objects by string property value much easier.

How can i delete one row from a Table, which is saved in localStorage?

My Problem is, that i can only delete the full Content. By i need to delete a Row i selected.
I tried this:
function addData(){
arr.push({
name:document.getElementById('name').value,
datum:document.getElementById('datum').value,
start:document.getElementById('start').value,
ziel:document.getElementById('ziel').value,
hinfahrt:document.getElementById('hinfahrt').value,
ruckfahrt:document.getElementById('ruckfahrt').value,
zuzahlung:document.getElementById('zuzahlung').value
});
localStorage.setItem("localData",JSON.stringify(arr)); <---------
}
function deleteOne(){
var content = localStorage.getItem("localData");
localStorage.removeItem(JSON.stringify(arr[1]));
localStorage.removeItem(content);
}
The Informations are in a array. And the Key is "localData". How can i especial target one Row?
The checkpoint marks the deleting row:
Front
EDIT
I tried to implement, what you say. But i have this Problem. Cant remove from Storage. Here is my full Code. The Problem is in the Method
deleteOne() the Value for XXX. Hope you can understand my Problem.
var rowId = 0;
var testcounter;
function deleteMoreRows(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var selectedRows = getCheckedBoxes();
selectedRows.forEach(function (currentValue) {
deleteRowByCheckboxId(currentValue.id);
});
}
function getRowId() {
rowId += 1;
return rowId;
}
function getRowIdsFromElements($array) {
var arrIds = [];
$array.forEach(function (currentValue, index, array) {
arrIds.push(getRowIdFromElement(currentValue));
});
return arrIds;
}
function getRowIdFromElement($el) {
return $el.id.split('delete')[1];
}
function getCheckedBoxes() {
var inputs = document.getElementsByTagName("input");
var checkboxesChecked = [];
for (var i = 0; i < inputs.length; i++) {
// And stick the checked ones onto an array...
if (inputs[i].checked) {
checkboxesChecked.push(inputs[i]);
}
}
return checkboxesChecked.length > 0 ? checkboxesChecked : null;
}
function deleteRowByCheckboxId(CheckboxId) {
var checkbox = document.getElementById(CheckboxId);
var row = checkbox.parentNode.parentNode; //box, cell, row, table
var table = row.parentNode;
while (table && table.tagName != 'TABLE')
table = table.parentNode;
if (!table) return;
table.deleteRow(row.rowIndex);
}
function myFunction() {
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("search");
filter = input.value.toUpperCase();
table = document.getElementById("tbl_id");
tr = table.getElementsByTagName("tr");
for (i = 1; i < tr.length; i++) {
// Hide the row initially.
tr[i].style.display = "none";
td = tr[i].getElementsByTagName("td");
for (var j = 0; j < td.length; j++) {
cell = tr[i].getElementsByTagName("td")[j];
if (cell) {
if (cell.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
break;
}
}
}
}
}
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("tbl_id");
switching = true;
//Set the sorting direction to ascending:
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];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
//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;
}
}
}
}
function sortTableByAdding() {
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("tbl_id");
switching = true;
/*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")[1];
y = rows[i + 1].getElementsByTagName("TD")[1];
//check if the two rows should switch place:
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//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;
}
}
}
var arr = new Array();
//form onsubmit
function addData() {
getData();
arr.push({
name: document.getElementById('name').value,
datum: document.getElementById('datum').value,
start: document.getElementById('start').value,
ziel: document.getElementById('ziel').value,
hinfahrt: document.getElementById('hinfahrt').value,
ruckfahrt: document.getElementById('ruckfahrt').value,
zuzahlung: document.getElementById('zuzahlung').value
});
localStorage.setItem("localData", JSON.stringify(arr));
showData();
}
function getData() {
var str = localStorage.getItem("localData");
if (str != null) {
arr = JSON.parse(str);
}
}
function deleteData() {
localStorage.clear();
}
function deleteOne() {
var inhalt = localStorage.getItem("localData");
var tmp = JSON.parse(inhalt);
localStorage.removeItem("localData");
tmp.splice(**XXX**, 1);
localStorage.setItem("localData", JSON.stringify(tmp));
}
function showData() {
getData();
var table = document.getElementById('tbl_id');
var x = table.rows.length;
while (--x) {
table.deleteRow(x);
}
for (i = 0; i < arr.length; i++) {
var inputname = document.getElementById('name').value;
var inputdatum = document.getElementById('datum').value;
var inputstart = document.getElementById('start').value;
var inputziel = document.getElementById('ziel').value;
var inputhinfahrt = document.getElementById('hinfahrt').value;
var inputruckfahrt = document.getElementById('ruckfahrt').value;
var inputzuzahlung = document.getElementById('zuzahlung').value;
var row = table.insertRow();
var rowBox = row.insertCell(0);
var userName = row.insertCell(1);
var userDatum = row.insertCell(2);
var userStart = row.insertCell(3);
var userZiel = row.insertCell(4);
var userHinfahrt = row.insertCell(5);
var userRuckfahrt = row.insertCell(6);
var userZuzahlung = row.insertCell(7);
var checkbox = row.insertCell(8);
rowBox.innerHTML = '<input type="checkbox" id="delete' + getRowId() + '">';
userName.innerHTML = arr[i].name;
userDatum.innerHTML = arr[i].datum;
userStart.innerHTML = arr[i].start;
userZiel.innerHTML = arr[i].ziel;
userHinfahrt.innerHTML = arr[i].hinfahrt;
userRuckfahrt.innerHTML = arr[i].ruckfahrt;
userZuzahlung.innerHTML = arr[i].zuzahlung;
}
sortTableByAdding();
}
HTML
<body>
<input id="name" placeholder="Name" size="12" required>
<input id="datum" name="semdate" type="date" required>
<input id="start" placeholder="Start" size="12" required>
<input id="ziel" placeholder="Ziel" size="12" required>
<input id="hinfahrt" type="checkbox">Hinfahrt
<input id="ruckfahrt" type="checkbox">Rückfahrt
<input id="zuzahlung" placeholder="Zuzahlung" size="12">
<br>
<input type="button" id="mysubmit" value="Add" onClick="addData()">
<input type="button" id="delete" value="Delete"
onClick="deleteMoreRows('tbl_id')">
<input type="text" id="search" onkeyup="myFunction()" placeholder="Suche"
title="Type in a name">
<br>
<br>
<table id="tbl_id" style="text-align:center" align="center" valign="top">
<thead>
<tr>
<th style="width:200px;">Löschen</th>
<th onclick="sortTable(1)" style="width:200px;">Name</th>
<th onclick="sortTable(2)" style="width:200px;">Datum</th>
<th onclick="sortTable(3)" style="width:200px;">Start</th>
<th onclick="sortTable(4)" style="width:200px;">Ziel</th>
<th onclick="sortTable(5)" style="width:200px;">Hinfahrt</th>
<th onclick="sortTable(6)" style="width:200px;">Rückfahrt</th>
<th onclick="sortTable(7)" style="width:200px;">Zuzahlung</th>
</tr>
</thead>
<script>
showData();
</script>
<button onclick="deleteData()">!!!Clear Storage!!!</button>
<button onclick="deleteEinzel()">test</button>
</body>
You could use a data structure which allows you to target values by key. One option is to use an object instead of an array and remove/add the rows by their corresponding key.
// pass the id as a parameter to target the row
function addData(rowId) {
let storageTmp = JSON.parse(localStorage.getItem("storage"));
storageTmp = {
// ... -> spread operator
// add content of storage
...storageTmp,
// add new row
rowId: {
name: 'name',
datum: 'datum'
}
}
// overwrite storage variable
localStorage.setItem("storage", JSON.stringify(storageTmp));
}
// pass the id as a parameter to target the row
function deleteOne(rowId) {
const storageTmp = JSON.parse(localStorage.getItem("storage"));
// remove property
delete storageTmp.rowId;
localStorage.setItem("storage", JSON.stringify(storageTmp));
}
Another one would be to use a Map which got introduced by ECMA 6.
Save the content in a Json object.
var tmp = JSON.parse(content);
then delete the full content of the local storage
localStorage.removeItem("localdata");
then delete your line
tmp.splice(row, 1);
and finally throw data in local storage
localStorage.setItem("localData",JSON.stringify(tmp));
You have to retrieve the entry from the local storage, delete the value you want to delete and then write it to the local storage again.

Sort Table incorporated in GAS

Hi I would like to ask if why the sort table function is not working if I put a condition wherein only specific data will be shown in the table. However, if I show all the data from the spreadsheet to the table the sorting function works fine. See sample code below:
<table id="vllist" class="vllist1">
<? var data = SpreadsheetApp
.openById('spreadsheet ID')
.getSheetByName("VL Request")
.getDataRange()
.getValues();
var timeStamp = [0];
var rid = [1];
var ldap = [2];
var aname = [7];
var tlname = [8];
var lob = [9];
var dovl = [5];
var userName = Session.getEffectiveUser().getUsername();
?>
<tr>
<th colspan=5>Scheduler VIEW</th>
</tr>
<tr>
<th onclick="sortTable(0)">Request ID</th>
<th onclick="sortTable(1)">LDAP</th>
<th onclick="sortTable(2)">Agent Name</th>
<th onclick="sortTable(3)">Team Lead</th>
<th onclick="sortTable(4)">Lane</th>
<th onclick="sortTable(5)">Date of VL</th>
</tr>
<? for (var i = 1; i < data.length; i++) { ?>
<tr>
<?var today = new Date();
if (data[i][dovl] > today) { ?>
<?
var schedtimeStamp = data[i][schedtimeStampappr];
var POCtimeStamp = data[i][POCtimeStampappr];
var vldate = data[i][dovl];
var formattedDateVL = (vldate.getMonth()+1) + '/' + vldate.getDate() + '/' + vldate.getYear();
?>
<td>
<?= data[i][rid] ?>
</td>
<td>
<?= data[i][ldap] ?>
</td>
<td>
<?= data[i][aname] ?>
</td>
<td>
<?= data[i][tlname] ?>
</td>
<td>
<?= data[i][lob] ?>
</td>
<td>
<?= [formattedDateVL] ?>
</td>
<? } ?>
</tr>
<? } ?>
</table>
<script>
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("vllist");
switching = true;
//Set the sorting direction to ascending:
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 = 2; 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];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch= true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
//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;
}
}
}
}
</script>
Please check the code and let me know if there any other way or alternative to make a sorting table even if not all the data from the spreadsheet will be shown on the table. I just only the sorting to be fixed when each header will be clicked. :)
Well first of all write this as a function on the server.
var data = SpreadsheetApp
.openById('spreadsheet ID')
.getSheetByName("VL Request")
.getDataRange()
.getValues();
var timeStamp = [0];
var rid = [1];
var ldap = [2];
var aname = [7];
var tlname = [8];
var lob = [9];
var dovl = [5];
var userName = Session.getEffectiveUser().getUsername();
When you get that done we can move on to the next step.

Using Java script to sort HTML table by appropriate column on column header click

I am trying to set up a HTML table that when you click on the column header it will sort the table by that column. My current solution works perfectly for the first column, its something I found on W3schools.
Edit: (Issue was the script comparing all the contained HTML in each TD, not just the displayed text)
But when I tried to generalise it with "n" instead of leaving a number in the java script for which column to sort, I can't seem to get it to take the correct value for n.
My plan was to use the code from W3schools (below) for sorting the first column, but insert a variable n to allow the same piece of code to sort multiple columns. I am trying to get the Java script to read n from the HTML section itself but i am not sure why it's not working.
This is my version of the W3schools code where I have tried to use n, this currently sorts the first column no matter which column header I click on.
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("mytable");
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
if (dir == "asc") {
if (x.innerHTML.toUpperCase() > y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toUpperCase() < y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
switchcount ++;
} else {
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
<table id="mytable">
<tr>
<th>
<div onclick="sortTable(0)">a</div>
</th>
<th>
<div onclick="sortTable(1)">b</div>
</th>
<th>
<div onclick="sortTable(2)">c</div>
</th>
</tr>
<tr>
<td>04718J00065</td>
<td>2100305513</td>
<td>10</td>
</tr>
<tr>
<td>29417J01131</td>
<td>2100305513</td>
<td>30</td>
</tr>
<tr>
<td>07416J01979</td>
<td>2100029648</td>
<td>0</td>
</tr>
</table>
I think what the issue is, is that the Java script isn't getting a value for n and it's defaulting to 0 which is why it sorts the first column no matter which header was clicked on. How can I get it to read n=0 from onclick="sortTable(0)", n=1 from onclick="sortTable(1)" etc?
I have found out what was causing the issue.
Using
(x.innerHTML.toUpperCase() > y.innerHTML.toUpperCase())
and
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
compares everything inside that TD, not just the text that gets displayed. I had removed a <a></a> section from each TD when posting the code for this question trying to avoid posting code in too much detail and the link was pointing to files that shared a name with the string that was in the first column.
<table id="mytable">
<tr>
<th>
<div onclick="sortTable(0)">a</div>
</th>
<th>
<div onclick="sortTable(1)">b</div>
</th>
<th>
<div onclick="sortTable(2)">c</div>
</th>
</tr>
<tr>
<td>04718J00065</td>
<td>2100305513</td>
<td>10</td>
</tr>
<tr>
<td>29417J01131</td>
<td>2100305513</td>
<td>30</td>
</tr>
<tr>
<td>07416J01979</td>
<td>2100029648</td>
<td>0</td>
</tr>
</table>
<script>
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("mytable");
switching = true;
dir = "asc";
while (switching) {
switching = false;
rows = table.rows;
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("A")[n];
y = rows[i + 1].getElementsByTagName("A")[n];
if (dir == "asc") {
if (x.innerHTML.toUpperCase() > y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toUpperCase() < y.innerHTML.toUpperCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
switchcount ++;
} else {
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
</script>
My solution to this was just to swap "TD" in the script to "A" so it would compare inside the tag and not the link location itself. My changes to include "n" had worked as intended.

Change color of cells based on value in DB

I'm trying to accomplish the following.
I have a "grid" in which each cell can be 'owned' by a user.
To 'own' some new cells, the user should be able to click on two points (in a straight line) on the grid and then confirm by clicking on a button or cancel by clicking on another button, which updates the state of the grid. When both points are clicked, the cells between the two clicked ones must change color.
I should mention that I would like to achieve this only by using plain Javascript / PHP, if possible.
What I've done so far:
I have stored the 'grid' in a DB, having a record for each cell, containing position (i, j), owner and some other feature.
I query the DB using PHP, I save everything in memory (2D array - the grid is supposed to be small) and represent the grid by generating an HTML table
I'm trying to use JS to change the color of the cells when clicking, but I'm having problems (I'm new to JS and web programming in general).
I'm sure there's some kind of pattern to do what I want to do (surely is not rocket science), and would completely agree the following is pure Spaghetti code, but that's the only way I thought of doing it given my very very limited experience.
I do the following.
I have an HTML page with a named div in which I represent the table
<div id="Vis_table"> <?php echo $table ?> </div>
At the end of the body I have a script, which I report in its essential elements
var click = 0;
var grid = <?php echo json_encode($grid); ?>;
var Y_grid = <?php echo Y_g; ?>;
if (click == 0) { //first click
var cells = document.getElementsByTagName("th"); //take all cells
for (var i = 0; i < cells.length; i++) { // all rows
var row = parseInt(i / (Y_grid)); //dimensions
var col = i % (Y_grid);
cells[i].onclick = (function (xr, yc, index) {
return function () {
if (click == 0) { //first click, start
var tab = "<table>";
for (var x = 0; x < grid.length; x++) {
tab += "<tr>";
for (var y = 0; y < grid[0].length; y++) {
if (x == xr && y == yc) { //if it's the cell i clicked on
tab += "<th class = 'clicked'>" + x + " " + y + "</th>";
} else {
tab += "<th class = 'free'> </th>";
}
}
tab += "</tr>";
}
tab += "</table>";
click = 1;
document.getElementById("Vis_table").innerHTML = tab;
}
};
})(row, col, i);
}
}
Now, this works just fine, and the clicked cell changes color according to the CSS rules. The problem is that I don't know how to go on (ie color the cells between the first and the second clicked cells).
Do you have any suggestion?
Table prepared via JS(to do this in PHP is your task).
Area marking in JS :)
I've split the task in small steps to its easier to understand. If you got questions, feel free to ask!
/* This is generated by PHP (for testing i do it with js here) >>> */
var rows = 5;
var cols = 10;
var $table = $('#myTable');
for( let row = 1; row <= rows; row++ ) {
$row = $('<tr>');
for( let col = 1; col <= cols; col++ ) {
$col = $('<td>');
$col.text(row + "|" + col);
$col.attr('data-row', row);
$col.attr('data-col', col);
$row.append($col);
}
$table.append($row);
}
/* <<< */
var cells = [];
$('#myTable').click(function(e) {
$cell = $(e.target);
cells.unshift($cell);
if(cells.length > 2) {
cells.pop();
}
resetCells();
markActiveCells();
if ( cells.length == 2 ) {
fillArea();
}
});
function resetCells() {
$('#myTable td').removeClass('active');
$('#myTable td').removeClass('area');
}
function markActiveCells() {
$(cells).each(function() {
$(this).addClass('active');
});
}
function fillArea() {
if( cells.length < 2 ) return;
start_row_cell = (cells[0].data('row') <= cells[1].data('row'))?0:1;
start_col_cell = (cells[0].data('col') <= cells[1].data('col'))?0:1;
start_row = cells[start_row_cell].data('row');
end_row = cells[(start_row_cell+1)%2].data('row');
start_col = cells[start_col_cell].data('col');
end_col = cells[(start_col_cell+1)%2].data('col');
for( let row = start_row; row <= end_row; row++ ) {
for( let col = start_col; col <= end_col; col++ ) {
$('#myTable td[data-row=' + row + '][data-col=' + col + ']').addClass('area');
}
}
}
td {
font-size: 10px;
width: 25px;
height: 25px;
background-color: #EEE;
text-align: center;
}
td.active {
background-color: #FA0 !important;
}
td.area {
background-color: #FDA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable" cellspacing=0></table>

Categories