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>
Related
I am looking to pass a list of autocomplete values to text boxes that have been appended based on a specified number of units.
function getUnits() {
var units = $("#units").val();
if (units > 1){
for (var count = 1; count < units-1; count++) {
$("<input type='text' /><br>").appendTo("#left-col");
}
$("#left-col").append('<input type="text">');
}}
$(function() {
google.script.run.withSuccessHandler(buildTagList)
.getAvailableTags();
});
function buildTagList(availableTags) {
$( '#med' ).autocomplete({
source: availableTags
});
}
This is the code for appending the appropriate amount of text boxes based on the # of units.
function getAvailableTags() {
var ss = SpreadsheetApp.openById("someID");
var s = ss.getSheetByName("someSheet");
var drug = s.getRange("A2:A").getValues();
var headers = 1;
var tagColumn = 0;
var availableTags = [];
for (var row=headers; row < drug.length; row++) {
availableTags.push(drug[row][tagColumn]);
}
return( availableTags );
}
I have tried creating the appended values with the same name/id/and class, but nothing seems to be working. A bonus question would also be: when a user goes to submit the form, how do I capture all of the appended boxes' values?
Here's a short example of adding textboxes to a dialog and submitting the data back to a spreadsheet
Run addTextBoxestoADialog(). Give it the names of the textboxes separated by forward slash. Like this: name1/name2/name3 and then it will build the form. You can fill in the values and hit submit and the names and values will be appended to the active sheet.
Code.gs:
function addTextBoxestoADialog() {
var ss=SpreadsheetApp.getActive();
var ui=SpreadsheetApp.getUi();
var resp=ui.prompt("Adding Text Boxes to a Dialog","Enter unique names of text boxes separate by forward slash /.",ui.ButtonSet.OK );
var tA=resp.getResponseText().split('/');
var html='<html><head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"><script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>';
html+='<script>function fileUploadJs(frmData){google.script.run.upLoadForm(frmData);}</script></head><body>';
html+='<form id="myForm">';
for(var i=0;i<tA.length;i++) {
html+=Utilities.formatString('<br /><input type="text" value="%s" name="%s" /> %s',i+1,tA[i],tA[i]);//added default values
}
html+=Utilities.formatString('<input type="hidden" value="%s" name="NameArray" />',tA.join('~~~'));
html+='<br /><input type="button" value="Submit" onclick="fileUploadJs(this.parentNode)" />';
html+='</form></body></html>';
var userInterface=HtmlService.createHtmlOutput(html);
ui.showModelessDialog(userInterface, "Adding TextBoxes");
}
function upLoadForm(theForm) {
Logger.log(JSON.stringify(theForm));
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var nA=theForm.NameArray.split('~~~');
for(var i=0;i<nA.length;i++) {
sh.appendRow([nA[i],theForm[nA[i]]]);
}
}
I am working on a school project, and I need to create a program that will calculate the commission of our companies employees. So far I have a place where I can upload a data file and put it into a table. I want to add a button that will calculate the sales commission for each employee and add a new column to the table with the calculated sales commission.
data file:
Name,Sales,Commission,Region
Billy Bradshaw,$33611,20%,North
Twanna Beagle,$44250,20%,East
Gloria Saling,$49278,20%,West
Theola Spargo,$75021,20%,South
Giovanni Armas,$59821,20%,East
Cristal Smith,$44597,20%,West
Ashley Morris,$55597,20%,North
Tiffaney Kreps,$40728,20%,South
Arnold Fultz,$49674,20%,East
Sherman Sallee,$23780,20%,North
Shawana Johnson,$58365,20%,West
Kathrine Mosca,$67489,20%,North
Karren Mahmoud,$53382,20%,East
Venus Grasser,$33572,20%,West
Rickey Jones,$28522,20%,East
Verona Strauch,$41865,20%,North
Elvis Yearta,$25314,20%,South
Jonathan Lee,$22823,20%,West
Sommer Cottle,$45660,20%,East
Elsa Laverty,$49386,20%,North
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sales Commission Calculator</title>
<h1>Sales Commission Calculator</h1>
<p>Please select the Employee Sales Database</p>
<style type="text/css">
body
{
font-family: Arial;
font-size: 10pt;
}
table
{
border: 1px solid rgb(155, 155, 155);
border-collapse: collapse;
}
tr:nth-child(even) {
background: #4ac5fd;
}
table td
{
padding: 5px;
}
</style>
</head>
<body>
<script>
function Upload() {
var fileUpload = document.getElementById("fileUpload");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/;
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var table = document.createElement("table");
var rows = e.target.result.split("\n");
for (var i = 0; i < rows.length; i++) {
var cells = rows[i].split(",");
if (cells.length > 1) {
var row = table.insertRow(-1);
for (var j = 0; j < cells.length; j++) {
var cell = row.insertCell(-1);
cell.innerHTML = cells[j];
}
}
}
var dvCSV = document.getElementById("dvCSV");
dvCSV.innerHTML = "";
dvCSV.appendChild(table);
}
reader.readAsText(fileUpload.files[0]);
} else {
alert("This browser does not support HTML5.");
}
} else {
alert("Please upload a valid CSV file.");
}
}
</script>
<input type="file" id="fileUpload" />
<input type="button" id="upload" value="Upload" onclick="Upload()" />
<input type="button" id="Calculate Commission" value="Calculate Commission" oneclick=""/>
<hr />
<div id="dvCSV">
</div>
</body>
</html>
Make a button that will add a column to my table with the calculates sales commission numbers.
Thanks for being up-front about it being for a school project. We've all been there, so let me walk you through it a little bit.
You need to have the button you have call a function, which you already have. Fix your typo and then assign a new function to the onclick attribute:
<input type="button" id="Calculate Commission" value="Calculate Commission" onclick="calculateCommissions()" />
Then you'll need to create that function... Ultimately, overall idea, is we want that function to look at each row (so, we'll probably want a loop, to loop over the rows in the table)... pull out that row's "sales" and "commission %" and multiply them together... then, before we let the loop move on to the next row, add that final commission score to the end of the current row.
function calculateCommissions() {
// Get an array full of the rows
// Note the use of the spread operator, we need to convert the NodeList type to an Array type
var allRows = [...document.getElementsByTagName('tr')];
// Now let's loop over that array and look at each row individually
allRows.forEach( eachRow => {
// For the current row, we need to pull out the "sales" and "commission %" values
var sales = Number(eachRow.childNodes[1].innerText.slice(1));
var percentCommission = Number(eachRow.childNodes[2].innerText.substr(0, eachRow.childNodes[2].innerText.indexOf('%')));
// Do the math...
var commission = Math.round(sales * percentCommission / 100)
// And now, we want to add that commission as an additional column
// Note that since we're also going to be looping over the header...
// ... let's add a column header "Commission"
var tableCellToAppend = document.createElement('td')
tableCellToAppend.innerText = commission ? `$${commission}` : 'Commission';
eachRow.appendChild(tableCellToAppend)
})
}
Of course in the real world project, you would need to have error handling galore. Real users never upload perfect csv files. Welcome to SO.
I'm trying to create a table using javascript. The number of rows is inserted by the user using this form.I don't know how to output this table correctly.Tried this but i think i have a problem inside the javascript code.Can someone please show me how to output a table where the number of rows is inserted in this form?
Here is my code
<html>
<head>
<title>
</title>
</head>
<body>
<form name="table" id="hey">
Insert nr of rows <input type="text"/>
</form>
<script>
var nr=document.getElementById("hey");
var c=parseInt("nr");
for(int i=0;i<c;i++){
print("<table><tr><td></td></tr></table>");
}
</script>
</script>
</body>
</html>
You had an error in your for loop, you had:
for(int i=0;i<c;i++){
print("<table><tr><td></td></tr></table>");
}
This should be:
for(i=0;i<c;i++){
print("<table><tr><td></td></tr></table>");
}
As for your actual problem, you could try doing it like this:
HTML
Insert number of rows
<input type="text" id="hey" />
<input type="button" value="Generate table" id="btnShow">
<div id="container"></div>
CSS
#container {
height:50vh;
width:50vw;
background-color:#eee;
}
JavaScript
//Event listener for the button.
document.getElementById ("btnShow").addEventListener ("click", generateTable, false);
//Function generating the table.
function generateTable() {
//Get the value the user gave
var nr = document.getElementById("hey").value;
//Make it an Int
var c = parseInt(nr);
//Get the div containing the table
var div = document.getElementById("container");
//Write the table
div.innerHTML += "<table border='1' id='table'>";
for (i = 0; i < c; i++) {
//Write the rows and cells
document.getElementById('table').innerHTML += "<tr><td>One</td><td>Two</td></tr>"
}
}
JsFiddle
EDIT
I've updated the code to clear the div before adding rows a second time.
Updated fiddle
JavaSript
//Event listener for the button.
document.getElementById ("btnShow").addEventListener ("click", generateTable, false);
//Function generating the table.
function generateTable() {
//Get the value the user gave
var nr = document.getElementById("hey").value;
//Make it an Int
var c = parseInt(nr);
//Get the div containing the table
var div = document.getElementById("container");
//Clear the container div <----------- Note this
div.innerHTML = " ";
//Write the table
div.innerHTML += "<table border='1' id='table'>";
for (i = 0; i < c; i++) {
//Write the rows and cells
document.getElementById('table').innerHTML += "<tr><td>One</td><td>Two</td></tr>"
}
}
Hope this helps!
This is what a proper table should look like.
< table > /*this is the table that will contain all of the rows and table data */
< tr > /* this stands for table row */
< td > /* this stands for table data which is inside the row. You can think of these as columns */
< / td >
< td >
< / td >
< / tr >
< / table >
You do not need all of the extra coding unless you are trying to do something very specific.
I have a Javascript like this:
<script language="javascript">
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for(var i=0; i<colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
}
}
}
var showMode = 'table-cell';
if (document.all) showMode='block';
function toggleVis(btn){
btn = document.forms['tcol'].elements[btn];
cells = document.getElementsByName('t'+btn.name);
mode = btn.checked ? showMode : 'none';
for(j = 0; j < cells.length; j++) cells[j].style.display = mode;
}
</script>
The following is HTML for show/hide the columns and insert new row:
<body>
<form name="tcol" onsubmit="return false">
Show columns
<input type=checkbox name="col1" onclick="toggleVis(this.name)" checked> 1
<input type=checkbox name="col2" onclick="toggleVis(this.name)" checked> 2
<input type=checkbox name="col3" onclick="toggleVis(this.name)" checked> 3
</form>
<input type="button" value="Insert Row" onclick="addRow('dataTable')">
<table id="dataTable">
<tr>
<td name="tcol1" id="tcol1"><input type="text" name="txt1"></td>
<td name="tcol2" id="tcol2"><input type="text" name="txt2"></td>
<td name="tcol3" id="tcol3"><input type="text" name="txt3"></td>
</tr>
</table>
I can insert row, but only the first row's column can be hidden. Is it because of the input fields' attributes? If yes, how do I add tag attribute into new row? Please help me out on this. Thanks.
newcell.innerHTML = table.rows[0].cells[i].innerHTML wont copy attribute to new cell, it will just copy innerHtml of table.rows[0].cells[i] cell.
So name attribute wont get applied to newcelll toggleVis functions work by finding cells by name attribute.
You can add following code in addRow to apply name attribute to newcell.
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for(var i=0; i<colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
newcell.setAttribute("name",table.rows[0].cells[i].getAttribute("name"));//use setAttribute to set any attribute of dom element
newcell.style.display = table.rows[0].cells[i].style.display ; // to copy display style
newcell.id = table.rows[0].cells[i].getAttribute("name"); // IE workaround for getting this table cell in getElementsByName , see this http://stackoverflow.com/questions/278719/getelementsbyname-in-ie7
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
}
}
}
I know this doesn't answer your specific question, but your code needs a lot of help. The way you are doing things is very prone to breakage and can be accomplished in a much simpler way. Here is one example. I used jQuery to save myself time, but the principles can be mapped to plain javascript if you don't want to use jQuery.
Don't use inline javascript calls. You can monitor the parent container of the checkbox and determine which one was changed.
Don't monitor onclick events for checkboxes. Use onchange instead. This is safer.
You can use the html5 data attribute to store which checkbox was clicked. For example, <input type=checkbox name="col1" checked data-number="1"> 1.
Use the clicked data field to determine which cell in the table you want to modify.
http://jsfiddle.net/E3D2U/
$('input:checkbox').change( function() {
//which checkbox was changed?
var number = $(this).data('number') - 1;
//get the table cell that matches the clicked number
var targetTD = $('#dataTable td')[number];
//if our checkbox is checked then...
if ($(this).is(':checked')) {
$(targetTD).css('background-color', 'white');
}
else {
$(targetTD).css('background-color', 'yellow');
}
});
I have a table that has a header with a checkbox in that row. The data gets dynamically added in the table with javascript. Now checking on the checkbox that is in the header row checks or unchecks all the checkboxes of all rows.. I have done it till here in the method "checkUncheck()", i.e.:
<input type="checkbox" id="chkAppId" onclick="checkUncheck()"/>
But now, suppose there are 10 records dynamically added in the table. I have checked the main checkbox in the header. After that, I uncheck one of the checkboxes, e.g.: on the 10th row, then the checkbox of the header must be unchecked....and if I check all of the 10 rows of checkboxes manually, then the checkbox of main header must be checked. This is something normally observed in Yahoo, gmail, etc...
One way would be to count the number of checked ones and compare it with the total number of rows, and if found equal, then check the main one; otherwise, uncheck the main one. But I can't figure out where to do that... not working!
Update
<html>
<head><title>Checkbox puzzle</title></head>
<body>
<input type="checkbox" id="chkAppId" onclick="checkUncheck()"/>Main<br/>
<input type="checkbox" id="chkAppId1" onclick="check()"/>chk1<br/>
<input type="checkbox" id="chkAppId2" onclick="check()"/>chk2<br/>
<input type="checkbox" id="chkAppId3" onclick="check()"/>chk3<br/>
<script type="text/javascript">
function checkUncheck()
{
var totalRows = 4;
if(document.getElementById("chkAppId").checked){
checkedAll = true;
}
else{
checkedAll = false;
}
for(i = 1; i< totalRows; i++){
document.getElementById("chkAppId"+i).checked = checkedAll;
}
}
function check()
{
var totalRows = 4,count=0;
for(i = 1; i< totalRows; i++) {
if(document.getElementById("chkAppId"+i).checked){
count= count+1;
}
}
if(count ==totalRows - 1){
//alert("check Main");
document.getElementById("chkAppId").checked = true;
}
else
{
//alert("uncheck Main");
document.getElementById("chkAppId").checked = false;
}
}
</script>
</body>
</html>
This would be a simpler version that can explain the purpose, for anyone else who may need to implement such things.
When you dynamically insert the checkboxes, do you give them each different IDs?
Post the code you have and someone may be able to help you.
Here's a self-contained example with 'dynamic' rows.
<HTML>
<input type="button" value="add row" onclick="add_row()">
<table border id="my_table">
<TR><TH><input type="checkbox" onclick="header_check_click()" id="header_check"></TH><TH>HEADER</TH></TR>
</table>
<FORM name="frm">
<script language="javascript">
var g_check_ids = [];
function header_check_click()
{
var header_check = document.getElementById("header_check");
for (var k in g_check_ids)
{
var the_check = document.getElementById("check" + g_check_ids[k]);
the_check.checked = header_check.checked;
}
}
function fix_header_checkbox()
{
var all_checked = true;
for (var k in g_check_ids)
{
var the_check = document.getElementById("check" + g_check_ids[k]);
if (!the_check.checked)
{ all_checked = false;
}
}
var header_check = document.getElementById("header_check");
header_check.checked = all_checked;
}
function add_row()
{
var tbl = document.getElementById("my_table");
var cnt = tbl.rows.length;
var row = tbl.insertRow(cnt);
var checkCell = row.insertCell(0);
checkCell.innerHTML = "<input onclick=\"fix_header_checkbox()\" type=\"checkbox\" id=check" + cnt + ">";
g_check_ids.push(cnt);
var txtCell = row.insertCell(1);
txtCell.innerHTML = "Cell " + cnt;
fix_header_checkbox();
}
add_row();
</script>
</FORM>
</HTML>