Code for highlighting table cell code isn't working - javascript

I have a code that's supposed to show the table cell value when clicked on and also highlight the table cell that has been clicked on (Using CSS class). However, the table cell isn't highlighting for some reason. It works when I remove the table cell value code. I'm not sure what's wrong.
const myWords = ["LOL", "HEY", "TOYS", "YES", "SIR", "JOY"];
//Highlighting Table Cell code
//Goes through every 'td' on page
for (let node of document.querySelectorAll("td")) {
node.onclick = function() {
if (node.className == "") {
node.className = "selected"
} else {
node.className = ""
}
}
}
//Get Table Value code
var selectedWord = "";
var clicking = document.getElementsByTagName('td');
//Everytime the user click on a cell...
for (var i = 0; i < clicking.length; i++) {
var click = clicking[i];
click.onclick = function() {
selectedWord += this.innerHTML;
alert(selectedWord);
//Calls a function for each word in myWords
myWords.forEach(myFunction);
function myFunction(item, index) {
//If a word matches the selected word...
if (item == selectedWord) {
alert(item);
}
}
}
}

Related

Insert text to selected range with button

I apologize in advance for having little to no knowledge on this matter. I am familiar enough to utilize VBA but have recently made the switch to Sheets and I am lost.
I was originally looking for a way to prompt a drop down menu when double clicking a cell in a range that will then add the selected information as a prefix to the text.
Example: cell contains "First Last", upon double clicking you get a drop down to select "Mr., Mrs." when selecting "Mr." the cell now says "Mr. First Last" but it doesn't appear that you can set a double click event.
So now I am trying to come up with another solution where you select desired cells and 'apply' the function.
Example: Select cells A1 B1 C3 D9, click a button that applies "Mr. " as a prefix. Selecting it again will remove it.
Please help me get this moving.
Try this:
// menu
function onOpen() {
SpreadsheetApp.getUi().createMenu('⚡ Scripts')
.addItem('🎩 Add Mr', 'add_Mr')
.addItem('Remove Mr', 'remove_Mr')
.addToUi();
}
// functions
function add_Mr() {
var sheet = SpreadsheetApp.getActiveSheet();
var selection = sheet.getSelection();
var ranges = selection.getActiveRangeList().getRanges();
for (var i in ranges) {
var data = ranges[i].getValues();
for (var row in data) for (var col in data[row])
if (data[row][col] != '') data[row][col] = 'Mr. ' + data[row][col];
ranges[i].setValues(data);
}
}
function remove_Mr() {
var sheet = SpreadsheetApp.getActiveSheet();
var selection = sheet.getSelection();
var ranges = selection.getActiveRangeList().getRanges();
for (var i in ranges) {
var data = ranges[i].getValues();
for (var row in data) for (var col in data[row])
if (data[row][col] != '') data[row][col] = data[row][col].replace(/^Mr\. /,'');
ranges[i].setValues(data);
}
}
It will add menu Scripts and two commands 'Add Mr' and 'Remove Mrs' for selected cells.
And as a homework you can try to add add_Mrs() and remove_Mrs() functions.
If you need to toggle 'Mr' here you go:
function toggle_Mr() {
var sheet = SpreadsheetApp.getActiveSheet();
var selection = sheet.getSelection();
var ranges = selection.getActiveRangeList().getRanges();
for (var i in ranges) {
var data = ranges[i].getValues();
for (var row in data) for (var col in data[row]) {
var cell = data[row][col];
if (cell == '') continue; // if empty --> go to next cell
if (cell.match(/^Mr\. /)) { // if contains 'Mr.'
data[row][col] = cell.replace(/^Mr\. /,''); // --> remove 'Mr.'
continue; // --> go to next cell
} else {
data[row][col] = 'Mr. ' + data[row][col]; // else --> add 'Mr.'
}
}
ranges[i].setValues(data);
}
}
Update
Here is the same function toggle_Mr() with example how you can get the 'coordinates' of all processed cells:
function toggle_Mr() {
var sheet = SpreadsheetApp.getActiveSheet();
var selection = sheet.getSelection();
var ranges = selection.getActiveRangeList().getRanges();
for (var i in ranges) {
// get 'coordinates' (col, row) of first (left-top) cell of selected range
var start_col = ranges[i].getColumn();
var start_row = ranges[i].getRow();
var data = ranges[i].getValues();
for (var row in data) for (var col in data[row]) {
var cell = data[row][col];
// calculate the real 'coordinates' of processed cells
var real_col = +start_col + +col;
var real_row = +start_row + +row
console.log('Process the cell [' + real_col + '][' + real_row + ']');
if (cell == '') continue;
if (cell.match(/^Mr\. /)) {
data[row][col] = cell.replace(/^Mr\. /,'');
continue;
} else {
data[row][col] = 'Mr. ' + data[row][col];
}
}
ranges[i].setValues(data);
}
}
You can see the cell 'coordinates' in console if you run the function from the Script Editor.

