Variable not changing inside function once changed for next use - javascript

I am trying to remove columns from a table on the click of a button, however; when I use the button and it removes the last column, if I then want to remove another column I run into an issue where a critical variable isn't updated.
JS:
function deleteCol(){
debugger;
var tds = document.getElementById("icol").value;
var cold = document.getElementsByClassName(tds-1);
for (var i = 0; i < tds; i++) {
var inc = 0;
var lastCol = cold[inc];
lastCol.remove();
}
tds--;
}
Here I am trying to alter the value of tds after the loop has taken place, but when I next use the button it uses the initial tds value over again and not the updated version, can someone explain to me why it doesn't re assign the tds variable for when I use it next time? edit the function I have here is basically removing the last cell on each row.

You're only updating a variable rather than the live attribute value, instead do this:
var input = document.getElementById("icol");
var tds = input.value;
.
.
.
input.value = --tds

Related

JS / GS Simple Google Sheets Script

Im trying to create a simple script that firstly checks (all cells in row 3 starting from column 3) for whether they contain a name different from the available sheets and if so create a new one. If not go to the next cell down. Preferably until the row is empty but I didnt get that far. Currently I have
var row = 3; //Global Variable
function Main() { // Main Function
Activate();
GetNames();
}
function Activate() { // Initialize
var get = SpreadsheetApp.getActiveSpreadsheet();
var import = get.getSheetByName("Import");
}
function GetNames() { // Get Names and check for existing Sheets
var ss = SpreadsheetApp.getActiveSpreadsheet();
var import = ss.getSheetByName("Import");
var sheet = ss.getSheets()[0];
for (i = 0; i < 1000; i++) { // Loop which I think is broken
var names = import.getRange(row,3).getValue();
if (import.getSheetByName(names) == null) {
import.insertSheet(names);
import.activate();
}
row + 1;
}
}
And here is the Data
It succeeds to add the first sheet but fails to continue in the loop I think.
As you will probably see I'm very new to this and any help would be appreciated.
You probably wanted to increase row by 1 here:
row + 1;
But you're not. row + 1 is just an expression with a value (4, in your example, because row remains 3 throughout). What you would need is the statement
row = row + 1;
But if this is all that you're using the global variable row for, you don't need it at all. Just use the loop variable i that's already counting from 0 to 1000. You probably want something like import.getRange(i+3,3).

Cant set the value of a cell within a row because it was converted to object or array with no methods

I am trying to write a function that will iterate over each row in a master spreadsheet and check the value of the 3rd column against every row in a second spreadsheet and compare it with the value in the 6th column, then change the value in the 4th column of the master spreadsheet based on the result. The script is a standalone script because its part of a larger project.
The problem is that when I try to set the value of the 4th column in the spreadsheet, I am getting an error that reads "Cannot find function setValue in object SENT". SENT is the value that is in that cell, and I do not understand how it became an object or how I would need to change to code to get at the value to change it. I checked this post about someone having a problem not being able to act on a date value, but I could not figure out how to take that feedback and apply it to this problem.
function eFormCheck() {
var masterSS = SpreadsheetApp.openById("mastersheet");
var masterSheet = masterSS.getSheets()[0];
var masterRange = masterSheet.getDataRange();
var masterData = masterRange.getValues();
var workersCompSent = "SENT";
var workersCompRec = "RECEIVED";
var workersCompSS = SpreadsheetApp.openById("formsheet");
var wcSheets = workersCompSS.getSheets()[0];
var wcRange = wcSheets.getDataRange();
var wcData = wcRange.getValues();
for (var i = 1; i < masterData.length; i++) {
var row = masterData[i];
var email = row[2];
var rowLog = row[3]; //on my spreadsheet this value is "SENT"
for (var j = 1; j < wcData.length; j++) {
var wcRow = wcData[j];
var wcEmail = wcRow[5];
if (email == wcEmail) {
rowLog.setValue(workersCompRec);//having an issue with the value of the third column being an object, but I don't understand how its an object
}
}
}
}
The setValue() method only works on the Range Class. You can't chain the setValue() method to a variable or a cell value. You must first define a range. There are 4 variations of the getRange() method. If you want to set a value in a single cell, then you must get a range that is a single cell. You may need to use your variable i in the getRange() method to get the row. If the column is always the same, then you can "hard code" the column value.
sheet.getRange(i, 4).setValue(workersCompRec);

Remove all child nodes but the first one

