Adding n <td> to every <tr> in a table - javascript

My purpose is simple is to add 'n' <td> to every <tr> in a table.
the problem i am facing is that, it is adding only one <td>, not n <td>, in the last <tr> ,not in all <tr>, with class 'n'
var actions = function(){
return { // this is going to return a long object containg a list of mny function which can be called any time
whichPattern: "pattern1",
addSlots:function(n){
var e =document.getElementById(this.whichPattern),
c = e.children[0].children,
ap_e = document.createElement('td');
for(var i=0; i<c.length; i++){
for(var j=0; j<=n; j++){
var parent = c[i];
ap_e.setAttribute("class", String(j));
parent.appendChild(ap_e);
}
};
pattern_config[this.whichPattern].WP_slotsCounter=n;
//console.log(this);
},
}
};
var pattern_config = {
pattern1:{
WP_slotsCounter:0,
},
};
window.onload = actions().addSlots(3)
<head>
<script type="text/javascript" src="actions.js" ></script>
</head>
<body>
<div id="pattern_body">
<div></div>
<table id="pattern1" border="2">
<tr class="kick instrument">
<td class='1'>gg</td>
<td class="2">dd</td>
</tr>
<tr class="snare instrument">
<td class='1'>vv</td>
<td class="2">aa</td>
</tr>
<tr class="cymbal instrument">
<td class='1'>kk</td>
<td class="2">tt</td>
</tr>
</table>
</div>
</body>

A node can exist only in one location in the tree at a time.
You can use .cloneNode(true) to make a copy to append.
var clone = ap_e.cloneNode(true);
clone.className = String(j);
parent.appendChild(clone);
I also changed setAttribute to set the className property instead.
In this particular case, since the node is really pretty simple, you may just want to create it in the same place where you're appending it instead of creating it beforehand and cloning it.

Related

How to break out to the parent tag and get the innerHTML of the next tag with javascript?

