How can I detect if a mouse click was not done on a table row?
I created this table, which can be modified on the fly and highlights the selected row, if selected. Now I try to establish a function, which removes the row highlighting as soon as a mouse click was not done in one of those table rows. I do not want to add another eventListener for the remaining body or other html elements located in the background.
I thought about the following:
if (row highlighted) { next outside click removes row highlight }
JavaScript
x
111
111
1
<!DOCTYPE html>
2
<html>
3
4
<head>
5
<meta charset="utf-8">
6
<meta name="viewport" content="width=device-width, initial-scale=1">
7
8
<title>Table Test</title>
9
<!-- d3.js framework -->
10
<script src="https://d3js.org/d3.v6.js"></script>
11
<!-- jquery import-->
12
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
13
<!-- fontawesome stylesheet https://fontawesome.com/ -->
14
<script src="https://kit.fontawesome.com/39094309d6.js" crossorigin="anonymous"></script>
15
</head>
16
17
<style>
18
#myTable {
19
border-collapse: collapse;
20
}
21
22
#myTable td {
23
border: 1px solid black;
24
padding: 8px;
25
}
26
27
#delRow {
28
width: auto;
29
height: 30px;
30
}
31
32
</style>
33
34
<body>
35
<table id="myTable">
36
<th>
37
Property
38
</th>
39
<th>
40
Value
41
</th>
42
<tbody>
43
<!-- filled by script -->
44
</tbody>
45
</table>
46
47
<button id="dataToArray">dataToArray</button>
48
49
<script>
50
data = [
51
{
52
"property": "animal",
53
"value": "dog"
54
},
55
{
56
"property": "car",
57
"value": "audi"
58
},
59
{
60
"property": "snacks",
61
"value": "chips"
62
}
63
]
64
65
66
//populate table
67
var myTable = document.getElementById("myTable")
68
69
for (var i = 0; i < data.length; i++ ) {
70
var row = `<tr>
71
<td contenteditable='true'>${data[i].property}</td>
72
<td contenteditable='true'>${data[i].value}</td>
73
</tr>`
74
75
myTable.innerHTML += row
76
}
77
78
//higlight row
79
let lastClickedRow = null
80
for (var i = 0, tableRow; tableRow = myTable.rows[i]; i++) {
81
tableRow.addEventListener("click", function() {
82
if (lastClickedRow != null) {
83
lastClickedRow.style.backgroundColor = null
84
}
85
86
lastClickedRow = this
87
88
lastClickedRow.style.backgroundColor = "greenyellow"
89
})
90
}
91
92
//get table data
93
var dataToArray = document.getElementById("dataToArray")
94
95
dataToArray.addEventListener("click", function() {
96
var exportData = []
97
$("table#myTable tr").each(function() {
98
var rowDataObject = new Object
99
var actualData = $(this).find("td");
100
if (actualData.length > 0) {
101
rowDataObject.property = actualData[0].innerText;
102
rowDataObject.value = actualData[1].innerText;
103
exportData.push(rowDataObject)
104
};
105
})
106
console.log(exportData)
107
})
108
</script>
109
</body>
110
111
</html>
Advertisement
Answer
Much simpler solution for this will be
- Add an event listner to the click event of body.
- Check whether the ckick event is either on the button or on the table with
Node.contains
in Javascript Reference - If the table row and button is not clicked, reset the color.
JavaScript
1
72
72
1
data = [
2
{
3
"property": "animal",
4
"value": "dog"
5
},
6
{
7
"property": "car",
8
"value": "audi"
9
},
10
{
11
"property": "snacks",
12
"value": "chips"
13
}
14
]
15
16
17
//populate table
18
var myTable = document.getElementById("myTable")
19
20
for (var i = 0; i < data.length; i++) {
21
var row = `<tr>
22
<td contenteditable='true'>${data[i].property}</td>
23
<td contenteditable='true'>${data[i].value}</td>
24
</tr>`
25
myTable.innerHTML += row
26
}
27
28
//higlight row
29
let lastClickedRow = null;
30
31
function resetColor() {
32
for (var i = 0, tableRow; tableRow = myTable.rows[i]; i++) {
33
tableRow.style.backgroundColor = null;
34
}
35
}
36
37
for (var i = 0, tableRow; tableRow = myTable.rows[i]; i++) {
38
tableRow.addEventListener("click", function (e) {
39
if (lastClickedRow != null) {
40
lastClickedRow.style.backgroundColor = null
41
}
42
lastClickedRow = this
43
lastClickedRow.style.backgroundColor = "greenyellow";
44
})
45
}
46
47
var tableElement = document.getElementById('myTable');
48
var buttonElement = document.getElementById('dataToArray');
49
50
51
document.addEventListener('click', function(event) {
52
const isInsideClicked = tableElement.contains(event.target) || buttonElement.contains(event.target);
53
if(!isInsideClicked) {
54
resetColor();
55
}
56
})
57
58
//get table data
59
var dataToArray = document.getElementById("dataToArray")
60
dataToArray.addEventListener("click", function (e) {
61
var exportData = []
62
$("table#myTable tr").each(function () {
63
var rowDataObject = new Object
64
var actualData = $(this).find("td");
65
if (actualData.length > 0) {
66
rowDataObject.property = actualData[0].innerText;
67
rowDataObject.value = actualData[1].innerText;
68
exportData.push(rowDataObject)
69
};
70
})
71
console.log(exportData)
72
})
JavaScript
1
13
13
1
#myTable {
2
border-collapse: collapse;
3
}
4
5
#myTable td {
6
border: 1px solid black;
7
padding: 8px;
8
}
9
10
#delRow {
11
width: auto;
12
height: 30px;
13
}
JavaScript
1
13
13
1
<table id="myTable">
2
<th>
3
Property
4
</th>
5
<th>
6
Value
7
</th>
8
<tbody>
9
<!-- filled by script -->
10
</tbody>
11
</table>
12
13
<button id="dataToArray">dataToArray</button>