Reading data from text boxes inside a table - javascript

I have the following two function in my code, the addValueToSTorage has to read the editable table data and add the values to the localStorage and the populate table reads the values from localStorage and populates the table with the updated values and makes the table non-editable.
function addValueToStorage() {
localStorage.clear();
var table = document.getElementById('table');
var i;
var j;
var rowLength = table.rows.length;
for (i = 0; i < rowLength; i++) {
var value=[];
for (j = 0; j < 4; j++) {
value.push(table.rows[i].cells[j].firstChild.data);
}
var val=JSON.stringify(value);
var key = "xyz" + localStorage.length;
localStorage.setItem(key, val);
}
populatetable();
}
function populatetable() {
$('#table').empty();
var header = "<tr><th>Select</th><th>Name</th><th>1</th><th>2</th><th>3</th></tr>";
$('#table').append(header);
for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
if (key.substring(0, 5) == "xyz") {
var value = JSON.parse(localStorage.getItem(key));
var xyzvalue = "<tr><td><input type=\"checkbox\" value=" + key + "></td><td><input type=\"text\" value=" + value[0] + "></td><td><input type=\"text\" value=" + value[1] + "</td><td><input type=\"text\" value=" + value[2] + "</td><td><input type=\"text\" value=" + value[3] + "</td></tr>";
$('#table').append(xyzvalue);
}
}
$('#table:input').prop("disabled", true);
}
The addValueToStorage is able to read data from the cells of a normal table, but since my table is editable I have used textboxes inside the table and the addValueToStorage is not able to read the data from the cells and also the table size is completely distorted and is overflowing the div enclosing it because of the textboxes.
Any help on extracting the data and setting the size of the table is greatly appreciated. Thanks in Advance

try changing:
for (i = 0; i < rowLength; i++) {
var value=[];
for (j = 0; j < 4; j++) {
value.push(table.rows[i].cells[j].firstChild.data);
}
var val=JSON.stringify(value);
var key = "xyz" + localStorage.length;
localStorage.setItem(key, val);
}
to
for (i = 0; i < rowLength; i++) {
var value=[];
for (j = 0; j < 4; j++) {
// getAttribute is probably what you're after here
value.push(table.rows[i].cells[j].firstChild.getAttribute('value'));
}
var val=JSON.stringify(value);
var key = "xyz" + localStorage.length;
localStorage.setItem(key, val);
}

Related

Despite my eventlistener, my function will still run regardless

I'm trying to make a game and a form that gets information from the user via an input.
I would like my function that starts the game to run after the user places an input and clicks my
"play game" button, but the function that starts the game will run regardless of whether or not the button is pressed. Thanks.
"use strict";
window.onload = main;
function main()
{
var symbolAmount = 0;
document.getElementById("numSymbols").value = symbolAmount;
//symbolAmount cannot be greater than 8
if (symbolAmount > 8)
{
symbolAmount = 8;
}
document.getElementById('startButton').addEventListener("click", startGame(symbolAmount));
}
function startGame(symbolAmount)
{
//getting rid of the startup form
//symbols array being loaded and the various variables for the table setup
var symbols = new Array("!", "#", "#", "$", ";", "+", "*", "&");
var gameHtmlInfo = "<table id= 'gameTable' \
style= \
'width:60%; \
margin-left:20%:\
max-height:60%; \
'>";
var columnCount;
var rowCount;
//setting the columns and rows for the table
if ((symbolAmount*2 === 4) || (symbolAmount*2 === 16))
{
columnCount = (symbolAmount/2);
rowCount = (symbolAmount/2);
}
else
{
columnCount = symbolAmount;
rowCount = 2;
}
//making the tables
for(var i = 0; i < rowCount; i++)
{
gameHtmlInfo += "<tr class='rows'>";
//making the cells
for(var j = 0; j < columnCount; j++)
{
gameHtmlInfo += "<td class='card'>" + symbols[j] + "</td>";
symbols.shift();
}
gameHtmlInfo += "</tr>";
}
gameHtmlInfo += "</table>";
}
You actually call the startGame function when registering the event. Try wrapping the function with either arrow-function or just a normal funcion:
document.getElementById('startButton').addEventListener("click", () => startGame(symbolAmount));
This pattern is also known as Curry.
The curent code immediately invokes your startGame function as you create a subscription to the click event of your button.
change your function to return a callback like so.
function startGame(symbolAmount) {
return function () {
//getting rid of the startup form
//symbols array being loaded and the various variables for the table setup
var symbols = new Array("!", "#", "#", "$", ";", "+", "*", "&");
var gameHtmlInfo = "<table id= 'gameTable' \
style= \
'width:60%; \
margin-left:20%:\
max-height:60%; \
'>";
var columnCount;
var rowCount;
//setting the columns and rows for the table
if ((symbolAmount * 2 === 4) || (symbolAmount * 2 === 16)) {
columnCount = (symbolAmount / 2);
rowCount = (symbolAmount / 2);
}
else {
columnCount = symbolAmount;
rowCount = 2;
}
//making the tables
for (var i = 0; i < rowCount; i++) {
gameHtmlInfo += "<tr class='rows'>";
//making the cells
for (var j = 0; j < columnCount; j++) {
gameHtmlInfo += "<td class='card'>" + symbols[j] + "</td>";
symbols.shift();
}
gameHtmlInfo += "</tr>";
}
gameHtmlInfo += "</table>";
}
}