I have an HTML table. The first row contains a checkbox. There is a javascript method associated to the checkbox change. If the checkbox is checked, the code adds a few rows to the table and fills them. If the checkbox is unchecked, the code removes all rows but the first one (the one that contains the checkbox).
The first part of the code works fine : the rows are properly added.
I have an issue with the second part. Here is my code :
if (checkboxValue) {
//Add first row
var tr1 = document.createElement("tr");
var td1_1 = document.createElement("td");
....
tr1.appendChild(td1_1);
var td1_2 = document.createElement("td");
...
tr1.appendChild(td1_2);
table.appendChild(tr1);
//Add second row
var tr2 = document.createElement("tr");
var td2_1 = document.createElement("td");
...
tr2.appendChild(td2_1);
var td2_2 = document.createElement("td");
...
tr2.appendChild(td2_2);
table.appendChild(tr2);
} else {
//Remove all rows but the first
var rows = table.getElementsByTagName("tr");
var nbrRows = rows.length;
if (nbrRows > 1) {
for (var i = 1; i < nbrRows; i++) {
var row = rows[i];
row.parentNode.removeChild(row);
}
}
}
The issue always come from rows[2] being undefined. I have no idea why!
If, instead of using removeChild, I write row.innerHTML = "", I have the visual effect I am looking for (all rows gone), but this is inelegant, since the table now contains several empty rows (their number increasing everytime I check/uncheck the checkbox).
A clue? Thank you very much for your time!
Don't use for-loop to remove DOM elements like this. The problem is that rows is a live collection, meaning that it updates every time you remove elements from DOM. As the result, i counter shifts and eventually you hit "undefined" element spot.
Instead, use while loop. For example, to remove all rows except the first one you could do:
var rows = table.getElementsByTagName("tr");
while (rows.length > 1) {
rows[1].parentNode.removeChild(rows[1]);
}
Also note, that it's getElementsByTagName without s.
UPD. Or iterate backward if you like for-loops better:
var rows = table.getElementsByTagName("tr");
for (var i = rows.length - 1; i > 0; i--) {
rows[i].parentNode.removeChild(rows[i]);
}
Demo: https://jsfiddle.net/9y03co6w/
you remove a row from the array you are iterating over. This is always a bad idea and probably the reason for your error.
solution: start iterating from the end instead of the beginning.
also see for example: example
try to replace this line
var rows = table.getElementsByTagNames("tr");
by
var rows = table.find("tr");

copying values from one textbox to another based on the input type id

With reference to the question regarding replicating values from one textbox to another
Replicating the values to another textbox
The solution works well if there are only two text boxes. But it fails when the index is running on loop.
For Ex - let us consider the table has list of text boxes in each row
1st row textbox1 textbox2
2nd row textbox3 textbox4
the id for each box is generated based on the status index. When I update the value in textbox1 textbox2 gets updated. But when I update textbox3 , instead of updating textbox4.textbox2 is updated.
Because the linked code updates textbox2 directly. Put the ids in an array and iterate over it to set the value of each text box, e.g.
function updateTextareas(el) {
var value = el.value;
for (var i=1, iLen=arguments.length; i<iLen; i++) {
document.getElementById(arguments[i]).value = value;
}
}
Then you can call it like:
document.getElementById('input1').onkeyup = function () {
updateTextareas(this,'textbox2','textbox3',...);
};
or some similar strategy.
Give all elements in the set the same name (or classname, and use getElementsByClassName). Then do the following pseudocode in javascript:
// onmodify:
var name = thisTextarea.name;
var newText = thisTextarea.text;
var elementsToUpdate = document.getElementsByName(name);
for each textarea in elementsToUpdate {
if (textarea != thisTextarea) // may not even need this line
textarea.text = newText;
}

Javascript table creation

Trying to create a table using the following code but not working. Please point out where I'm going wrong.
var i,j;
function cell(ih){
var tcell =document.createElement('td');
tcell.innerHTML=ih;
return tcell;
}
mutable=document.createElement('table');
for (i=0;i<10;i++){
row1=document.createElement('tr');
for(j=0;j<10;j++){
row1.appendChild(cell(j));
}
mutable.appendChild(row1);
document.write(mutable);
}
You have several problems, the first two are the big ones, the second two are a matter of style and risk of clashes with other code:
You are trying to document.write HTMLElementNodes. document.write only deals with strings. Grab a container element (e.g. with document.getElementById) and append to it
You are trying to document.write the entire table every time you add a row to it. Append the table once the table is complete, not every time you go through the loop.
You are using globals all over the place, learn to love the var keyword
row1 is a poor variable name for the row you are operating on which usually isn't the first
Use document.body.appendChild(...) instead of document.write(...).
You can do it by changing your script to use document.body.appendChild(mutable) after your nested for loop:
var i,j;
function cell(ih){
var tcell =document.createElement('td');
tcell.innerHTML=ih;
return tcell;
}
mutable=document.createElement('table');
for (i=0;i<10;i++){
row1=document.createElement('tr');
for(j=0;j<10;j++){
row1.appendChild(cell(j));
}
mutable.appendChild(row1);
}
document.body.appendChild(mutable);
This appends the entire mutable table object you've created to the <body> element of your page. You can see it working here.
Also note that most times in markup, you don't see the <tbody> element, but it is good practice to append this as a child element of the <table> and as a parent element for all of your rows. So, your script should look more like this:
function cell(ih){
var tcell = document.createElement('td');
tcell.innerHTML = ih; // I would suggest you use document.createTextNode(ih) instead
return tcell;
}
function appendTable() { // you now have to call this function some time
mutable = document.createElement("table");
var tBody = mutable.appendChild( document.createElement("tbody") ); // technique using "fluid interfaces"
for (var i = 0; i < 10; i++) {
var row1 = tBody.appendChild( document.createElement('tr') ); // fluid interface call again
for(var j = 0; j < 10; j++) {
row1.appendChild(cell(j));
}
}
document.body.appendChild(mutable);
}
I made some style changes to your script, and I would suggest making even more, but as far as correctness, it should work.

Categories

Resources