I would like to get the value "450" next to the strong tag with "Total:" in it. I cant seem to identify this. I've tried using parentNode etc and I cannot find the right combination. Would be grate
Here is a jsfiddle of it - https://jsfiddle.net/smduy1w3/
<tfoot>
<tr>
<td colspan="4" class="text-right"><strong>Sub-Total:</strong></td>
<td class="text-right">£450.00</td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>Total:</strong></td>
<td class="text-right">£450.00</td>
</tr>
</tfoot>
var aTags = document.getElementsByTagName("strong");
var searchText = "Total:";
var found;
for (var i = 0; i < aTags.length; i++) {
if (aTags[i].textContent == searchText) {
found = aTags[i];console.log(found.previousNode);
break;
}
}
Here you can check my solution. I've just searched for the element with strong tag with the text "Total" and then find out the next sibling using nextSibling and that did the work for me.
const tds = [...document.querySelectorAll("td.text-right")];
const selected = tds.find((td) => td.innerHTML === `<strong>Total:</strong>`);
let nextSibling = selected.nextSibling;
while (nextSibling && nextSibling.nodeType !== 1) {
nextSibling = nextSibling.nextSibling;
}
console.log(nextSibling.innerText.substr(1));
<table>
<tfoot>
<tr>
<td colspan="4" class="text-right"><strong>Sub-Total:</strong></td>
<td class="text-right">£450.00</td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>Total:</strong></td>
<td class="text-right">£450.00</td>
</tr>
</tfoot>
</table>
I believe you have a couple of problems with your code:
First, for some reason, you need to wrap your html inside a <table> tag, or else the html isn't properly parsed.
Second, the search anchor <strong>Total:</strong> is a child node of its parent node <td> and the target <td class="text-right">£450.00</td> is a sibling of that parent, not the way you had it in your code.
So, assuming your html is fixed, you need to change
found = aTags[i];
console.log(found.previousNode);
to
found = aTags[i];
console.log(found.parentNode.nextSibling.nextSibling.textContent);
Second, I would argue that using xpath is a cleaner way of reaching your target; something along these lines:
target = document.evaluate( './/table//tr/td[strong[.="Total:"]]/following-sibling::td' ,document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
for (var i = 0; i < target.snapshotLength; i++) {
price = target.snapshotItem (i);
console.log(price.textContent);
};
Try this:
var aTags = document.getElementsByTagName("strong");
var searchText = "Total:";
var found;
for (var i = 0; i < aTags.length; i++) {
if(aTags[i].textContent.includes(searchText)){
//console.log(aTags[i].textContent);
found = aTags[i].nextSibling.textContent;
console.log(found);
}
}
<tfoot>
<tr>
<td colspan="4" class="text-right"><strong>Sub-Total:</strong></td>
<td class="text-right">£450.00</td>
</tr>
<tr>
<td colspan="4" class="text-right"><strong>Total:</strong></td>
<td class="text-right">£450.00</td>
</tr>
</tfoot>

for each table push to array

I'm a beginner with code,
I'm trying to run on this table and get the text from each .winner class and push it to an Array, so instead of getting:
["aa","aa","dd"]
I'm getting
["aaaadd","aaaadd","aaaadd"]
$(document).ready(function(){
var arr = [];
var winner = $('.winner').text() ;
for ( i = 0; i < $('table').length ; i++ ) {
arr.push(winner);
}
console.log(arr);
});
HTML:
<table>
<tr>
<td>#</td>
<td class="winner">aa</td>
<td>bb</td>
<td>cc</td>
<td>dd</td>
</tr>
</table>
<table>
<tr>
<td>#</td>
<td class="winner">aa</td>
<td>bb</td>
<td>cc</td>
<td>dd</td>
</tr>
</table>
<table>
<tr>
<td>#</td>
<td class="winner">dd</td>
<td>cc</td>
<td>bb</td>
<td>aa</td>
</tr>
</table>
I guess something is wrong with my for loop
var arr = [];
$('table .winner').each(function () {
arr.push($(this).text());
})
Example
or version without class .winner
$('table').each(function () {
arr.push($(this).find('tr').eq(0).find('td').eq(1).text());
});
Example
$('table .winner') - returns 3 td's with class .winner
$(this).text() - get text from current element.
In your example $('.winner').text() returns text "aaaadd", then you get $('table').length (will be 3) and three times push the same text to arr
The sentence
var winner = $('.winner')
will give you an array of objects, so you need to loop each of them and call text() method for each one.
With this:
var winner = $('.winner').text();
You are getting a combined texts from all the td elements marked as winner (see docs here).
Then, for each table, to push this value to the array:
for ( i = 0; i < $('table').length ; i++ ) {
arr.push(winner);
}
This is actually not necessary.
What you want is probably:
var winners = $('.winner');
for (var i = 0; i < winners.length(); ++i) {
arr.push(winners.eq(i).text());
}

Add tags to enclose existing table

Here I have an existing table:
<table>
<tr>
<td>content
</td>
</tr>
</table>
and in JavaScript, I have already obtained this table:
var isert = main_code.getElementsByTagName("table");
How to use JavaScript to attach tags to this table so it looks like:
<div id=extra>
<table>
<tr>
<td>content
</td>
</tr>
</table>
</div>
PS: It seems that insertAdjacentHTML only works on current <table>tag, not entire <table></table>.
Thank!
Try this:
var tables = main_code.getElementsByTagName("table");
for(var i = 0; i < tables.length; i++) {
var div = document.createElement("div");
var _t = tables[i];
var parent = _t.parentNode;
div.id = "extra";
parent.replaceChild(div, _t);
div.appendChild(_t);
}
Although, this adds the same id to multiple div container, if there are more than one table. You might want to use div.className = 'extra' instead.

Nested tag name with getElementsByTagName doesn't work

I have the following div that contains the table and its data queried from database
<div id="content">
<table>
<tbody>
<tr>
<th class="header" colspan="2">Food items include:</th>
</tr>
<tr>
<td id="15" class="fruits">Papaya+salt</td>
<td><p>This includes papaya and salt</p></td>
</tr>
<tr>
<td class="meat">Baked chicken</td>
<td><p>This includes a chicken thide and kethup</p></td>
</tr>
<tr>
<td id="1" class="Juices">Strawberry Sting</td>
<td><p>Sugar, color and water</p></td>
</tr>
<table>
</div>
That table is defined in a page.aspx
and here is my code used to sort that table data alphabetically
OldFunc = window.onload;
window.onload = OnLoad;
function OnLoad(){
try{
var pathName = window.location.pathname.toLowerCase();
if( pathName=="/Resources/Glossary.aspx") {
sort_it();
}
OldFunc();
}
catch(e) {
}
}
function TermDefinition(def_term,def_desc)
{
this.def_term=def_term;
this.def_desc=def_desc;
}
function sort_it()
{
var gloss_list=document.getElementsByTagName('td');
var desc_list=document.getElementsByTagName('td p');
var gloss_defs=[];
var list_length=gloss_list.length;
for(var i=0;i<list_length;i++)
{
gloss_defs[i]=new TermDefinition(gloss_list[i].firstChild.nodeValue,desc_list[i].firstChild.nodeValue);
}
gloss_defs.sort(function(a, b){
var termA=a.def_term.toLocaleUpperCase();
var termB=b.def_term.toLocaleUpperCase();
if (termA < termB)
return -1;
if (termA > termB)
return 1;
return 0;
})
for(var i=0;i<gloss_defs.length;i++)
{
gloss_list[i].firstChild.nodeValue=gloss_defs[i].def_term;
desc_list[i].firstChild.nodeValue=gloss_defs[i].def_desc;
}
}
Please lookat the the two getElementsByTagName, I think I am misuse its content since nothing is done on the output.
Invalid:
desc_list=document.getElementsByTagName('td p');
You can't pass a css selector to that function, only a tag name like div\ span input etc'.
You might want to use:
desc_list = $('td p');
Since you tagged the question with jQuery, or document.querySelectorAll for vanilla js:
desc_list = document.querySelectorAll('td p');

Sorting function in javascript

Hi I have html structure with table. I want to sort td according to their value. I trying it but cant find the logic to make it happen. My function is
<head>
<script type="text/javascript">
function sorting(){
var sortvalue= document.getElementsByTagName('td');
for(i=0; i<sortvalue.length;i++){
var val= sortvalue[i].value
}
}
</script>
</head>
<body>
<table width="500" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>5</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
</table>
click to sort
</body>
If you plan to do more than just organize those numbers: those saying you should use a plugin are correct. It'd take more effort than it's worth to try to make your own table sorter.
If all you want to do is sort those numbers (small to large):
function sorting() {
td = document.getElementsByTagName("td");
sorted = [];
for (x = 0; x < td.length; x++)
sorted[x] = Number(td[x].innerHTML);
sorted.sort();
for (x = 0; x < sorted.length; x++)
td[x].innerHTML = sorted[x];
}
Largest to smallest:
function sorting() {
td = document.getElementsByTagName("td");
sorted = [];
for (x = 0; x < td.length; x++)
sorted[x] = Number(td[x].innerHTML);
sorted.sort().reverse();
for (x = 0; x < sorted.length; x++)
td[x].innerHTML = sorted[x];
}
Assuming that you're putting the script under your link, or adding it on domready:
function sorting(){
var tbl = document.getElementsByTagName('table')[0];
var store = [];
for(var i=0, len=tbl.rows.length;i<len; i++){
var row = tbl.rows[i];
var sortnr = parseFloat(row.cells[0].textContent || row.cells[0].innerText);
if(!isNaN(sortnr)) store.push([sortnr, row]);
}
store.sort(function(x,y){
return x[0] - y[0];
});
for(var i=0, len=store.length; i<len; i++){
tbl.appendChild(store[i][1]);
}
store = null;
}
link here: http://jsfiddle.net/UMjDb/
For your example you can make an array of the cell data from the node list and sort that array, and then replace the cells data with the sorted data. Simpler than moving elements.
<head>
<script type= "text/javascript">
function sorting(){
var T= [], tds= document.getElementsByTagName('td');
for(var i= 0;i<tds.length;i++){
T.push(tds[i].firstChild.data);
}
T.sort(function(a, b){
return a-b
});
for(var i= 0;i<tds.length;i++){
tds[i].replaceChild(document.createTextNode(T[i]), tds[i].firstChild);
}
}
</script>
</head>
<body>
<table width= "500" border= "0" cellspacing= "0" cellpadding= "0">
<tr>
<td>5</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>1</td>
</tr>
</table>
click to sort
</body>
i giving a jquery solution, hope this post helps you.
var tdData = Array();
$(document).ready(function(){
$('td').each(function(i){
tdData [i] = $(this).text();
});
});
function sorting(){
var sortedData = tdData.sort();
$('td').each(function(i){
$(this).text(sortedData[i]);
} );
}
complete solution: link
step 1: find all td's
step 2: fetch their values
step 3: sort them on their values
step 4: put them back into their parent in the correct order. This can simply be done with an $(parent).html("").append(sortedNodes) (if you use jQuery that is).
As #FelixKling points out below, the .html("") is not strictly necessary other than for code clarity since "If you have nodes that already exist in the tree, then .append will remove them first from their current location and add them to the new parent"
You need to re-organise the table.
The simplest approach would be to use a plugin like this one for jQuery
You need to modify the DOM, they would be different way to do that, like grabbing all the data, removing all the rows and adding them back in the right order.
It could be improved better using detach and reattaching.

Categories

Resources