Using cellindex() to locate a cell that may move - javascript

I'm just getting started learning JavaScript, and I am having some trouble inserting cells into a table. I have a 1-row table of 3 cells and I want to insert a new cell to the left of whichever cell is clicked, but only after when I click on the "Insert" button.
Here is the HTML for the table:
<table border="1" id="table1">
<tr id="row1">
<td id="c1" onclick="c1()">Cell 1</td>
<td id="c2" onclick="c2()">Cell 2</td>
<td id="c3" onclick="c3()">Cell 3</td>
</tr>
</table>
<br>
<button onclick="insert()">Insert</button>
If I manually designate the cell index like I did with Cell 2, it works fine, but if I try to detect the cell's index like I'm doing with Cell 3, it just inserts the new cell at index 0.
JavaScript:
var cell1=false,
cell2=false,
cell3=false,
x;
function c1() {
cell1=true;
}
function c2() {
cell2=true;
}
function c3() {
cell3=true;
x=getElementById("c3").cellIndex;
}
function insert() {
if (cell1==true) {
// Not used yet
}
if (cell2==true) {
document.getElementById("table1").rows[0].insertCell(1).innerHTML="New1";
}
if (cell3==true) {
document.getElementById("table1").rows[0].insertCell(x).innerHTML="New3";
}
cell1=false;
cell2=false;
cell3=false;
};
I've tried a few variants both in the c3() function and in the insert() function, but each time it either didn't insert at all, or it inserts at index 0.
By the way, I'm trying to do this with pure JavaScript.

You need to check your Javascript console for errors, it reports:
Uncaught ReferenceError: getElementById is not defined
Change getElementById in c3() to document.getElementById to fix this.

Related

Use javascript to Transfer Text

