Electron's localstorage not saving my on-click events on dynamically created elements
I am creating a desktop application using Electron and I'm running into an issue regarding the local storage of on click events.
In my application, the user enters 5 groups of information (publication name, publisher name, status, submission date, response date)
the information is then placed into an HTML table through the D.O.M, where it is separated into rows by entry and columns by information category with Remove and Edit buttons on the far right columns.
e.g.
|name1|publisher1|awaiting|noDate|NoDate2|[RemoveButton][EditButton]|
|name2|publisher2|denied|noDate3|NoDate4|[RemoveButton]|[EditButton]|
|name3|publisher3|accepted|noDate5|NoDate6|[RemoveButton]|[EditButton]|
and so on, as the user enters more entries, the more rows are appended to the table. Each row that is appended, however, always has the 2 remove and edit buttons on the right. I have assigned a function to these 2 buttons like this:
The Remove Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
};
The Edit Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
};
(To elaborate further on the edit button, It deletes the row that the button is in and re enters all the column entries publication name, status, etc. back into the textfields to be revised and resubmitted.)
(Formatting of code may not be exact, as I am not used to formatting it on here)
These buttons do their job during an active session (when the submissions are added as the application is running) but when I close the application and reopen it and/or force reload it, the buttons seem to lose their functionality. I believe this to be some sort of issue with how I'm storing my local storage.
What I do find strange, however, I have a "clear all button" that essentially clears all the content in the table. This button is formatted in the same way the other buttons are but it is not dynamically generated like them. Because of this, it leads me to believe there is a problem in how my functions are being declared.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
Here is the full code snippet:
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
The snippet is not entirely accurate as my application is run through Node and Electron.
If I haven't made things clear enough, feel free to ask me questions to clear up confusion.
If you have any solutions to this, or tips for my bad code and practices I appreciate any feedback.
Thanks.
javascript html node.js local-storage electron
add a comment |
I am creating a desktop application using Electron and I'm running into an issue regarding the local storage of on click events.
In my application, the user enters 5 groups of information (publication name, publisher name, status, submission date, response date)
the information is then placed into an HTML table through the D.O.M, where it is separated into rows by entry and columns by information category with Remove and Edit buttons on the far right columns.
e.g.
|name1|publisher1|awaiting|noDate|NoDate2|[RemoveButton][EditButton]|
|name2|publisher2|denied|noDate3|NoDate4|[RemoveButton]|[EditButton]|
|name3|publisher3|accepted|noDate5|NoDate6|[RemoveButton]|[EditButton]|
and so on, as the user enters more entries, the more rows are appended to the table. Each row that is appended, however, always has the 2 remove and edit buttons on the right. I have assigned a function to these 2 buttons like this:
The Remove Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
};
The Edit Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
};
(To elaborate further on the edit button, It deletes the row that the button is in and re enters all the column entries publication name, status, etc. back into the textfields to be revised and resubmitted.)
(Formatting of code may not be exact, as I am not used to formatting it on here)
These buttons do their job during an active session (when the submissions are added as the application is running) but when I close the application and reopen it and/or force reload it, the buttons seem to lose their functionality. I believe this to be some sort of issue with how I'm storing my local storage.
What I do find strange, however, I have a "clear all button" that essentially clears all the content in the table. This button is formatted in the same way the other buttons are but it is not dynamically generated like them. Because of this, it leads me to believe there is a problem in how my functions are being declared.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
Here is the full code snippet:
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
The snippet is not entirely accurate as my application is run through Node and Electron.
If I haven't made things clear enough, feel free to ask me questions to clear up confusion.
If you have any solutions to this, or tips for my bad code and practices I appreciate any feedback.
Thanks.
javascript html node.js local-storage electron
add a comment |
I am creating a desktop application using Electron and I'm running into an issue regarding the local storage of on click events.
In my application, the user enters 5 groups of information (publication name, publisher name, status, submission date, response date)
the information is then placed into an HTML table through the D.O.M, where it is separated into rows by entry and columns by information category with Remove and Edit buttons on the far right columns.
e.g.
|name1|publisher1|awaiting|noDate|NoDate2|[RemoveButton][EditButton]|
|name2|publisher2|denied|noDate3|NoDate4|[RemoveButton]|[EditButton]|
|name3|publisher3|accepted|noDate5|NoDate6|[RemoveButton]|[EditButton]|
and so on, as the user enters more entries, the more rows are appended to the table. Each row that is appended, however, always has the 2 remove and edit buttons on the right. I have assigned a function to these 2 buttons like this:
The Remove Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
};
The Edit Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
};
(To elaborate further on the edit button, It deletes the row that the button is in and re enters all the column entries publication name, status, etc. back into the textfields to be revised and resubmitted.)
(Formatting of code may not be exact, as I am not used to formatting it on here)
These buttons do their job during an active session (when the submissions are added as the application is running) but when I close the application and reopen it and/or force reload it, the buttons seem to lose their functionality. I believe this to be some sort of issue with how I'm storing my local storage.
What I do find strange, however, I have a "clear all button" that essentially clears all the content in the table. This button is formatted in the same way the other buttons are but it is not dynamically generated like them. Because of this, it leads me to believe there is a problem in how my functions are being declared.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
Here is the full code snippet:
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
The snippet is not entirely accurate as my application is run through Node and Electron.
If I haven't made things clear enough, feel free to ask me questions to clear up confusion.
If you have any solutions to this, or tips for my bad code and practices I appreciate any feedback.
Thanks.
javascript html node.js local-storage electron
I am creating a desktop application using Electron and I'm running into an issue regarding the local storage of on click events.
In my application, the user enters 5 groups of information (publication name, publisher name, status, submission date, response date)
the information is then placed into an HTML table through the D.O.M, where it is separated into rows by entry and columns by information category with Remove and Edit buttons on the far right columns.
e.g.
|name1|publisher1|awaiting|noDate|NoDate2|[RemoveButton][EditButton]|
|name2|publisher2|denied|noDate3|NoDate4|[RemoveButton]|[EditButton]|
|name3|publisher3|accepted|noDate5|NoDate6|[RemoveButton]|[EditButton]|
and so on, as the user enters more entries, the more rows are appended to the table. Each row that is appended, however, always has the 2 remove and edit buttons on the right. I have assigned a function to these 2 buttons like this:
The Remove Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
};
The Edit Button:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
};
(To elaborate further on the edit button, It deletes the row that the button is in and re enters all the column entries publication name, status, etc. back into the textfields to be revised and resubmitted.)
(Formatting of code may not be exact, as I am not used to formatting it on here)
These buttons do their job during an active session (when the submissions are added as the application is running) but when I close the application and reopen it and/or force reload it, the buttons seem to lose their functionality. I believe this to be some sort of issue with how I'm storing my local storage.
What I do find strange, however, I have a "clear all button" that essentially clears all the content in the table. This button is formatted in the same way the other buttons are but it is not dynamically generated like them. Because of this, it leads me to believe there is a problem in how my functions are being declared.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
Here is the full code snippet:
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
The snippet is not entirely accurate as my application is run through Node and Electron.
If I haven't made things clear enough, feel free to ask me questions to clear up confusion.
If you have any solutions to this, or tips for my bad code and practices I appreciate any feedback.
Thanks.
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
javascript html node.js local-storage electron
javascript html node.js local-storage electron
edited Nov 21 at 7:23
Abhijit
317213
317213
asked Nov 21 at 7:04
Trent Hardy
61
61
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
After further examination, I have found the problem. The on click events on the buttons were being assigned in the session but the local storage could not store the events because they weren't strings.
To solve this:
Leave your on click events on your add button so that they function during the session, but add a for loop on the page load for the buttons you wish to use. Make sure you assign a class for your element during the button click to reference it on the page load.
e.g.
window.onload = function() {
var savedInner = localStorage.getItem("listStorageInner");
var savedOuter = localStorage.getItem("listStorageOuter");
// If there are any saved items, update our list
if (savedInner) {
let targetList = document.getElementById("projectList");
targetList.innerHTML = savedInner;
}
if (savedOuter) {
let targetList = document.getElementById("projectList");
targetList.outerHTML = savedOuter;
}
var removeButtons = document.getElementsByClassName("removeMeBtn");
for (let i = 0; i < removeButtons.length; i++) {
removeButtons[i].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(i),
false
);
}
var editBtns = document.getElementsByClassName("editMeBtn");
for (let j = 0; j < editBtns.length; j++) {
editBtns[j].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
document.getElementById("entryInput").value = parent.textContent;
parent.focus();
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(j),
false
);
}
};
The for loop goes through all elements that have the class names of the buttons, then assigns the onclick event on the page load. That way the button click events always work and save properly through local storage. Also, make sure to watch the scope when it comes to using local storage.
Hope this helps if someone else encounters this issue.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53406835%2felectrons-localstorage-not-saving-my-on-click-events-on-dynamically-created-ele%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
After further examination, I have found the problem. The on click events on the buttons were being assigned in the session but the local storage could not store the events because they weren't strings.
To solve this:
Leave your on click events on your add button so that they function during the session, but add a for loop on the page load for the buttons you wish to use. Make sure you assign a class for your element during the button click to reference it on the page load.
e.g.
window.onload = function() {
var savedInner = localStorage.getItem("listStorageInner");
var savedOuter = localStorage.getItem("listStorageOuter");
// If there are any saved items, update our list
if (savedInner) {
let targetList = document.getElementById("projectList");
targetList.innerHTML = savedInner;
}
if (savedOuter) {
let targetList = document.getElementById("projectList");
targetList.outerHTML = savedOuter;
}
var removeButtons = document.getElementsByClassName("removeMeBtn");
for (let i = 0; i < removeButtons.length; i++) {
removeButtons[i].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(i),
false
);
}
var editBtns = document.getElementsByClassName("editMeBtn");
for (let j = 0; j < editBtns.length; j++) {
editBtns[j].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
document.getElementById("entryInput").value = parent.textContent;
parent.focus();
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(j),
false
);
}
};
The for loop goes through all elements that have the class names of the buttons, then assigns the onclick event on the page load. That way the button click events always work and save properly through local storage. Also, make sure to watch the scope when it comes to using local storage.
Hope this helps if someone else encounters this issue.
add a comment |
After further examination, I have found the problem. The on click events on the buttons were being assigned in the session but the local storage could not store the events because they weren't strings.
To solve this:
Leave your on click events on your add button so that they function during the session, but add a for loop on the page load for the buttons you wish to use. Make sure you assign a class for your element during the button click to reference it on the page load.
e.g.
window.onload = function() {
var savedInner = localStorage.getItem("listStorageInner");
var savedOuter = localStorage.getItem("listStorageOuter");
// If there are any saved items, update our list
if (savedInner) {
let targetList = document.getElementById("projectList");
targetList.innerHTML = savedInner;
}
if (savedOuter) {
let targetList = document.getElementById("projectList");
targetList.outerHTML = savedOuter;
}
var removeButtons = document.getElementsByClassName("removeMeBtn");
for (let i = 0; i < removeButtons.length; i++) {
removeButtons[i].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(i),
false
);
}
var editBtns = document.getElementsByClassName("editMeBtn");
for (let j = 0; j < editBtns.length; j++) {
editBtns[j].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
document.getElementById("entryInput").value = parent.textContent;
parent.focus();
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(j),
false
);
}
};
The for loop goes through all elements that have the class names of the buttons, then assigns the onclick event on the page load. That way the button click events always work and save properly through local storage. Also, make sure to watch the scope when it comes to using local storage.
Hope this helps if someone else encounters this issue.
add a comment |
After further examination, I have found the problem. The on click events on the buttons were being assigned in the session but the local storage could not store the events because they weren't strings.
To solve this:
Leave your on click events on your add button so that they function during the session, but add a for loop on the page load for the buttons you wish to use. Make sure you assign a class for your element during the button click to reference it on the page load.
e.g.
window.onload = function() {
var savedInner = localStorage.getItem("listStorageInner");
var savedOuter = localStorage.getItem("listStorageOuter");
// If there are any saved items, update our list
if (savedInner) {
let targetList = document.getElementById("projectList");
targetList.innerHTML = savedInner;
}
if (savedOuter) {
let targetList = document.getElementById("projectList");
targetList.outerHTML = savedOuter;
}
var removeButtons = document.getElementsByClassName("removeMeBtn");
for (let i = 0; i < removeButtons.length; i++) {
removeButtons[i].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(i),
false
);
}
var editBtns = document.getElementsByClassName("editMeBtn");
for (let j = 0; j < editBtns.length; j++) {
editBtns[j].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
document.getElementById("entryInput").value = parent.textContent;
parent.focus();
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(j),
false
);
}
};
The for loop goes through all elements that have the class names of the buttons, then assigns the onclick event on the page load. That way the button click events always work and save properly through local storage. Also, make sure to watch the scope when it comes to using local storage.
Hope this helps if someone else encounters this issue.
After further examination, I have found the problem. The on click events on the buttons were being assigned in the session but the local storage could not store the events because they weren't strings.
To solve this:
Leave your on click events on your add button so that they function during the session, but add a for loop on the page load for the buttons you wish to use. Make sure you assign a class for your element during the button click to reference it on the page load.
e.g.
window.onload = function() {
var savedInner = localStorage.getItem("listStorageInner");
var savedOuter = localStorage.getItem("listStorageOuter");
// If there are any saved items, update our list
if (savedInner) {
let targetList = document.getElementById("projectList");
targetList.innerHTML = savedInner;
}
if (savedOuter) {
let targetList = document.getElementById("projectList");
targetList.outerHTML = savedOuter;
}
var removeButtons = document.getElementsByClassName("removeMeBtn");
for (let i = 0; i < removeButtons.length; i++) {
removeButtons[i].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(i),
false
);
}
var editBtns = document.getElementsByClassName("editMeBtn");
for (let j = 0; j < editBtns.length; j++) {
editBtns[j].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
document.getElementById("entryInput").value = parent.textContent;
parent.focus();
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(j),
false
);
}
};
The for loop goes through all elements that have the class names of the buttons, then assigns the onclick event on the page load. That way the button click events always work and save properly through local storage. Also, make sure to watch the scope when it comes to using local storage.
Hope this helps if someone else encounters this issue.
answered Nov 24 at 7:05
Trent Hardy
61
61
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53406835%2felectrons-localstorage-not-saving-my-on-click-events-on-dynamically-created-ele%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown