Javascript sorting a csv rows and displaying in table - javascript

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>

Related

Hover keyframe values green and red

I'm kind of stuck in a keyframe. I have a table with values from a fetch (json) and i should add a hover when the values is less than 5 in red and starting from 5 in green. This is my code in javascript ->
how do i have to implement the keyframe with it in css or is it different that i think?
// Html
<div id="group3">
<table class="table">
<thead>
<tr class="info">
<th></th>
<th>February</th>
<th>March</th>
<th>April</th>
<th>May</th>
<th>June</th>
<th>July</th>
<th>August</th>
</tr>
</thead>
<tbody id='mytable'>
</tbody>
</table>
</div>
//CSS
Keyframe?
//hover
let cells = document.querySelectorAll("tbody");
cells.forEach( el => el.addEventListener('mouseenter', function () {
if(el.textContent < 5){
el.classList.add('underfive');
} else if (el.textContent >=5){
el.classList.add('abovefive');
}
}));
// reset animationx
cells.forEach(el => el.addEventListener('mouseleave', function () {
if(el.textContent < 5){
el.classList.remove('underfive');
} else if (el.textContent >=5){
el.classList.remove('abovefive');
}
}));
it should be like this ->
this is the startpage, background is white
this is the end result how it should be, uploaded from a json file in a table, red value
this is the green value when it's 5 of higher
Based on what you say you want to show a different background color or styling in general than the default if the mouse is over the td.
So use :hover for that. You want to have a transition between those states so use transition.
You want to have a different color if it is above or below 5. So define what you want to have as default and add a class for the other case.
let data = [1,4,2,8,12,2,5,7];
const tr = document.querySelector('tr');
data.forEach(elem => {
let td = document.createElement('td');
td.textContent = elem;
td.classList.toggle('belowfive', elem < 5);
tr.appendChild(td);
});
td {
transition: background-color 1s;
background-color: white;
padding: 1rem;
border: 1px solid hsl(0 0% 50%);
}
td:hover {
background-color: green;
}
td.belowfive:hover {
background-color: red;
}
<table>
<tbody>
<tr>
</tr>
</tbody>
</table>

Is there a way I can have a separate background image for each button in localstorage?

