Save content editable HTML table in multiple fields - javascript

I need to develop a HTML table where one of the table column is editable on its row and the table row is dynamic in term of the row number.
I come across a problem where when I automate the saveEdits() function, the code is not working.
Here is my code, where the 'cnt' is a dynamic numeric number. Example cnt=50
<!DOCTYPE html>
<html>
<head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
table ,tr td{
border:1px solid #dddddd;
padding: 8px;
}
tbody {
display:block;
height:600px;
overflow:auto;
}
thead, tbody tr {
display:table;
width:100%;
table-layout:fixed;
}
thead {
width: calc( 100% - 1em )
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<script type="text/javascript">
function saveEdits(cnt) {
//get the editable elements.
var str_out = ''
while (cnt>0){
str1 = '\'edit' + cnt + '\': document.getElementById(\'edit' + cnt + '\').innerHTML,\n'
str_out = str_out.concat(' ', str1);
cnt--;
};
var editElems= { str_out };
alert(editElems)
//save the content to local storage. Stringify object as localstorage can only support string values
localStorage.setItem('userEdits', JSON.stringify(editElems));
}
function checkEdits(){
//find out if the user has previously saved edits
var userEdits = localStorage.getItem('userEdits');
alert(userEdits) // suppose to print {"edit1":" rpeyy7<br>","edit2":" tpruiiy<br>","edit3":" opty<br>"}
if(userEdits){
userEdits = JSON.parse(userEdits);
for(var elementId in userEdits){
document.getElementById(elementId).innerHTML = userEdits[elementId];
}
}
}
</script>
</head>
<body onload="checkEdits()">
<table id="myTable">
<thead>
<tr>
<td style="background-color:#A9A9A9" > Field#1 </td>
<td style="background-color:#A9A9A9" > Field#2 </td>
<td style="background-color:#A9A9A9" > Field#3- Each Row Under field#3 is content EditableByUser </td>
</tr>
</thead>
<tbody>
// Here is the python code that loop through a diectionary content
cnt = 0
for c in sorted(data_dict.keys()) :
cnt += 1
<tr>
<td> {0} </td> //Field#1
<td> {0} </td> //Field#2
...
...
<td id="edit{0}" contenteditable="true" onKeyUp="saveEdits({0});"> {1} </td>\n'.format(cnt,comment)]
</tr>
</table>
</body>
I'm not sure where goes wrong as when I automate the saveEdits() function with 'cnt' in while loop, the above code doesn't works for me. But when I defined each row clearly like below, the data the keyed-in are properly saved to each column.
function saveEdits(cnt) {
//get the editable elements.
var editElems = {
'edit1': document.getElementById('edit1').innerHTML,
'edit2': document.getElementById('edit2').innerHTML,
'edit3': document.getElementById('edit3').innerHTML,
};
alert(editElems) //print [object Object]
//save the content to local storage. Stringify object as localstorage can only support string values
localStorage.setItem('userEdits', JSON.stringify(editElems));
}
I would be much appreciate if someone can point out my mistake. The error is very much likely on saveEdits(cnt) function but I'm not sure how to fix that cause it I define each count 1 by 1, each update that being keyed-in is actually saved properly and able to retrieve when rerun. Thanks you!

Related

Can't get the numeric value from HTML using parseInt or Number in my js function

So I'm trying to complete this simple html page for a friend's project, the goal is to get 2 user entries, minutes and seconds, that will be compared to the data already in the table and if the minutes and seconds entered are greater than one of the time in the table, it will be replaced by the entry.
I've never worked with js except to make some simple prompt or alert so I don't know what I'm supposed to do.
Here is the html, js and css :
function timeEntry() {
var min1 = Number(document.getElementById('firstTimeMin'));
var sec1 = Number(document.getElementById('firstTimeSec'));
var min2 = Number(document.getElementById('secondTimeMin'));
var sec2 = Number(document.getElementById('secondTimeSec'));
var min3 = Number(document.getElementById('thirdTimeMin'));
var sec3 = Number(document.getElementById('thirdTimeSec'));
var entryMin = Number(prompt('What is the time in minutes ?'));
var newTimeMin = entryMin;
var entrySec = Number(prompt('What is the time in seconds'));
var newTimeSec = entrySec;
for (var i = 0; i < 3; i++) {
if (entryMin > min1 && entrySec > sec1) {
document.getElementById('firstTimeMin').innerHTML = newTimeMin;
document.getElementById('firstTimeSec').innerHTML = newTimeSec;
break;
} else if (entryMin > min2 && entrySec > sec2) {
document.getElementById('secondTimeMin').innerHTML = newTimeMin;
document.getElementById('secondTimeSec').innerHTML = newTimeSec;
break;
} else if (entryMin > min3 && entrySec > sec3) {
document.getElementById('thirdTimeMin').innerHTML = newTimeMin;
document.getElementById('thirdTimeSec').innerHTML = newTimeSec;
break;
}
};
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
section {
width: 100%;
height: 100%;
}
table,
td {
width: 40%;
text-align: center;
border: 1px solid black;
border-collapse: collapse;
}
button {
cursor: pointer;
font-weight: 700;
}
<!DOCTYPE html>
<html>
<head>
<title>Table of best times</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="javascript/besttime.js"></script>
</head>
<body>
<section>
<table>
<tbody>
<caption>The best times</caption>
<tr>
<td id="firstTimeMin">1</td>
<td id="firstTimeSec">2</td>
</tr>
<tr>
<td id="secondTimeMin">3</td>
<td id="secondTimeSec">4</td>
</tr>
<tr>
<td id="thirdTimeMin">5</td>
<td id="thirdTimeSec">6</td>
</tr>
</tbody>
</table>
<button onclick="timeEntry()">
Enter a new time
</button>
</section>
</body>
</html>
My idea was to simply get the data already in the table using Number or parseInt to get the number value, but either way from the test I've been doing, when I try to get the element from html, it tells me that I get a number type but when I try to use it in an operation it returns NaN. Maybe I'm just stupid, but I've been reading and looking for a day for a way to get the data from the cells as numbers, but aside from Number or parseInt or using a form, I haven't seen a way to do this and it feels like the more I search the less I understand why it doesn't work.
Any help or clue on how to get this done, even it means start back from scratch would be really appreciated.
document.getElementById('firstTimeMin') only get the DOM Element, you should do document.getElementById('firstTimeMin').innerHTML to get the content of the HTML so you'll be able to get the number using parseInt() or Number.
Do the same with every elements.

JavaScript Save Table Rows added by User

I am making an Electron app that has tables, the user can add a table and change the content of the fields, but I want the input to be saved, and only if the user entered anything into them.
How would I do this? Do I need a database? Can it be done with cookies? I have tried to learn how to use cookies but have not found how to save an added element as well as the content.
function appendRow(id) {
var table = document.getElementById(id); // table reference
length = table.length,
row = table.insertRow(table.rows.length); // append table row
var i;
// insert table cells to the new row
for (i = 0; i < table.rows[0].cells.length; i++) {
createCell(row.insertCell(i), i, 'row');
}
}
function createCell(cell, text, style) {
var div = document.createElement('div'), // create DIV element
txt = document.createTextNode('_'); // create text node
div.appendChild(txt); // append text node to the DIV
div.setAttribute('id', style); // set DIV class attribute
div.setAttribute('idName', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
}
table {
text-align: center;
width: 400px;
}
tr:nth-child(even) {
background-color: #ccc;
}
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<link rel="stylesheet" href="test.css">
</head>
<body>
<button id="addCust" class="addSort" onclick="appendRow('custList')">add customer</button>
<table id="custListTop" contenteditable="false" style="background-color: #ccc;">
<tr>
<td style="border-top-left-radius: 5px;">Customers</td>
<td style="border-top-right-radius: 5px;">Main Location</td>
</tr>
</table>
<table id="custList" contenteditable="true">
<tr>
<td>Someone</td>
<td>something</td>
</tr>
</table>
<script src="test.js"></script>
</body>
</html>
Well how you are going to save it depends on what you want to do. If you want it to persist after your program was exited, you will need to save it on the disk or on a server somehow. You probably just want to save it into a file, though. (JSON is the most obvious choice). Otherwise, just save it into a js variable.
To get the data, I would either use a save button that reads the text of your cells, or use databinding. Later is very useful for Electron apps. You can either use a framework (like vue.js, react.js or many more) or DIY.
Former is probably easier and you will want a button to save it to the disk anyways. On the click of the button you can just go through all <tr>-elements and get their values and save them.
function save(id) {
var table = document.getElementById(id);
var trs = table.getElementsByTagName('tr'); // list of all rows
var values = []; // will be a (potentially jagged) 2D array of all values
for (var i = 0; i < trs.length; i++) {
// loop through all rows, each will be one entrie in values
var trValues = [];
var tds = trs[i].getElementsByTagName('td'); // list of all cells in this row
for (var j = 0; j < tds.length; j++) {
trValues[j] = tds[j].innerText;
// get the value of the cell (preserve newlines, if you don't want that use .textContent)
}
values[i] = trValues;
}
// save values
console.log(values);
}
function appendRow(id) {
var table = document.getElementById(id); // table reference
length = table.length,
row = table.insertRow(table.rows.length); // append table row
var i;
// insert table cells to the new row
for (i = 0; i < table.rows[0].cells.length; i++) {
createCell(row.insertCell(i), i, 'row');
}
}
function createCell(cell, text, style) {
var div = document.createElement('div'), // create DIV element
txt = document.createTextNode('_'); // create text node
div.appendChild(txt); // append text node to the DIV
div.setAttribute('id', style); // set DIV class attribute
div.setAttribute('idName', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
}
table {
text-align: center;
width: 400px;
}
tr:nth-child(even) {
background-color: #ccc;
}
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<link rel="stylesheet" href="test.css">
</head>
<body>
<button id="addCust" class="addSort" onclick="appendRow('custList')">add customer</button>
<button id="save" class="save" onclick="save('custList')">save</button>
<table id="custListTop" contenteditable="false" style="background-color: #ccc;">
<tr>
<td style="border-top-left-radius: 5px;">Customers</td>
<td style="border-top-right-radius: 5px;">Main Location</td>
</tr>
</table>
<table id="custList" contenteditable="true">
<tr>
<td>Someone</td>
<td>something</td>
</tr>
</table>
<script src="test.js"></script>
</body>
</html>

Javascript sorting a csv rows and displaying in table

I have a csv file which has this format:
Major;2;4;29
Major should be displayed on the 4 row 2 column.
The file can have a lot nof rows!
I have created this:
var fileInput = document.getElementById("csv"),
readFile = function () {
var reader = new FileReader();
reader.onload = function () {
document.getElementById('out').innerHTML = reader.result;
};
reader.readAsBinaryString(fileInput.files[0]);
};
fileInput.addEventListener('change', readFile);
<style type="text/css">
output {
display: block;
margin-top: 4em;
font-family: monospace;
font-size: .8em;
}
</style>
which basically takes a csv file as an input and prints all as it is raw!How can I work and divide the rows on the ";"?And I also want an honest answer what level is this for?(intern,senior?)
Here's a trivial example, it's fairly straight forward. The issue will be splitting the data, it's pretty simple if the data is simple and the delimiter unique. But if the delimiter is in the data, the splitting into values requires a little more cleverness.
This uses table.rows to get the row, then row.cells to get the cell and inserts the value. Columns and rows are zero indexed, and for rows includes the header and footer (if they exist). You can also use the tbody.rows if the header rows should be skipped.
var data = 'Major;1;2;29\nMinor;2;3;29';
function insertData(id, data) {
// Show data
console.log(data);
// Get the table
var table = document.getElementById(id);
// Split the data into records
var dataRows = data.split(/\n/);
// Split each row into values and insert in table
if (table) {
dataRows.forEach(function(s) {
var x = s.split(';');
table.rows[x[2]].cells[x[1]].textContent = x[0];
});
}
}
table {
border-collapse: collapse;
border-left: 1px solid #999999;
border-top: 1px solid #999999;
}
td, th {
border-right: 1px solid #999999;
border-bottom: 1px solid #999999;
}
<table id="t0">
<thead>
<tr>
<th>col 0<th>col 1<th>col 2
</thead>
<tbody>
<tr>
<td> <td><td>
<tr>
<td> <td><td>
<tr>
<td> <td><td>
</tbody>
</table>
<button onclick="insertData('t0', data)">Insert data</button>

JavaScript how to get this html to read this CSS and organise my script into the table

How it looks:
How I want it to look:
I have a CSS file that has a table all organised and ready my question is how do I get my script to use the table in the CSS file this is my CSS file:
/*
styles.css
*/
body{
background-color:#cecece;
color:#fff;
font-family: Arial, Tahoma, Sans-Serif;
font-size:1em;
}
h1{
color:#FF8000;
text-align:center;
}
table{
width:95%;
}
caption{
font-size:1.2em;
margin:10px;
color:#FF8000;
}
th{
width:33.333%;
font-size:1.1em;
text-align:left;
color:steelblue;
}
#output{
position:absolute;
width:50%;
height:70%;
top:15%;
left:25%;
margin:0px;
padding:10px;
font-size:.9em;
background-color:#2E2E2E;
color:ivory;
}
this is my Html document that calls the css and my script
<html lang="en">
<head>
<title>Student Grades - [Your Name]</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<h1>Student Grades System</h1>
<div id="output"></div>
<script src="./assignment.js"></script>
</body>
</html>
This is my JavaScript that prints everything out if u need more of the script let me know
var mytable = "<table><caption>Grading Results</caption>";
document.write(mytable);
document.write('<td><tr><th>' + "Student"+'</th><th>' + "Mark!" + '</th><th>'+"Grade" + '</th> </tr></td>');
for(var i = 0; i < markArr.length; i++){
document.write(' <tr><td>'+studentArr[i] + space1+markArr[i] + space1+gradeAwarded[i] + '</td> </th> ');
}
document.write(' </tr>');
document.write('<td>'+ "The Highest mark was : "+max+ ''+'</td> </th>');
document.write('<td>' + "The Lowest mark was : "+min+''+'</td> </th>');
document.write('<td>'+ "The Average mark was : "+average+''+'</td> </th>');
document.write('<td>' + "number A grades : "+A+''+'</td> </th>');
document.write('<td>'+ "number B grades : "+B+''+'</td> </th>');
document.write('<td>'+ "number C grades : "+C+''+'</td> </th>');
document.write('<td>'+ "number F grades : "+F+''+'</td> </th>');
document.write('</table>');
Try this
Add the code below before the for loop:
document.write('<table><caption>My Caption</caption>');
and this after the loop:
document.write('</table>');
The problem you told me happened because the <div> was closed before the <table> was created. Try this:
<div id="output">
<script src="./assignment.js"></script>
</div>
together with my code above.
Hope it works!
A HTML table generally has the format
<table>
<tr>
<th>Header1</th>
<th>Header2</th>
</tr>
<tr>
<td>Item1Row1</td>
<td>Item1Row2</td>
</tr>
<tr>
<td>Item2Row1</td>
<td>Item2Row2</td>
</tr>
</table>
Try creating a variable and build the html object as a string, then adding it to a element.
something like this:
var myTable= "<table><tr><td style='width: 100px; color: red;'>Col Head 1</td>";
myTable+= "<td style='width: 100px; color: red; text-align: right;'>Col Head 2</td>";
myTable+="<td style='width: 100px; color: red; text-align: right;'>Col Head 3</td></tr></table>";
document.getElementById('body').innerHTML = myTable
Try this
Add the code below before the for loop:
var mytable = "<table><caption>My Caption</caption>";
and this after the loop:
document.write(mytable +'</table>');
#HelloWorld, here you go. Click on CSS and JavaScript tabs to see how I set it up
http://jsbin.com/cogux/1/edit?html,output
Without knowing what assignment.js does, the main steps would be:
Create/compile a data set you can loop through
Dynamically create the table rows and data
Create the statistics area for top student, marks and number of grades (just refer to how I set up #2)
Insert table into a target element. In the case for #2 the target was the <tbody> element
I hope this helps.

HTML/CSS/Javascript - Align Text In Table

I am trying to align the text in my table. It currently looks like this:
I would like to align the tile (in bold) in the center. Also, I am trying to get the values on the right, moved to the left.
Currently I have:
Javascript:
var table = $('<table/>',
{
id: 'table',
"class":'tables'
});
// ************************ Row 1 ************************************
row1 = $('<tr></tr>');
var head = $('<th></th>').addClass('dealHead').text(value.dealTitle);
row1.append(head);
table.append(row1);
// ********************************************************************
// ************************ Row 2 ************************************
row2 = $('<tr></tr>');
var col1 = $('<td></td>').addClass('name').text("Name: ");
var col2 = $('<td></td>').addClass('nameValue').text(value.name);
row2.append(col1);
row2.append(col2);
table.append(row2);
// ********************************************************************
// ************************ Row 3 ************************************
row3 = $('<tr></tr>');
col1 = $('<td></td>').addClass('address').text("Address: ");
col2 = $('<td></td>').addClass('addressValue').text(value.address);
row3.append(col1);
row3.append(col2);
table.append(row3);
// ********************************************************************
table.appendTo('body')
CSS:
body
{
background-color:#5CD65C;
}
.dealHead
{
text-align:center;
}
.name
{
border-top:thick double #0F0F00;
border-left:thick double #0F0F00;
border-bottom:thick double #0F0F00;
}
.nameValue
{
border-top:thick double #0F0F00;
border-right:thick double #0F0F00;
border-bottom:thick double #0F0F00;
text-align:left;
}
.address
{
border-top:thick double #0F0F00;
border-left:thick double #0F0F00;
border-bottom:thick double #0F0F00;
}
.addressValue
{
border-top:thick double #0F0F00;
border-right:thick double #0F0F00;
border-bottom:thick double #0F0F00;
text-align:left;
}
.tables
{
width="400";
border-collapse: collapse;
}
HTML
Pretty much an empty <body>
Would anyone know what I am doing wrong here?
In order to center the header you add colspan=2 that works,align the td's you have a class so add text-align-left like this
row1 = $('<tr></tr>');
var head = $('<th colspan="2"></th>').addClass('dealHead').text(value.dealTitle);
CSS
.test td {
text-align: right;
}
Example HTML
<table class="test">
<tr>
<th colspan="2">Title</th>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
</tr>
</table>
CSS
.tables { width="400"; ...
should be
.tables { width: 400px; ...
In order to have both cells the same with:
.tables td { width: 50%; }
Javascript
var head = $('<th></th>').addClass('dealHead').text(value.dealTitle);
This is only one cell, make it like two:
var head = $('<th colspan="2"></th>').addClass('dealHead').text(value.dealTitle);
jsFiddle
if this is plain html, I could have made the header <th> to be of colspan=2.
similarly make your header
var head = $('<th colspan="2"></th>').addClass('dealHead').text(value.dealTitle);
hope this would help.

Categories