Copy row from any table

I have an HTML page with 3 tables on it. I want to be able to copy specific cells in a table row to the clipboard. The row could come from any of the 3 tables.
Using the code below, I highlight and copy the row for a table with an ID of "final". How do I make this work for any of the 3 tables? I tried by getElementsByTagName and labeling them the same name but did not work - understandably so. Is there a way to designate the selected table? I am trying to avoid copying the whole row and might eventually add the formatted msg to a new page rather than copy to the clipboard.
function copy_highlight_row() {
var table = document.getElementById('final');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
var cellId = this.cellIndex + 1
msg = 'Title: ' + rowSelected.cells[0].innerHTML;
msg += '\r\nDescription: ' + rowSelected.cells[1].innerHTML;
msg += '\n\nLink: ' + rowSelected.cells[2].innerHTML;
msg += '\nPublication Date: ' + rowSelected.cells[3].innerHTML;
//msg += '\nThe cell value is: ' + this.innerHTML copies cell selected
navigator.clipboard.writeText(msg);
}
}
};
Based on a couple of the suggestions I came up with the following:
function highlight_row() {
var cells = document.querySelectorAll('td')
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var t_ID = this.closest('table').id
var table=document.getElementById(t_ID);
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
var cellId = this.cellIndex + 1
msg = 'Title: ' + rowSelected.cells[0].innerHTML;
msg += '\r\nDescription: ' + rowSelected.cells[1].innerHTML;
msg += '\n\nLink: ' + rowSelected.cells[2].innerHTML;
msg += '\nPublication Date: ' + rowSelected.cells[3].innerHTML;
navigator.clipboard.writeText(msg);
}
}
}
At the end of the html I call the function. The HTML contains 3 tables and this enabled me to click on any table, highlight the row, and copy the correct range of cells.

How to display selected file names before uploading multiple files in javascript