I have got 3 tables in html that at a certain time, i want to move text from 1 table will move to another. Can someone show me a javascript function ( just a few lines long - don't spend too long) that can transfer text from one td to another.
Transferring ONE td value to another:
Well if you assign a td an ID (ex. "firstTD", "secondTD"), you could store it's value in a variable (ex. "tdToMove"):
var tdToMove = document.getElementById("firstTD").innerHTML;
document.getElementById("secondTD").innerHTML = tdToMove;
Note: This will only copy the innerHTML of a single td, and duplicate it on the other. If you wish to clear the first entry, run:
document.getElementById("firstTD").innerHTML = "";
to render the first td 'blank'.
You will have to experiment to find a way to move ALL values to the other table, this was just a pointer.
Also, If the text is moving from table to table, and the tables remain identical, why not just place the input in both to begin with, OR, simply run a code to duplicate the table when you would like to move the data?
You can use Node.textContent property to get and set the text of a Node.
Here is a link about it:https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent
I have made a fiddle to show you that in action: https://jsfiddle.net/3dep0msg/
In this fiddle i transfer the text of cell1 to cell2 and add it to the text of cell2.
I use textContent and not innerHTML property, because you wanted to transfer ONLY text!
function copyTextFromCell(id1,id2){
var cell1= document.getElementById(id1);
var cell2= document.getElementById(id2);
cell2.textContent = cell2.textContent+cell1.textContent;
}
copyTextFromCell("cell1","cell2");
if you want to do this using jquery.
<table id="table1">
<tr>
<td>1,1</td>
<td>1,2</td>
</tr>
<tr>
<td>2,1</td>
<td>2,2</td>
</tr>
</table>
<table id="table2">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
$('#table1 tr').each(function (indexR, element) {
$(this).find('td').each(function (index, element) {
var table2Rows = $('#table2 tr');
var table2Row = table2Rows.eq(indexR);
var table2Column = table2Row.find('td');
var table2cell = table2Column.eq(index);
table2cell.html( $(this).html());
});
});
working fiddle.

Get <table> element's nth <td> innerHTML dynamically

Is there anyway I can get the innerHTML of the designated nth <td> in a <table> using JavaSCript?
Since my table is automatically generated, my <td>'s do not have IDs. I am using the following HTML code:
<table id="table">
<tr>
<td onmouseover="myTD()">Cell 1</td>
<td onmouseover="myTD()">Cell 2</td>
<td onmouseover="myTD()">Cell 3</td
</tr>
<tr>
<td onmouseover="myTD()">Cell 4</td>
<td onmouseover="myTD()">Cell 5</td>
<td onmouseover="myTD()">Cell 6</td>
</tr>
</table>
But how do access, for instance, Cell 5?
Thanks a lot!
var cells = document.getElementById('table').getElementsByTagName('td');
This will contain all your table cells. Use array notation to access a specific one:
cells[4]
Here's a quick demo which changes the background color:
http://jsfiddle.net/jackwanders/W7RAu/
Not sure what you want - Dom: document.getElementsByTagName("table")[0].rows[2].cells[1]
Pass the cell back to the function:
<td onmouseover="myTD(this)">Cell 1</td>
Get the innerhtml from the object:
function myTD(obj) {
alert(obj.innerHTML);
}
Can you clarify when (on load, on hovering, ...) and where (client side, server side ...) you want to do that?
If you need the cell inside myTD, just use the this keyword, which happens to be your HTMLTableCell:
function myTD() {
this.style.color="red"; // just for the example, using CSS classes is much better
}
Using just CSS you could do:
#table tr:nth-child(2) td:nth-child(2)
{
background:#ff0000;
}​
jsFiddle example
function addClassToNthTD(n) {
var table = document.getElementById('table');
for (var i = 0; i < table.childNodes.length; i++;) {
var rows = table.childNodes[i];
for (var j = 0; j < tr.childNodes.length; j++;) {
n = n - 1;
if (n == 0) {
tr.childNodes[j].className = 'foo';
}
}
}
}
This line:
$('td')
Places all of the td elements in the code into a zero-based array, so the cell with 'Cell 5' as its content would be the fifth element of that array, ie:
$('td')[4]
jQuery also accepts CSS style selectors, so if you wanted to target the every second cell in a row, you could use a selector such as:
$('tr td:nth-child(2)')
Read through the selector documentation I've linked, it can come in very handy for situations like this
I have no idea what you are trying to do, but if you want to do some kind of "hover" ability, jquery can do that quite simple. i have created an example Fiddle http://jsfiddle.net/fd3GK/1/

How to select value/innerHTML of a certain <td> within a certain <tr>? Using Javascript only. No jQuery

<table>
<tr>
<td>foo1</td>
<td>bar1</td>
<td><input type="button" id="button1" onClick="get(this);"></td>
</tr>
<tr>
<td>foo2</td>
<td>bar2</td>
<td><input type="button" id="button2" onClick="get(this);"></td>
</tr>
</table>
Goal: To get buttons button1 and button2 to trigger the same function get() which should get the value of the first <td> in the same <tr> the button resides in. Which is, in this case: foo1 and foo2 respectively.
This is a rough outline of the function which should help understand what I'm trying to achieve-
function get(element){
alert(element.tr.first_td.innerHTML);
}
I realize there was a jQuery solution to a similar problem. But I do not understand jQuery well enough to translate it back to JavaScript. If it is possible at all using JavaScript, please show me how.
Crawl up the parentNode twice to get to the tableRow element. From there, access the first td from the HTMLCollection of cells, and get the innerHTML value:
function find( element ) {
alert( element.parentNode.parentNode.cells[0].innerHTML );
}​
Fiddle: http://jsfiddle.net/jonathansampson/WuWnw/
Try this, since you have many tr and td tags right, so, you can do DOM Parsing. But you need to specify one ID for the table to get that table. For now lets call it foo-table.
var table = document.getElementById("foo-table");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
alert(cells[i].innerHTML);
}
If you don't wanna give an ID and you are sure that there is only one table, then use this:
var table = document.getElementsByTagName("table");
var cells = table[0].getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
alert(cells[i].innerHTML);
}
Enjoy! Hope this helps! :) No jQuery or any other plugin. Pure JavaScript. :)
<table>
<tr>
<td id="button1_value">foo1</td>
<td>bar1</td>
<td><input type="button" id="button1" onClick="get('button1_value');"></td>
</tr>
<tr>
<td id="button2_value">foo2</td>
<td>bar2</td>
<td><input type="button" id="button2" onClick="get('button2_value');"></td>
</tr>
</table>
You shoul identify what you want to get using an ID so that you can easily retrieve it. This also helps prevent the chance of getting erroneous data. If you give the component an id you should be able to use document.getElementById() to get that component.
function get(element){
var obj = document.getElementById(element)
alert(obj.innerHTML);
}

