This question already has answers here:
JavaScript and getElementById for multiple elements with the same ID
(13 answers)
Iterating over result of getElementsByClassName using Array.forEach
(14 answers)
Closed 6 months ago.
I'm trying to change the value of colspan using the below code but its only working for January. It should work for both January and February. By clicking the button the value of the colspan attribute, from 2 to 1, of td with id "myTd".
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head>
<body>
<p>Click the button to change the value of the colspan attribute, from 2 to 1, of td with id "myTd".</p>
<table>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td id="myTd" colspan="2">January</td>
<td>$100</td>
</tr>
<tr>
<td id="myTd" colspan="2">February</td>
<td>$100</td>
</tr>
</table>
<br>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
document.getElementById("myTd").colSpan = "1";
}
</script>
</body>
</html>
The cause of your issue is because you've repeated the same id on multiple elements, which is invalid. id must be unique within the DOM. Change these to common class attributes.
From there you can use querySelectorAll() and loop through the resulting collection to update their colspan:
document.querySelector('button').addEventListener('click', e => {
document.querySelectorAll(".myTd").forEach(el => el.colSpan = "1");
});
table,
th,
td {
border: 1px solid black;
}
<p>Click the button to change the value of the colspan attribute, from 2 to 1, of td with id "myTd".</p>
<table>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td class="myTd" colspan="2">January</td>
<td>$100</td>
</tr>
<tr>
<td class="myTd" colspan="2">February</td>
<td>$100</td>
</tr>
</table>
<br>
<button>Try it</button>
Note the use of addEventListener() in the above example. This is an unobtrusive event handler bound in JS code, not HTML. It's much better practice over using inline onclick attributes.
Related
The question regarding the copying has certainly been addressed before. I'd like to know if this can be avoided: When pasting the clipboard to a notepad, i. e. I need the plain text, there's always an initial and final blank line in the copied text.
Any solution for the snippet below (or any other suggested code) that really only copies the two lines without this initial and final empty line in plain text?
[blank line]
test1 test2
test3 test4
[blank line]
let table = document.querySelector('#testTable');
let button = document.querySelector('#button');
function selectNode(node) {
let range = document.createRange();
range.selectNodeContents(node)
let select = window.getSelection()
select.removeAllRanges()
select.addRange(range)
}
button.addEventListener('click', function () {
selectNode(table);
document.execCommand('copy')
})
<style>
td {
border: 1px solid black;
}
</style>
<table collapsed id='testTable'>
<tr>
<td>test1</td>
<td> </td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td> </td>
<td>test4</td>
</tr>
</table>
<br />
<button id="button">select</button>
While I don't know the reason, adding a <tbody> element and selecting that one seems to be a possible workaround:
let table = document.querySelector('#testTable');
let button = document.querySelector('#button');
function selectNode(node) {
let range = document.createRange();
range.selectNodeContents(node)
let select = window.getSelection()
select.removeAllRanges()
select.addRange(range)
}
button.addEventListener('click', function() {
selectNode(table);
document.execCommand('copy')
})
<style>
td {
border: 1px solid black;
}
</style>
<table>
<tbody id='testTable'>
<tr>
<td>test1</td>
<td> </td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td> </td>
<td>test4</td>
</tr>
</tbody>
</table>
<br>
<button id="button">select</button>
This question already has answers here:
How can I select an element which does not contain a certain child element?
(8 answers)
Closed 4 years ago.
I'm using jQuery to conduct some action while clicking a certain 'tr', yet within that object I would like jQuery to ignore one of the children td which contains a url.. Any ideas how can this be done?
<tr class="parent_report>
<tr class="child1">Some text</tr>
<tr class="child2">Some text</tr>
<tr class="child3"><span>Some text</span></tr>
</tr>
And the jQuery:
$(".special_report, .new_report ,.parent_report").not("span").click(function(event){
event.preventDefault();
//do some action
So I would like to ignore the jQuery when clicking the link in child3 and not doing the action configured to jQuery
Any ideas?
Thanks
You are saying that any of the classes you selected can not be a span. You are not saying what is clicked....
So you need to do the check inside of the click that the action is not an anchor
$("tr").on("click", function (evt) {
if ($(evt.target).closest("a").length) {
return true
} else {
console.log("tr was clicked");
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>baz</td>
<td class="child3"><span>Some text</span></td>
</tr>
</tbody>
</table>
If you do not want any click on the td, than just ignore clicks on that td
$("tr").on("click", "td:not(:has(a))", function(evt) {
console.log("tr was clicked");
})
td {
padding: 1em;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>baz</td>
<td class="child3"><span>Some text</span></td>
</tr>
</tbody>
</table>
I'd move your click events to the table cells for more intuitive code.
$("td").not(':has("a")').click(function () {
console.log("tr was clicked");
});
<style>
td {
padding: 10px;
background: pink;
}
a {
background: lightgreen;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>baz</td>
<td class="child3"><span>Some text</span></td>
</tr>
</tbody>
</table>
I'm trying to figure out if I can name an entire column with the same class name in a table, without having to name each individual cell. Any suggestions? Would I use html, css or javascript to do so? Is naming every cell the only way to do so?
Sorry if I post this in the wrong area, I'm new to this site and still trying to figure it out
You can use the nth-child pseudo class selector
table tr td:nth-child(2) {
background: #CCCCCC;
}
table tr td:nth-child(4) {
background: #00FFEE;
}
<table>
<tbody>
<tr>
<td>1-1</td>
<td>1-2</td>
<td>1-3</td>
<td>1-4</td>
</tr>
<tr>
<td>2-1</td>
<td>2-2</td>
<td>2-3</td>
<td>2-4</td>
</tr>
<tr>
<td>3-1</td>
<td>3-2</td>
<td>3-3</td>
<td>3-4</td>
</tr>
<tr>
<td>4-1</td>
<td>4-2</td>
<td>4-3</td>
<td>4-4</td>
</tr>
</tbody>
</table>
If you want to add a class to all the elements inside the table (the td elements in this case) you can do so with jQuery.
$('td').addClass('my-class');
.my-class{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>1-1</td>
<td>1-2</td>
<td>1-3</td>
<td>1-4</td>
</tr>
<tr>
<td>2-1</td>
<td>2-2</td>
<td>2-3</td>
<td>2-4</td>
</tr>
<tr>
<td>3-1</td>
<td>3-2</td>
<td>3-3</td>
<td>3-4</td>
</tr>
<tr>
<td>4-1</td>
<td>4-2</td>
<td>4-3</td>
<td>4-4</td>
</tr>
</tbody>
</table>
With the example above you're basically telling jQuery to target all of the td elements and add your class to each one of them. However, this will apply the class to ALL the td elements in your DOM. If you want to apply the class only to the elements of a specific table, you can do so with:
$('.parent-class').find('td').addClass('your-class');
and you can add the parent-class to your <tbody> element of table. That way you find all the elements that match.
I have a problem that I can't solve how much I try. By clicking on the Edit Customer button I wan't to get the value from the CustomerNr cell. My problem is that I don't know how to get the row index by clicking on a button and then pass it to my function so I can specifically get the CustomerNr on that row I pressed the button on. You can take a look at my jsfiddle link and note, this is the first time I code in Javascript/Jquery. I'm open for smart solutions.
Here you can see how far I came. I managed to select value from a specific cell.
function GetCellValues() {
var Row = document.getElementById("somerow");
var Cells = Row.getElementsByTagName("td");
alert(Cells[0].innerText);
}
I have managed to get the row index by clicking on on a td but I want to get it by pressing a button.
function myMethod(obj) {
alert(obj.parentNode.rowIndex); // parentNode is also used
}
I wan't to somehow combine this two functions, like in C#. (I'm a C# programmer)
function GetCellValues(e) {
//Something here
alert(Cells[0].Rows[e] innerText);
}
http://jsfiddle.net/6srjc7qL/
I've changed the id's of your buttons to classes, as you can't name two elements with the same id, then I looped through the elements... Working fiddle
You should avoid to use inline functions and pereferably do it like this, this might safe you a lot of time and keeps it better maintainability:
Javascript:
var a = document.getElementsByClassName('otherButton');
for (var i = 0; i<a.length;i++) {
a[i].addEventListener('click',function(){
var b = this.parentNode.parentNode.cells[0].textContent;
alert(b);
});
}
HTML:
<table id="somerow">
<tr>
<th>CustomerNr</th>
<th>Name</th>
<th>Contact</th>
</tr>
<tr >
<td>1</td>
<td>Cigarettes Inc</td>
<td>Rambo</td>
<td>
<button class="otherButton" >Edit Customer</button>
</td>
</tr>
<tr >
<td >22</td>
<td>Razor</td>
<td>David</td>
<td>
<button class="otherButton">Edit Customer</button>
</td>
</tr>
<tr>
<td>3</td>
<td>H&M</td>
<td>Samuel Adams</td>
<td>
<button class="otherButton" >Edit Customer</button>
</td>
</tr>
}
the button is inside the td which is inside the tr, so you need to go 2 nodes up. Try this:
function GetCellValues(obj) {
alert(obj.parentNode.parentNode.rowIndex);
}
HTML
<html>
<head>
<style>
table, td {
border: 1px solid black;
}
.selected {
background-color: yellow;
}
</style>
</head>
<body>
<center>
<table id="somerow">
<tr>
<th>CustomerNr</th>
<th>Name</th>
<th>Contact</th>
</tr>
<tr>
<td>1</td>
<td>Cigarettes Inc</td>
<td>Rambo</td>
<td>
<button id="otherButton" onclick="GetCellValues()">Edit Customer</button>
</td>
</tr>
<tr>
<td onclick="myMethod(this);">22</td>
<td>Razor</td>
<td>David</td>
<td>
<button id="otherButton" onclick="GetCellValues()">Edit Customer</button>
</td>
</tr>
<tr>
<td>3</td>
<td>H&M</td>
<td>Samuel Adams</td>
<td>
<button id="otherButton" onclick="GetCellValues()">Edit Customer</button>
</td>
</tr>
</center>
</body>
</html>
JS
function GetCellValues(elm) {
alert(elm.parentNode.parentNode.cells[0].textContent);
}
function myMethod(obj) {
alert(obj.parentNode.rowIndex);
}
I know I can include <td colspan=10> statically when I want to merge the columns, but if I need to check some conditions and based on that only I need to merge then how this could be done?
My idea was like this:
var span="";
if(some condition)
span="colspan=10";
and then setting this variable inside <td> as:
<td +span+>
but it doesn't work like that… Any suggestion how to do this?
<table id="table" border=2>
<tr id="row1">
<td id="tableCellID">foo</td><td></td>
</tr>
<tr>
<td>foo</td><td>foo</td>
</tr>
</table>
<button onclick="button();" text="Change"/>
<script language="javascript">
var i = 0;
function button(){
var td = document.getElementById("tableCellID");
if(i==0){
td.setAttribute("colspan", 2);
i=1;
}else{
td.setAttribute("colspan", 1);
i=0;
}
}
</script>
This is how you can dynamically set the attribute colspan. You will see that changing the colspan of one cell will effect the layout of the entire table. You will need to deal with each cell in the row.
var span='';
var table='';
if(some condition)
span="colspan=10";
var table="<tr><td"+span+"></td></tr>":
One way to do is, if you able to set an id in your td
<td id="foo">
in your javascript, you can add attributes like this,
document.getElementById("foo").colSpan="10";
document.querySelector("tr.total td").style.backgroundColor = "#ccc";
document.querySelector("tr.grand td:nth-child(1)").colSpan="2";
document.querySelector("tr.grand td:nth-child(2)").remove();
table, table td {border:1px solid #ccc; padding:5px 10px; border-spacing:0px;}
.grand{font-weight:bold;}
<table>
<tr>
<td>Column</td>
<td>Value</td>
</tr>
<tr class="total">
<td>Sub Cost</td>
<td>$500</td>
</tr>
<tr class="grand">
<td>Amount $1000</td>
<td>Remove Me</td>
</tr>
</table>