I have this javascript that dynamically creates a table in HTML from a CSV file. I’m also using bootstrap and they have a cool ‘content editable’ class for table cells where you can edit the ’td’ element. I’m trying to add some css or just a border to a table cell after it has been edited. I’ve tried some jQuery but with no success. Any suggestions would be appreciated.
heres the github i used click here, essentially the same example with a few extra lines of javascript.
JavaScript:
<script type="text/javascript">
// check browser support
// console.log(SimpleExcel.isSupportedBrowser);
var fileInputCSV = document.getElementById('fileInputCSV');
// when local file loaded
fileInputCSV.addEventListener('change', function (e) {
// parse as CSV
var file = e.target.files[0];
var csvParser = new SimpleExcel.Parser.CSV();
csvParser.setDelimiter(',');
csvParser.loadFile(file, function () {
// draw HTML table based on sheet data
var sheet = csvParser.getSheet();
var table = document.getElementById('result');
var tbody = document.createElement('tbody');
table.innerHTML = "";
sheet.forEach(function (el, i) {
var row = document.createElement('tr');
el.forEach(function (el, i) {
var cell = document.createElement('td');
cell.setAttribute('contenteditable', 'true');
cell.setAttribute('id', 'cells');
cell.innerHTML = el.value;
row.appendChild(cell);
});
table.appendChild(tbody);
tbody.appendChild(row);
});
// create button to export as TSV
var btnSave = document.getElementById('fileExport');
btnSave.hidden = false;
btnSave.value = 'Save as TSV file ->';
document.body.appendChild(btnSave);
// export when button clicked
btnSave.addEventListener('click', function (e) {
var tsvWriter = new SimpleExcel.Writer.TSV();
tsvWriter.insertSheet(csvParser.getSheet(1));
tsvWriter.saveFile();
});
var data = csvParser.getSheet(1);
// var json_data = JSON.stringify(data);
console.log("data here", data);
angular.element('#angular-controller').scope().getCSV(data);
// print to console just for quick testing
// console.log(csvParser.getSheet(1));
// console.log(csvParser.getSheet(1).getRow(1));
// console.log(csvParser.getSheet(1).getColumn(2));
// console.log(csvParser.getSheet(1).getCell(3, 1));
// console.log(csvParser.getSheet(1).getCell(2, 3).value);
});
});
</script>
jQuery:
$(document).ready(function() {
$('#fileInputCSV').on('change',function() {
$('#save-button').css('display','inline-block');
$('#add-row').css('display', 'inline-block');
});
$('#cells').on('change', function() {
console.log("change");
$('#cells').css('style','border:2px solid orange');
});
});
HTML:
<div class="row">
<div class="container-fluid">
<button type="button" class="btn btn-success btn-sm" id="add-row" style="display:none" data-toggle="modal" data-target="#myModal">Add Row</button>
<button class="btn btn-sm btn-success pull-right" id="save-button" style="display:none">Save</button>
<table id="result" class="table table-condensed"></table>
<input type="button" id="fileExport" hidden="true" />
</div>
</div>
Have you tried to insert bootstrap´s table-bordered class to the object after is has been edited, like:
<table id="result" class="table table-condensed table-bordered"></table>
Check in the usagehere
Look at all bootstrap table possible flags here
To load a class dynamically to the result table (id="result") use:
$(#result).addClass("table-bordered");
Related
I am trying to pass a list containing the start cell and the end cell of the active range, and putting each of the values in a input field.
document.getElementById("btn-get-range").addEventListener('click', function(){
google.script.run.withSuccesHandler(showValues).getSelectedRange();
});
function showValues(startEndList){
document.getElementById('input-start-cell').value = startEndList[0];
document.getElementById('input-end-cell').value = startEndList[1];
}
/* Google Script Code */
let UI = SpreadsheetApp.getUi();
let SHEET = SpreadsheetApp.getActiveSheet();
function onOpen() {
UI.createMenu('Get Range In Input')
.addItem('Show Sidebar', 'showSidebar')
.addToUi();
}
function showSidebar(){
let html = HtmlService.createHtmlOutputFromFile('sidebar')
.setTitle('Get Range In Input');
UI.showSidebar(html);
}
function getSelectedRange() {
let range = SpreadsheetApp.getActive().getActiveRange().getA1Notation();
let startEndList = range.split(':');
return startEndList
}
<div class="text-center">
<input id='input-start-cell' type='text' class="m-2">
<input id='input-end-cell' type='text' class="m-2">
<button id='btn-get-range' type="button" class="btn btn-primary w-50" class="m-2">Get Range</button>
</div>
Why is it not working?
Thx for yout time.
There is a spelling mistake for withSuccesHandler. Modify withSuccesHandler to withSuccessHandler.
So this:
document.getElementById("btn-get-range").addEventListener('click', function(){
google.script.run.withSuccesHandler(showValues).getSelectedRange();
});
function showValues(startEndList){
document.getElementById('input-start-cell').value = startEndList[0];
document.getElementById('input-end-cell').value = startEndList[1];
}
Should be:
document.getElementById("btn-get-range").addEventListener('click', function(){
google.script.run.withSuccessHandler(showValues).getSelectedRange();
});
function showValues(startEndList){
document.getElementById('input-start-cell').value = startEndList[0];
document.getElementById('input-end-cell').value = startEndList[1];
}
I'm new to coding and I'm really stuck. Here's the situation: I made a script to generate a unique table from multiple text areas, and that’s working fine. The problem is that I need to fill the table in a specific way:
data from 1st textarea=1st Column
data from 2nd textarea=2nd Column
data from 3rd textarea=3rd Column
(but all the columns need to be part of the same table)
Right now all the data from the 3 textAreas appears one below the other(in rows, not columns) and I just can’t figure it out.
So far, that's my script:
<script>
function generateTable() {
$('textarea').each(function(){
var data = $(this).val(); console.log(data);
var rows = data.split("\n");
var table = $('<table />');
for(var y in rows) {
var cells = rows[y].split("\t");
var row = $('<tr />');
for(var x in cells) {
row.append('<td>'+cells[x]+'</td>');
}
table.append(row);
}
$('#excel_table1').append(table);
})
}
</script>
That’s my “body” with the text areas in divs:
<div id=street> <p>street:</p>
<textarea name="data1" style="width:100px;height:20px;"></textarea>
</div>
<div id=city> <p>city:</p>
<textarea name="data2" style="width:200px;height:20px;"></textarea>
</div>
<div id=country> <p>country:</p>
<textarea name="data3" style="width:100px;height:20px;"></textarea>
</div>
<br>
<input id=bouton1 type="button" onclick="javascript:generateTable()" value="Generate
table"/>
And that’s the table generated in a different "body":
<body><center>
<p>Table:</p>
<div id="excel_table1"></div>
</center></body>
Can Anyone help? The answer might be super easy, but I'm just trying to learn on the fly and know not much about JS! Thanks in advance :)
There can only be one <body> element on your page. So you would need to place both the textareas and the table in the same body element.
The problem with your script was that you created the table and appended it to your div for each textarea. You need to do this before and after iterating over the textareas.
I've created a snippet changing just that. Hope this helps!
function generateTable() {
var table = $('<table></table>');
$('textarea').each(function() {
var data = $(this).val();
console.log(data);
var rows = data.split("\n");
for (var y in rows) {
var cells = rows[y].split("\t");
var row = $('<tr />');
for (var x in cells) {
row.append('<td>' + cells[x] + '</td>');
}
table.append(row);
}
})
$('#excel_table1').append(table);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=street>
<p>street:</p>
<textarea name="data1" style="width:100px;height:20px;"></textarea>
</div>
<div id=city>
<p>city:</p>
<textarea name="data2" style="width:200px;height:20px;"></textarea>
</div>
<div id=country>
<p>country:</p>
<textarea name="data3" style="width:100px;height:20px;"></textarea>
</div>
<br>
<input id="bouton1" type="button" onclick="generateTable()" value="Generate
table" />
<p>Table:</p>
<div id="excel_table1"></div>
Never mind, I figured it out! :D
Here's the script that takes data from multiple textareas and put it in different columns of the same table:
<script src="jquery-3.5.0.js" type="text/javascript" charset="utf-8"></script>
<script>
function generateTable() {
var n=1;
var rows=[];
var lng=0;
$('textarea').each(function(){
var data = $(this).val();
var rowData = data.split("\n");
rows[n] = rowData;
lng = rowData.length;
n++;
})
var table = $('<table />');
k=0;
while (k < lng) {
var row = $('<tr />');
for(var i = 1; i < rows.length; i++) {
var singleRow = rows[i];
row.append('<td>'+singleRow[k]+'</td>')
}
table.append(row);
k++;
}
$('#excel_table1').append(table);
}
</script>
I'm trying to transform something like this:
firstnameA,lastnameA,emailA
firstnameB,lastnameB,emailB
into a js/jquery variable that I can then post to my php script to insert row by row in a table.
So far I have managed to do this: it splits the input by new line and then by comma, creates a table to make it easy for the user to check their input and in parralel builds an array that I will post to my script for further treatment. The second part is not working at all (building the table works). I have looked at plenty of posts here on how to create multi-dimensional arrays in js but they all require that I know the exact dimensions of the array. However it could be 1,2 or 50 lines.
Here's my code:
(function($) {
$(document).ready(function() {
$('#new_coll').submit(function(e) {
e.preventDefault();
if($("#names").val() != "") {
var table = '<table class="table mt-4"><thead><th>First name</th><th>Last name</th><th>Email address</th></thead><tbody>';
var i = 0;
var j = 0;
var data;
$.each($("#names").val().split(/\r?\n/), function(e, elements) {
table = table+'<tr>';
$.each(elements.split(","), function(e, element) {
table = table+'<td>'+element+'</td>';
data[i][j] = element;
j++;
});
var j = 0;
table = table+'</tr>';
i++;
});
table = table+'</tbody></table>';
var posting = $.post("Connections/colleagues_add.php", data);
$('#results').empty().html(table);
posting.done(function( data ) {
$( "#results" ).append( data );
});
}
});
});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" id="new_coll">
<textarea class="form-control" id="names" placeholder="Event description*" rows="3" required>
firstnameA,lastnameA,emailA
firstnameB,lastnameB,emailB
</textarea>
<button type="submit" id="verify" class="btn btn-primary btn-block">Verify</button>
</form>
<div class="col" id="results"></div>
If you comment out line 16 it works with the table, however creating the array isnt working. My file where it gets posted to is just a $_POST dump.
I'd appreciate any pointers!
Just turn your data into a multi-dimensional array like below, stringify it with JSON.stringify and post it to your php file. In php use json_decode to turn it into an php-array and then go from there with your database stuff.
// SPLIT YOUR DATA BY NEWLINE
const data = document.getElementById("data").value.split("\n");
// BUILD NEW ARRAY
let json = [];
for (let i in data) {
// SPLIT EACH LINE INTO ARRAY
// AND PUSH IT TO NEW ARRAY
json.push(data[i].split(","));
}
// STRINGIFY YOUR NEW ARRAY
console.log(JSON.stringify(json));
<textarea id="data" cols="50">
firstnameA,lastnameA,emailA
firstnameB,lastnameB,emailB</textarea>
I kinda solved it, happy to get more input though!
(function($) {
$(document).ready(function() {
$('#add').hide();
$('#new_coll').submit(function(e) {
e.preventDefault();
if($("#names").val() != "") {
var table = '<table class="table mt-4"><thead><th>First name</th><th>Last name</th><th>Email address</th></thead><tbody>';
var i = 0;
var data = new Array()
$.each($("#names").val().split(/\r?\n/), function(e, elements) {
table = table+'<tr>';
data[i] = new Array();
var j = 0;
$.each(elements.split(","), function(e, element) {
table = table+'<td>'+element+'</td>';
data[i][j] = element;
j++;
});
table = table+'</tr>';
i++;
});
table = table+'</tbody></table>';
$('#results').empty().html(table);
console.log(data);
$('#add').show();
$('#add').click(function(e) {
$('#add').empty().html('<i class="fa fa-spin fa-spinner"></i>');
var posting = $.ajax({ url : 'https://httpbin.org/post',
type : 'POST',
data : {'data':JSON.stringify(data)},
success : function(){ }
});
posting.done(function( response ) {
$( "#step2" ).append( response );
$('#add').empty().html('Done');
});
posting.fail(function( response ) {
$('#add').empty().html('Error');
});
});
}
});
});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" id="new_coll">
<div class="form-row mb-2">
<div class="col">
<textarea class="form-control" id="names" placeholder="Event description*" rows="3" required>a1,a2,emaila
b1,b2,emailb</textarea>
</div>
</div>
<div class="form-row mt-4">
<div class="col">
<button type="submit" id="verify" class="btn btn-primary btn-block">Verify</button>
</div>
</div>
</form>
<div class="form-row mb-2">
<div class="col" id="results">
</div>
<div class="col mt-2" id="step2">
<button id="add" class="btn btn-primary btn-block">Add</button>
</div>
</div>
For some reason the PHP part isnt working here but that works too!
Happy for any improvements!
I have a CSV file which is always in the following format
COL A | COL B | COL C |
---------------------------------------
Email | First Name | Last Name |
So on each row, column A contains the email, column B the first name and column C the last name.
What I am attempting to do is read this CSV file and inject some of the data within a modal I am displaying. At the moment I have come up with the following
$(function () {
$("#preview-btn").bind("click", function () {
var regex = /^([a-zA-Z0-9\s\S_\\.\-:])+(.csv|.txt)$/;
if (regex.test($("#fileOne").val().toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var rows = e.target.result.split("\n");
for (var i = 0; i < 1; i++) {
var cells = rows[i].split(",");
$('#myModal .modal-body').load('./emailTemplate.html', function(){
$(this).find("#fName").append(cells[1]);
$(this).find("#lName").append(cells[2]);
});
}
$('#myModal').modal('show');
};
reader.readAsText($("#fileOne")[0].files[0]);
} else {
alert("This browser does not support HTML5.");
}
} else {
alert("Please upload a valid CSV file.");
}
});
});
So the function splits the rows within the CSV, loads a HTML template, and injects the first name and last name into the html for row 1.
So the above works fine. The problem I am having is that within my model I have the following buttons
<button type="button" class="btn btn-default btn-prev">Prev</button>
<button type="button" class="btn btn-default btn-next">Next</button>
What I am trying to do is if Next is clicked, to display the data from the next row, opposite for the Prev button. I am having issues integrating these 2 button events with the above.
With what I currently have in place, how can I step through the rows within the CSV?
Thanks
Here is a pseudo simple of how to manage the next/prev buttons.
The key is to declare a pointer for the current row. So when user clicks next the pointer will "move" to next (e.g. 0 to 1 etc.) than call the function which parse the row and display it.
If something is not clear, let me know.
var current = 0;
var rows = $('textarea').val().split('\n');
console.log(rows);
function applyRow() {
console.log(rows[current]);
var cells = rows[current].split(",");
$("#fName").html(cells[0]);
$("#lName").html(cells[1]);
}
applyRow();
$('.btn-next').click(function(){
current++;
applyRow();
});
$('.btn-prev').click(function(){
current--;
applyRow();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea>
john,doe
john1,doe1
john2,doe2
</textarea>
<table>
<tr>
<td id="fName"></td>
<td id="lName"></td>
</tr>
</table>
<hr />
<button type="button" class="btn btn-default btn-prev">Prev</button>
<button type="button" class="btn btn-default btn-next">Next</button>
If i understand you code right, you only load the first row
for (var i = 0; i < 1; i++) { ... }
Just load all rows this way and insert them into a table. With CSS you hide all rows of this table by default. When loading is done set a global variable var i=1. Add a function:
function updateRows(){
$('#tableId tr').hide()`;
$('#tableId tr:nth-child(i)').show()`;
}
And you buttons manipulate the i and then call updateRows()
I'm developing a web application.My App is using Javascript, PHP, HTML. I already done apply code to upload xlsx , attach it on screen .
Here's my Code
<script type="text/javascript" src="simple-excel.js"></script>
<table width=50% align="left" border=0 STYLE="border-collapse:collapse;">
<tr>
<td style="width:9.2%"><b>Load CSV file</b></td>
<td style="width:1%"><b>:</b></td>
<td style="width:15%"><input type="file" id="fileInputCSV" /></td>
</tr>
</table>
<table id="result"></table>
<script type="text/javascript">
// check browser support
// console.log(SimpleExcel.isSupportedBrowser);
var fileInputCSV = document.getElementById('fileInputCSV');
// when local file loaded
fileInputCSV.addEventListener('change', function (e) {
// parse as CSV
var file = e.target.files[0];
var csvParser = new SimpleExcel.Parser.CSV();
csvParser.setDelimiter(',');
csvParser.loadFile(file, function () {
// draw HTML table based on sheet data
var sheet = csvParser.getSheet();
var table = document.getElementById('result');
table.innerHTML = "";
sheet.forEach(function (el, i) {
var row = document.createElement('tr');
el.forEach(function (el, i) {
var cell = document.createElement('td');
cell.innerHTML = el.value;
row.appendChild(cell);
});
table.appendChild(row);
});
});
});
</script>
Here's my UI
How do i supposed to do for hide/erase the null cell(Red Mark)?
It seems your CSV has an empty line at the bottom. Even if it is empty, as far as "sheet" is concerned, it will have one field as long as a carriage return is there.
I'd check to see if the content of the "el" contains anything before executing your el.forEach()
Put some condition inside el.forEach
Like this
el.forEach(function (el, i) {
if(el.value!="")
{
var cell = document.createElement('td');
cell.innerHTML = el.value;
row.appendChild(cell);
}
});