In the website I am trying to create, I want a 7x7 table, each cell being a "button" that you can click on to toggle between images. Almost like a bingo board, you click on a cell and it will mark it as being completed by switching to another image. I am using localstorage to store which image is being shown so a user can keep their progress basically.
My problem is that since there is only 1 "backgroundImage" property, how do I have a different image in each box that I can toggle without affecting the others?
The javascript I provide is the same function twice, as it works for the first button but not for the second one, as I am guessing the background image is being conflicted with since they are both trying to access the same one.
HTML code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js" data-semver="3.0.0" data-require="jquery"></script>
<script src="js/script.js"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<table>
<tr>
<th>T</th>
<th>W</th>
<th>I</th>
<th>S</th>
<th>T</th>
<th>E</th>
<th>D</th>
</tr>
<tr>
<th><button class="button1"></button></th>
<th><button class="button2"></button></th>
<th>Task 3</th>
<th>Task 4</th>
<th>Task 5</th>
<th>Task 6</th>
<th>Task 7</th>
</tr>
</table>
</body>
</html>
CSS:
button
{
display: inline-block;
width: 100%; /* set to 100% */
height: 100%; /* set to 100% */
margin-bottom: 0.5em;
padding-top: .6em;
padding-bottom: .6em;
color: #fff;
background-color: #aaabbb;
border-radius: 5px;
border: solid #cccccc 1px;
clear:right;
float:right;
height: 150px;
width: 150px;
}
JS:
$(function(){
if (localStorage.getItem('backgroundImage') !== null) {
url = localStorage.backgroundImage;
$('.button1').css('backgroundImage', url);
}
else
{
url = 'url(images/button1.png)';
}
$('.button1').click(function(){
if(url == "url(images/button1.png)"){
localStorage.removeItem('backgroundImage');
$('.button1').css('backgroundImage', 'url(images/button1no.png)');
localStorage.setItem('backgroundImage', 'url(images/button1no.png)');
}
else {
url = 'url(images/button1no.png)';
localStorage.removeItem('backgroundImage');
$('.button1').css('backgroundImage', 'url(images/button1.png)');
localStorage.setItem('backgroundImage', 'url(images/button1.png)');
}
});
});
//----------------------------------------------------------------------------
$(function(){
if (localStorage.getItem('backgroundImage') !== null) {
url = localStorage.backgroundImage;
$('.button2').css('backgroundImage', url);
}
else
{
url = 'url(images/button2.png)';
}
$('.button1').click(function(){
if(url == "url(images/button2.png)"){
localStorage.removeItem('backgroundImage');
$('.button2').css('backgroundImage', 'url(images/button2no.png)');
localStorage.setItem('backgroundImage', 'url(images/button2no.png)');
}
else {
url = 'url(images/button2no.png)';
localStorage.removeItem('backgroundImage');
$('.button2').css('backgroundImage', 'url(images/button2.png)');
localStorage.setItem('backgroundImage', 'url(images/button2.png)');
}
});
});
You need to store an array of the values instead of one value. Local Storage does not support complex values, but you can use JSON to encode it. So when you set the value, you would do something like this:
localStorage.setItem('backgroundImage', JSON.stringify(someArray));
And when you read it, parse it:
myArrayofValues = JSON.parse(localStorage.getItem('backgroundImage'))
Remember that by default the value will be empty, so you may want to set an initial value of an empty array first.
There are two questions here:
How to toggle bettween two images for each buttons
How to store the "current" image for each button
I would use data attributes to store both images url AND the current one (and a number telling which one is used). That makes it easy to maintain all the urls directly in your markup.
I would also use it to store the "index" of each button, just to simplify the correspondance of each buttons with the index of an array to be stored in localStorage.
So on click, you will simply toggle between 2 urls and store the new "image number" in the array, at the right index.
Notice that it isn't the url that is stored... it's already in the markup.
Now, as #Raymond Camden explained, localStorage can store a string... Not an object or an array. That is why JSON.stringify() and JSON.parse() are used.
$(document).ready(function() {
// retrieve localStorage if exist
let bg_numbers = [];
/*if (localStorage.getItem("bg_numbers") !== null) {
bg_numbers = JSON.parse(localStorage.getItem("bg_numbers"))
}*/
console.log(bg_numbers)
// Setting the data-bg_current and data-btn_index
$("button").each(function(index, btn) {
let $btn = $(btn);
// Get the urls for this button
let backgrounds = [$btn.data("bg_1"), $btn.data("bg_2")];
// Retreive the image number used, if any
let currentImage = (bg_numbers[index] && bg_numbers[index] === 1) ? 1 : 0;
// Set it
$btn.css("background-image", `url('${backgrounds[currentImage]}')`);
// Update the data attributes, since thos are zero on page load
$btn.data("bg_current", currentImage);
$btn.data("btn_index", index)
});
$("button").on("click", function() {
let $btn = $(this);
// Get the index of this button
let index = $btn.data("btn_index")
// Get the urls for this button
let backgrounds = [$btn.data("bg_1"), $btn.data("bg_2")];
// Toggle the image
let currentImage = ($(this).data("bg_current") === 1) ? 0 : 1;
$(this).css("background-image", `url('${backgrounds[currentImage]}')`);
// Update the array and save to localStorage
bg_numbers[index] = currentImage
//localStorage.setItem("bg_numbers", JSON.stringify(bg_numbers))
});
});
button {
display: inline-block;
width: 100%;
/* set to 100% */
height: 100%;
/* set to 100% */
margin-bottom: 0.5em;
padding-top: 0.6em;
padding-bottom: 0.6em;
color: #fff;
background-color: #aaabbb;
border-radius: 5px;
border: solid #cccccc 1px;
clear: right;
float: right;
height: 150px;
width: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>T</th>
<th>W</th>
<th>I</th>
<th>S</th>
<th>T</th>
<th>E</th>
<th>D</th>
</tr>
<tr>
<th><button data-bg_1="https://via.placeholder.com/150x150.png?text=Button 1" data-bg_2="https://loremflickr.com/150/150" data-bg_current=0 data-btn_index=0></button></th>
<th><button data-bg_1="https://via.placeholder.com/150x150.png?text=Button 2" data-bg_2="https://loremflickr.com/150/150" data-bg_current=0></button></th>
<th>Task 3</th>
<th>Task 4</th>
<th>Task 5</th>
<th>Task 6</th>
<th>Task 7</th>
</tr>
</table>
I commented all lines related to localStorage here since SO snippet are disallowing it... And it was throwing an ugly error. But see my CodePen.

Save content editable HTML table in multiple fields

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!

Iterating through html array is not working in javascript

I tried iterating through this but could not.
the function below
function orderpackage (){
var product_line = $('#carttable')[0].getElementsByTagName('tr');
for (var i = 1; i < product_line.length; i++) {
}
console.log(product_line)
Produces this in the console output
each of the tr.table_row is made from this
<tr class="table_row">
<td class="column-1">
<div class="how-itemcart1">
<img src=${Items.imageurl} alt="IMG">
</div>
</td>
<td class="column-2">${Items.name}</td>
<td class="column-3">$ ${Items.price}</td>
<td class="column-4">
<div class="wrap-num-product flex-w m-l-auto m-r-0">
<div class="btn-num-product-down cl8 hov-btn3 trans-04 flex-c-m qty-change" id="qty-change">
<i class="fs-16 zmdi zmdi-minus"></i>
</div>
<input class="mtext-104 cl3 txt-center num-product" type="number" name="num-product1" value=${Items.user_quantity}>
<div class="btn-num-product-up cl8 hov-btn3 trans-04 flex-c-m qty-change" id="qty-change">
<i class="fs-16 zmdi zmdi-plus"></i>
</div>
</div>
</td>
<td class="column-5">${line_total_sum}</td>
</tr>
what I want to do is iterate through each and get the price, quantity and line total.
When I tried the function below for the line total is shows error
var product_line = $('#carttable')[0].getElementsByTagName('tr')[4];
How do I iterate through each tr to the price, quantity and line total?
With plain JS, you can use HTMLTableElement.rows to get all the rows on the table.
Then you need to iterate over them, probably skipping the first one (header). For each one, access the children (cells) that contain the fields you need and create a new array with them, [price, quantity, total], and push that one to another array containing the data for all the table.
Here's one way to do it using Array.from() and Array.prototype.map():
const tableData = Array.from(document.getElementById('table').rows).slice(1).map(row => {
const cells = row.children;
return [cells[0].innerText, cells[1].innerText, cells[2].innerText];
});
console.log(JSON.stringify(tableData));
table {
border-collapse: collapse;
font-family: monospace;
text-align: right;
}
table, th, td {
border: 3px solid black;
}
th, td {
padding: 5px 10px;
}
<table id="table">
<tr><th>PRICE</th><th>QUANTITY</th><th>TOTAL</th></tr>
<tr><td>1</td><td>5</td><td>5</td></tr>
<tr><td>10</td><td>2</td><td>20</td></tr>
<tr><td>8</td><td>4</td><td>32</td></tr>
</table>
If you prefer to use a for...of loop instead:
let tableData = [];
// Iterate over every row:
for (const row of document.getElementById('table').rows) {
// Get the cells in the current row:
const cells = row.children;
// Read the text on the columns we want:
tableData.push([cells[0].innerText, cells[1].innerText, cells[2].innerText]);
}
// Remove the first row (header):
tableData = tableData.slice(1);
console.log(JSON.stringify(tableData));
table {
border-collapse: collapse;
font-family: monospace;
text-align: right;
}
table, th, td {
border: 3px solid black;
}
th, td {
padding: 5px 10px;
}
<table id="table">
<tr><th>PRICE</th><th>QUANTITY</th><th>TOTAL</th></tr>
<tr><td>1</td><td>5</td><td>5</td></tr>
<tr><td>10</td><td>2</td><td>20</td></tr>
<tr><td>8</td><td>4</td><td>32</td></tr>
</table>
Or just a normal for loop instead:
const rows = document.getElementById('table').rows;
const totalRows = rows.length;
const tableData = [];
// Iterate over every row, skipping the first one (header) already:
for (let i = 1; i < totalRows; ++i) {
// Get the cells in the current row:
const cells = rows[i].children;
// Read the text on the columns we want:
tableData.push([cells[0].innerText, cells[1].innerText, cells[2].innerText]);
}
console.log(JSON.stringify(tableData));
table {
border-collapse: collapse;
font-family: monospace;
text-align: right;
}
table, th, td {
border: 3px solid black;
}
th, td {
padding: 5px 10px;
}
<table id="table">
<tr><th>PRICE</th><th>QUANTITY</th><th>TOTAL</th></tr>
<tr><td>1</td><td>5</td><td>5</td></tr>
<tr><td>10</td><td>2</td><td>20</td></tr>
<tr><td>8</td><td>4</td><td>32</td></tr>
</table>

HTML - read .txt file from URL location in javascript

I want to read a .txt file an URL location, lets say from http://www.puzzlers.org/pub/wordlists/pocket.txt and process its content on my page.
Can you point me out some tutorials or some basic code on how to do this in javascript?
I have a basic HTML code where I have some tables and I want to populate them with text from a .txt from a given URL location, but I do not know how to read the data from that location.
<html>
<head>
<title>Pseudoganglia Interface</title>
<!-- CSS goes in the document HEAD or added to your external stylesheet -->
<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
</style>
<!-- Table goes in the document BODY -->
<script>
function getText()
{
// read text from URL location
}
function populateTables() {
var tableHP = document.getElementById("tHP");
// Create an empty <tr> element and add it to the 1st position of the table:
var row = tableHP.insertRow(tableHP.rows.length);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
// Add some text to the new cells:
cell1.innerHTML = "NEW CELL1";
cell2.innerHTML = "NEW CELL2";
}
</script>
</head>
<body onload="populateTables()">
<table class="gridtable" id="tHP">
<tr>
<th colspan=2>HP</th>
</tr>
<tr>
<td># SN</td>
<td>% of used RAM</td>
</tr>
</table>
<br>
<table class="gridtable" id="tIBM">
<tr>
<th colspan=2>IBM</th>
</tr>
<tr>
<td># CN</td>
<td>% of used RAM</td>
</tr>
</table>
</body>
</html>
this code may help you:
function getText(){
// read text from URL location
var request = new XMLHttpRequest();
request.open('GET', 'http://www.puzzlers.org/pub/wordlists/pocket.txt', true);
request.send(null);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
var type = request.getResponseHeader('Content-Type');
if (type.indexOf("text") !== 1) {
return request.responseText;
}
}
}
}
function populateTables(){
var outer_text = getText();
outer_text = outer_text.split('\n'); // you can adjust the manner of parsing the received file (regexp)
var tableHP = document.getElementById("tHP");
// Create an empty <tr> element and add it to the 1st position of the table:
var row = tableHP.insertRow(tableHP.rows.length);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
// Add some text to the new cells:
cell1.innerHTML = outer_text[0];
cell2.innerHTML = outer_text[1];
}
from codegrepper using fetch (unsupported on IE).
const url = "http://www.puzzlers.org/pub/wordlists/pocket.txt"
fetch(url)
.then( r => r.text() )
.then( t => //process your text! )

Categories