How to make a button functional when loaded into a row from local storage in javascript

//loops through all rows and cells and saves them into local storage as objects
window.onbeforeunload = function() {
var rows = document.getElementById('firsttable').tBodies[0].rows;
for (var i = 0; i < rows.length; i += 1) {
localStorage.setItem(i, JSON.stringify({
Item: rows[i].cells[0].innerHTML,
filling1: rows[i].cells[1].innerHTML,
filling2: rows[i].cells[2].innerHTML,
filling3: rows[i].cells[3].innerHTML,
Stock: rows[i].cells[4].innerHTML,
min: rows[i].cells[5].innerHTML,
sold: rows[i].cells[6].innerHTML,
closeAcc: rows[i].cells[7].innerHTML,
sell: rows[i].cells[8].innerHTML,
dltButton: rows[i].cells[9].innerHTML
}));
};
};
//loads the objects into rows with the values in their cells
window.onload = function() {
var r = 0,
c = 0;
//load the actual data from localstorage into html rows
for (x in localStorage) {
var row = table.insertRow(r),
obj = JSON.parse(localStorage.getItem(x));
for (i in obj) {
var cell = row.insertCell(c);
cell.innerHTML = obj[i];
c += 1
}
r += 1;
c = 0;
}
};
//where the problem is
$(function() {
$('table td').click(function(e) {
if (e.target.id === "Sellbtn") {
var sell = prompt("Enter the amount");
for (var i = 0; i < table.length; i += 1) {};
this.parentNode.parentNode.cells[4].innerHTML = parseInt(this.parentNode.parentNode.cells[4].innerHTML) - sell; //not working and no when put inside the for loop it doesn't work idk why
} else if (e.target.id === "Deletebtn") {
return false;
} else {
var ask = prompt("Input");
$(this).html(ask);
}
});
});
So i insert a row and add the details to the cells and such then as explained in the snippet the first function saves available the rows and cells into a JSON stringified object in the localstorage when the user is closing the browser and then loads them up during onload the problem is with the buttons idk how to make them function after the onload(user closes and opens again). So imagine this you have your HTML table with several rows and their cells and each row has the two buttons(sell and delete) how do i make them function when the user opens up the application again? and btw the buttons are both dynamically added using createElement() when the row is originally added
Try delegating the click event you have on your table rows since they're being created after the DOM loads:
$('table').on("click", "td", function(e) {

Get contents of the first cell in the clicked column and the first cell of the clicked row in a HTML table

I'm using the following javascript to get the data in a clicked table cell:
var table = document.getElementById('ThisWeek'),
cells = table.getElementsByTagName('td');
for (var i=0,len=cells.length; i<len; i++)
{
cells[i].onclick = function()
{
document.getElementById("txtVal").value = this.innerText;
}
}
How can I modify this so I can also obtain the contents of the first cell in the clicked column and the first cell in the clicked row? E.g. if I click on "s" in the table below, I get the results "2" and "B" returned as two variables:
0 1 2 3
A q w e
B a s d
C z x c
Please note that I need a javascript solution, not jQuery. Ideally, I would also like clicks on the first row and first column to return empty strings.
This snippet uses the properties I've mentioned in my comment:
window.onload = function () {
var table = document.getElementById('table');
table.addEventListener('click', function (e) {
var target = e.target,
col = target.cellIndex,
row;
while (target = target.parentElement) {
if (!col && col !== 0) {
col = target.cellIndex;
}
if (target.tagName.toLowerCase() === 'tr') {
row = target.rowIndex;
break;
}
}
console.log(table.rows[row].cells[0].innerHTML + ', ' + table.rows[0].cells[col].innerHTML);
});
}
A live demo at jsFiddle.
I'd suggest:
function index(c){
var i = 0;
while (c.previousSibling){
/* if the previousSibling has a nodeType and that nodeType === 1
(indicating the previousSibling is an element) increment the i variable */
if (c.previousSibling.nodeType && c.previousSibling.nodeType === 1){
i++;
}
// reset c to the previousSibling
c = c.previousSibling;
}
/* i is the count of previous-siblings, and therefore the index
amongst those siblings: */
return i;
}
function getHeaders(e){
/* this is the table element,
e.target is the clicked element */
var el = e.target,
text = 'textContent' in document ? 'textContent' : 'innerText',
headers = [el.parentNode.getElementsByTagName('td')[0][text],this.getElementsByTagName('tr')[0].getElementsByTagName('td')[index(el)][text]];
// set the text of the nextElementSibling of the table:
this.nextElementSibling[text] = headers.join(', ');
}
document.getElementById('table').addEventListener('click', getHeaders);
JS Fiddle demo.
You can add this to your cells[i].onclick function:
var row = this.parentElement; // TR
var table = row.parentElement.parentElement; // TBODY > TABLE
document.getElementById("columnVal").value = row.rowIndex && this.cellIndex ? table.rows[0].cells[this.cellIndex].innerText : "";
document.getElementById("rowVal").value = row.rowIndex && this.cellIndex ? row.cells[0].innerText : "";

TD class staying active when another TD class selected

I need guidance editing a file. I have posted the Javascript below. This is a link to my working example http://www.closetos.com/top-shelf-awards_copy_copy.
The problem occurred when I added an additional row to the table. Now, when you select the text link in a cell in the second row, it stays selected and active, when clicking on something in the top row.
function $(id)
{
return document.getElementById(id);
}
function Coalesce(Value, Default)
{
if(Value == null)
return Default;
return Value;
}
function Switcher(numberOfSections, sectionContainerID, activeClass, inactiveClass)
{
this.NumberOfSections = Coalesce(numberOfSections, 1) - 1;
this.SectionContainerID = Coalesce(sectionContainerID, "sectionContainer");
this.ActiveClass = Coalesce(activeClass, "active");
this.InactiveClass = Coalesce(inactiveClass, "");
}
Switcher.prototype.Switch = function(TheLink, SectionID)
{
// Make sure all sections are hidden
var SectionContainer = $(this.SectionContainerID);
for(var ct = 0; ct < SectionContainer.childNodes.length; ct++)
{
var node = SectionContainer.childNodes[ct];
if(node.nodeType != 1)
continue;
node.style.display = "none";
}
var First = true;
// Reset button styles
for(var ct = 0; ct < TheLink.parentNode.childNodes.length; ct++)
{
if(TheLink.parentNode.childNodes[ct].nodeType != 1)
continue;
else node = TheLink.parentNode.childNodes[ct];
node.className = this.InactiveClass;
if(First)
{
node.className += " firstCell";
First = false;
}
}
// Show the selected section
$(SectionID).style.display = "block";
TheLink.className = this.ActiveClass;
if(TheLink == node)
TheLink.className += " lastCell";
}
You problem is in this section of code. this looks only at the row that the clicked cell is in. TheLink.parentNode is a reference to the row that the cell is in.
for(var ct = 0; ct < TheLink.parentNode.childNodes.length; ct++) <--- parenNode == row
{
if(TheLink.parentNode.childNodes[ct].nodeType != 1)
{
continue;
}
else
{
node = TheLink.parentNode.childNodes[ct];
}
node.className = this.InactiveClass;
if(First)
{
node.className += " firstCell";
First = false;
}
}
In order to make this work with multiple rows you need to modify it to look at other rows in the table:
for(var ct = 0; ct < TheLink.parentNode.parentNode.childNodes.length; ct++)
{
for( innerL = 0; innerL < TheLink.parentNode.parentNode.childNodes[ct].childNodes.length; innerL++)
{
if(TheLink.parentNode.parentNode.childNodes[ct].childNodes[innerL].nodeType != 1)
{
continue;
}
else
{
node = TheLink.parentNode.parentNode.childNodes[ct].childNodes[innerL];
}
node.className = this.InactiveClass;
if(First)
{
node.className += " firstCell";
First = false;
}
}
}
in the block above you are looking at the parentNode's (the tr) parentNode (tbody) and then iterating through its grandchildren. This allows you to capture all the cells in the table, not just the row.
Here is an example of it working. When you follow the link you need to hit the green 'run' button on the bottom left of the page to get the script to load.

Making a row editable based on a checkbox in HTML

I have a table in HTML. The contents of this table are dynamically populated. Every row of the table has text boxes and one checkbox. When the page is loaded, all the text boxes in the rows will be in a read-only state.
Now, i want to change the state of the text boxes in a particular row to editable, if the check-box in that row is selected. Also, the text boxes should be made read-only if the check box is de-selected.
How could I accomplish this using Javascript? Please help me.
stating this with plain javascript would be pure pain :)
i suggest using jQuery, eg:
$(':checkbox').click(function() {
var checkbox = $(this);
var row = checkbox.closest('tr');
var inputText = $('input[type=text]', row);
if (checkbox.is(':checked')) {
inputText.attr('readonly', 'readonly');
}
else {
inputText.removeAttr('readonly');
}
});
otherwise
function HandleClickOnCheckbox() {
var checkbox = this;
var row;
var iter = checkbox;
while (!row) {
iter = iter.parent;
if (iter == window) {
break;
}
if (iter.tagName == 'tr') {
row = iter;
break;
}
}
if (!row) {
alert('row not found');
return false;
}
var textBoxes = GetTextBoxes(row);
var method;
if (checkbox.checked) {
var disabledAttribute = document.createAttribute('disabled');
disabledAttribute.nodeValue = 'disabled';
method = function(textBox) {
textBox.setAttributeNode(disabledAttribute);
};
}
else {
method = function(textBox) {
textBox.removeAttribute('disabled', 0);
}
}
for (var i = 0; i < textBoxes.length; i++) {
var textBox = textBoxes[i];
method(textBox);
}
}
function GetTextBoxes(element) {
var textBoxes = new Array();
for (var i = 0; i < element.children.lenght; i++) {
var child = element.children[i];
if (child.tagName == 'input') {
if (child.type == 'text') {
textBoxes.push(child);
}
}
if (child.tagName == 'td') {
var childTextBoxes = GetTextBoxes(child);
if (childTextBoxes.length) {
for (var j = 0; j < childTextBoxes.length; j++) {
var childTextBox = childTextBoxes[j];
textBoxes.push(childTextBox);
}
}
}
}
return textBoxes;
}
this is not tested!
Perhaps, you can start by handling the click event of the checkbox using an if/else statement to check if the checkbox is actually checked. If it is you can use the row within which the checkbox resides to find all the textboxes in the different cells and enable/disable them.
Are you using JQuery or plain Javascript?
If you don't mind using jQuery, you could do:
$('checkbox').click(function() {
if ($(this).attr('checked')) {
$(this).parents('tr').children('input[type="text"]').each().attr('readonly', 'readonly');
} else {
$(this).parents('tr').children('input[type="text"]').each().removeAttr('readonly');
}
})
Or something like that. I'd have to test it to be sure.
Edited to reflect Andreas's comment.
Try this snippet (assumes that the checkbox has a class called "checkbox") if you are using Jquery.
jQuery('tr.checkbox').click(function() {
if (jQuery(this).is(":checked")) {
jQuery('td', this).removeAttr('disabled');
} else {
jQuery('td', this).attr('disabled', '');
}
});`

Categories

Resources