How to use table instead of list for alignment. Also ones we click the cancel button the file list need to be deleted from list.
updateList = function () {
var input = document.getElementById('fileUploader');
var output = document.getElementById('divFiles');
output.innerHTML = '<ul style="list-style-type:none">';
for (var i = 0; i < input.files.length; ++i) {
output.innerHTML += '<li>' + input.files.item(i).name + ' <button>X</button></li> ';
}
output image for the above code
updateList = function () {
var input = document.getElementById('fileUploader');
var output = document.getElementById('divFiles');var HTML = "<table>";
for (var i = 0; i < input.files.length; ++i)
{
HTML += "<tr><td>" + input.files.item(i).name + "</td><td> <button>X</button></td></tr>";
}
HTML += "</table>";
output.innerHTML = HTML;
}

How do I apply code to a dynamically created element

The following code works only if the table is already present in the document upon page load. I however want it to apply on a dynamically created table.
Can this be done?
var colNumber=22
for (var i=0; i<colNumber; i++)
{
var thWidth=$("#tbl").find("th:eq("+i+")").width();
var tdWidth=$("#tbl").find("td:eq("+i+")").width();
if (thWidth<tdWidth)
$("#tbl").find("th:eq("+i+")").width(tdWidth);
else
$("#tbl").find("td:eq("+i+")").width(thWidth);
}
The table is created in the following way:
function loadFile(event){
alasql('SELECT * FROM FILE(?,{headers:false})',[event],function(data){
var keys = [];
for (var i = 0; i < data.length; i++) {
for (var categoryid in data[i]) {
var category = data[i][categoryid];
keys.push(categoryid);
}
}
keysConverted = keys.map(foo);
var vMin = Math.min.apply(null, keysConverted);
var vMax = Math.max.apply(null, keysConverted);
var start = vMin-1
var ColNeeded = vMax - vMin+1;
var arrExcel2Table = '<table id="tbl">';
for (var i = 0; i < data.length; i++){
arrExcel2Table = arrExcel2Table + '<tr>';
for (var j = 0; j < ColNeeded; j++){
cellValue = data[i][number2Letter(j+start)];
if (typeof cellValue === "undefined"){
cellValue = '';
}
arrExcel2Table = arrExcel2Table + '<td>' + cellValue + '</td>';
}
arrExcel2Table = arrExcel2Table + '</tr>';
}
arrExcel2Table = arrExcel2Table + '</table>';
document.getElementById('excel_table').innerHTML = arrExcel2Table;
});
}
Create a function you want to run and add an event from the dynamic element. For example
arrExcel2Table = arrExcel2Table + '<td>' + cellValue + '</td>';
can be replaced by
arrExcel2Table = arrExcel2Table + '<td onclick="myFunction();">' + cellValue + '</td>';
Above code will call the function you created
myFunction() {
alert();
}
Just create your table, then apply whatever code you want to it :
$('#excel_table').html(arrExcel2Table);
adjustWidth()
function adjustWidth(){
var $tbl = $("#tbl"); // And cache your jQuery objects!! Massive performance boost
for (var i=0; i<colNumber; i++)
{
var $th = $tbl.find("th:eq("+i+")"),
$td = $tbl.find("td:eq("+i+")"),
thWidth = $th.width(),
tdWidth = $td.width();
if (thWidth<tdWidth)
$th.width(tdWidth);
else
$td.width(thWidth);
}
}

Access to a variable prints undefined?

Hi i tried to access a variable as follows,
for(var k=0;k<resultSet.length;k++)
{
alert(resultSet[k]);
$.get('/api/TagsApi/ElementsTagsIntersect?ids='+resultSet[k], function (data) {
testingarr = [];
for (var i = 0; i < data.length; i++) {
testingarr.push(data[i]["ID"]);
}
for (var w = 0; w <3; w++) {
if (($.inArray(testingarr[w], selectedloc)) > -1) {
var str = "<input type='checkbox' name ='test[]' value='" + resultSet[k] + "'/>" + resultSet[k] + "</br>";
$('#childs').append(str);
alert(resultSet[k]);
break;
}
}
}, 'json');
where first alert displays the exact value what i am expecting but when it comes to the inner for loop, alert returns undefined and adds a check box with undefined side to it.. i think i am using the proper initializations but confused why it does so?
The reason is that k changes value, so by the time the inner function gets called, k is already equal to resultSet.length. You can wrap the whole thing in another function and pass k as a parameter to bind it to a new variable that won't change with the original k:
for(var k=0;k<resultSet.length;k++)
{
(function (result) {
$.get('/api/TagsApi/ElementsTagsIntersect?ids='+result, function (data) {
var testingarr = [];
for (var i = 0; i < data.length; i++) {
testingarr.push(data[i]["ID"]);
}
for (var w = 0; w <3; w++) {
if (($.inArray(testingarr[w], selectedloc)) > -1) {
var str = "<input type='checkbox' name ='test[]' value='" + result + "'/>" + result + "</br>";
$('#childs').append(str);
break;
}
}
}, 'json');
})(resultSet[k]);
}

Categories