Getting inner tag element inside an "each"

I've been messing around with different forms and tables, now I need something that takes data from table tr and td field, runs a if statement on each fetched item, and outputs text inside the form, depending what was found in td fields.
So right now I have something like this, which doesn't do anything useful at all, for now, just outputs td-01 class values into the form:
var test;
$('tbody tr').each(function(index) {
test = $(this+'.td.td-0');
$('fieldset.csc-mailform').after($('td.td-0'));
});
and my table structure looks something like this:
<table class="contenttable contenttable-3 tabel">
<tr class="tr-even tr-0">
<td class="td-0">01</td>
<td class="td-1">Valik 1</td>
<td class="td-last td-2">150€</td>
</tr>
<tr class="tr-odd tr-1">
<td class="td-0">01</td>
<td class="td-1">Valik 2</td>
<td class="td-last td-2">50€</td>
</tr>
<tr class="tr-even tr-2">
<td class="td-0">01</td>
<td class="td-1">Valik 3</td>
<td class="td-last td-2">170€</td>
</tr>
<tr class="tr-odd tr-3">
<td class="td-0">01</td>
<td class="td-1">Valik 4</td>
<td class="td-last td-2">88€</td>
</tr>
</table>
Right now it only find tr tags and outputs all of them. I need it to split the tr tag up, run if condition on td-0 to determine if it needs to be radio button/text input/checkbox etc, then see what td-1 contains and make that field name, then td-2 is for example a price. all of this should end up in a form.
So as you can see, I am stuck with jQuery, but I think it should be doable.
edit:
I got something like this after messing around a little, but my if statements don't seem to work on jQuery objects, any way to get around this?
var check1;
$('tbody tr').each(function(index) {
//test = $(this+'.td.td-0');
check1 = $('td.td-0');
alert(check1);
if(check1=='01'){
content_type="checkbox";
}else if(check1=='02'){
content_type="text";
}else{
content_type="none";
}
$('fieldset.csc-mailform').after(content_type);
//$('fieldset.csc-mailform').after($('td.td-0'));
});
//edit2
Ugh, I was running if statement against jQuery object, of course it didn't work.
I got it working with this, looks quite nasty, but it seems to work:
$('tr').each(function () { var val = $(this).children('td:first').text();
//$check1 = $('td.td-0');
if(val=='01'){
content_type="checkbox";
}else if(val=='02'){
content_type="text";
}else{
content_type="none";
}
$('fieldset.csc-mailform').after(content_type + '<br/>');
}
);
Now, I need to figure out how to create input fields from these.
You could possibly make it a bit cleaner by using the jQuery selector context, e.g.:
$('tr').each(function () {
var val = $('td:first', this).text();
..
}
Something like this will do:
$('table tr').each(function() {
$tds = $(this).children();
for(var i=0;i<$tds.length;i++){
$td = $tds[i];
if($td.hasClass('td-0'){
//do your thing by getting next TD or something else
break;
}
}
});

Optimizing Jquery iteration through table columns comparing with existing row

I'm trying to write a function to add color to a table based on a reference which is one of the top rows of the table. There are several questions in SO mentioning row based iteration but not so much about column.
The structure of the table is something like:
<table id="data">
<tr>
<th rowspan="2">Name</th>
<th rowspan="2">Selection</th>
<th rowspan="2">Title</th>
<th rowspan="2">Info1</th>
<th rowspan="2">Info2</th>
<th colspan="10">Data</th>
</tr>
<tr>
<th>001</th>
<th>002</th>
<th>003</th>
<th>004</th>
<th>005</th>
<th>006</th>
<th>007</th>
<th>008</th>
<th>009</th>
<th>010</th>
</tr>
<tr id="ref_control">
<td></td>
<td>RefName</td>
<td></td>
<td></td>
<td></td>
<td>A</td>
<td>B</td>
<td>J</td>
<td>L</td>
<td>Z</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td><input type="checkbox" name="checkbox"/></td>
<td>Entity 1</td>
<td>Info...</td>
<td>More info...</td>
<td>Even more...</td>
<td>A</td>
<td>T</td>
<td>M</td>
<td>L</td>
<td>Z</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>2</td>
<td>5</td>
</tr>
(...)
</table>
In addition I'm using JQuery and the JQuery column cell select plugin to perform the mentioned task.
The Javascript code looks like this:
$(document).ready(function() {
// Colorize table based on matches
// Number of Data entries - Count on the reference (2nd row)
// and only 5th column onwards (index starts at 0)
var datasize = $("#data tr:eq(2) td:gt(4)").length;
// Start with column 6 (index starts at 1)
var begin = 6;
for (var i = begin; i < begin + datasize; ++i) {
var curCol = $("#data td").nthCol(i);
var ref = curCol.eq(0).text();
curCol.not(curCol.eq(0)).each(function() {
var data = $(this);
if (data.text() == '') {
data.addClass("black");
} else if (data.text() != ref) {
data.addClass("color");
}
});
}
});
A working example can be visualized here. In the example the table has only 9 rows and 10 data columns. The actual page I'm trying to optimize has 20 rows and 90 data columns.
Using the mentioned Javascript extensions/plugins the big sized table poses no threat to the Google Chrome browser taking a few seconds to load, however Opera, Firefox and Internet Explorer have a hard time running the function or end up asking for user interaction to stop the script from running.
So my question is aimed at both alternatives to the column select plugin or ways to optimize the code such that I don't kill almost all browsers except Google Chrome.
Edit: Changes according the the two comments from #Pointy
You can easily get 10x faster code if you want. Just save references once and go row by row instead of column by column. It doesn't become more complicated yet it performs much better. The reason is that your plug-in hides the abstraction that your table is made of rows that are made of columns. And not the other way around. Emulating the second version can be costy as you noticed in this example.
You may also use DOM properties instead of jQuery methods. They are really straightforward.
// get text (modern browsers || IE <= 8)
var text = elem.textContent || elem.innerText;
// set class
elem.className = "black";
your final code will be something like:
var refcells = $("#data tr:eq(2) td:gt(4)");
var datasize = refcells.length;
// Start with column 5
var begin = 5;
var refs = [];
var i = begin;
refcells.each(function () {
refs[i++] = $(this).text();
});
$("#data tr:gt(2)").each(function () {
var cells = $("td", this);
for (var i = begin; i < begin + datasize; i++) {
var elem = cells[i];
var text = elem.textContent || elem.innerText;
if (!text) {
elem.className = "black";
} else if (text != refs[i]) {
elem.className = "color";
}
}
});
Doing what you're doing is going to be very computationally intensive. Since your table layout seems pretty regular, I'd just completely ditch that nthCol() thing (for this page anyway) and do your work by iterating over the table once:
Grab the "key" row first, and save it
Loop through each relevant <tr>, and for each one get the <td> elements and iterate over them as a raw node list, or as a jQuery list. Either way it should be a lot faster.
In the second loop, you'll do the same logic you've got (although I'd use addClass() and removeClass()), referring back to the saved "key" row for each cell.
In your current loop, you're re-building the jQuery object of every <td> in the table for each column, and then you're doing that nthCol() work! That's a lot of work to do if you do it once, so repeating that for every single column is going to really drag that CPU down. (On IE6 - especially with all those "class" changes - I bet it's almost unbearably slow.)
edit — I looked over that code (for the plugin), and while it looks like it was competently implemented it doesn't have any "magic tricks". All it does is iterate through all the table cells you give it and checks whether or not each cell is in fact in the "nth" column. Thus, your iteration will perform that test on every cell in the table for every column you care about. In your 90x20 table, that'd be about 85 iterations through all 1800 cells. And that's before you do your work!

Categories

Resources