Clone and append previous tr row to current table - javascript

Im having a table with 3 rows, with inputs where you can fill values in.
Now I have a link in the last tr, that says "+ More".
The "+ More" link, should if worked as expected, clone the above tr and append it above the link.
This is how far I am:
http://jsfiddle.net/9s8LH/2/
$(document).ready(function(){
$('.appendRow').bind('click', function(){
var $table = $(this).closest('table');
var $tr = $(this).closest('tr');
var $trAbove = $(this).prev('tr');
$table.append($tr.clone());
});
});
I tried to use prev('tr') to grab the TR element before the one I am inside, but it does not really work.
The second issue is that it appends under the +More TR, and not above it.
How can this be done?

The reason that $(this).prev('tr') doesn't work is that your appendRow class is on the link, not the row. There is no tr immediately prior to the link, prev looks at the previous sibling element (sibling = within the same parent) to see if it matches the selector. It doesn't scan, and it doesn't go up the hierarchy.
You're pretty close though, see comments: Updated Fiddle
$(document).ready(function(){
$('.appendRow').bind('click', function(){
// First get the current row
var $tr = $(this).closest('tr');
// Now the one above it
var $trAbove = $tr.prev('tr');
// Now insert the clone
$trAbove.clone().insertBefore($tr);
});
});
Note the use of insertBefore, which will insert the clone before the current row.

Try to use on() for dynamically added elements and you HTML should be like,
HTML
<table class="extraBookingBox">
<tr><td>Fees</td><td>Amount</td></tr>
<tr>
<td><input type="text" style="width: 40px;" name="cancelfee_price[]" />€</td>
<td><input type="text" style="width: 40px;" name="cancelfee_price[]" />€</td>
</tr>
<tr>
<td colspan="2">+ More</td>
</tr>
</table>
SCRIPT
$(document).ready(function(){
$(document).on('click','.appendRow', function(){
var $tr = $('table tr:nth-child(2)').clone();
console.log($tr);
$tr.insertBefore($('.appendRow').closest('tr'));
});
});
Demo

Related

jQuery find next anchor element inside td

I have HTML that looks like this:
<table>
<tr>
<td>Hello<div class="yo"></div></td>
<td>Bye<div class="yo"></div></td>
</tr>
<tr>
<td>Foo<div class="yo"></div></td>
<td>Bar<div class="yo"></div></td>
</tr>
...
<!-- Rows continue on... -->
The divs have a listener for tab keydown, so whenever a tab is pressed it should go to the next link. (or perhaps it's enough to go to the next td element?)
For instance I click on Hello anchor, then Bye anchor should get focused. If I click on Bye anchor then Foo anchor should get focused.
You can get the index of the clicked link and call .focus() on the next element in the array:
var $links = $('table a');
$links.on('click', function() {
$links.eq($links.index(this)+1).focus();
});
https://jsfiddle.net/qcbozbyn/1/
How about working with jquery Next() and prev() methods
$("table tr td a").click(function(){
var me = $(this) ;
var nextElm = me.closest("td").next();
if(nextElm.length>0){
nextElm.find("a").css("color","green");
}
else{
var prevElm = me.closest("td").prev();
if(prevElm.length>0){
prevElm.find("a").css("color","red");
}
}
});
JSfiddle link: https://jsfiddle.net/7fw2oeLm/

Remove first TD of a TR Table in javascript

I am trying to remove a td at runtime using Javascript only (no JQuery intended). Here is my table :
<table id = "tab">
<tr>
<td>
test 1
</td>
<td>
test 2
</td>
<td>
test 3
</td>
</tr>
</table>
Here is what I tryied :
function removeFirstTD() {
var element = document.getElementById("tab");
element.removeChild(element.firstChild);
}
Note that this function works and I execute it by doing this :
<body onload = "removeFirstTD();">
<!-- the tab is here -->
</body>
The problem is that it seems to erase the <tr> because I didn't scope the tr before requesting remove the td. May someone help me doing this please ?
Maybe the simplest way is to use HTMLTableElement Interface:
function removeFirstTD() {
var element = document.getElementById("tab");
element.rows[0].deleteCell(0);
}
A live demo at jsFiddle.
Use can also use querySelector. It picks the first element that matches it like this;
function removeFirstTD() {
var element = document.querySelector("#tab tr td");
element.remove();
}
Go down one more level?
element.firstChild.removeChild(element.firstChild);
Due to white space (between the table and tr, and tr and td) this creates TEXTNODES which will be the first children, you would have to be more specific:
function removeFirstTD() {
var element = document.getElementById('tab');
var firstRow = element.getElementsByTagName('TR')[0];
var firstColumn = firstRow.getElementsByTagName('TD')[0];
firstColumn.remove();
}
But you might find this simpler and more reliable:
function removeFirstTD() {
document.querySelector('#tab tr td').remove();
}
You're close. td elements belong to the tr elements (and technically the tr elements should belong to a tbody element, not the table directly). You need to get the tr elements then find their first children.
function removeFirstTD() {
var element = document.getElementById("tab");
var tr = element.getElementsByTagName('tr');
var j = tr.length;
while (j--){
tr[j].removeChild(tr[j].firstChild);
}
}
Note that firstChild might be whitespace or some other entity that is no the first td element, and you should add a check for that before removing that child.
<table class="u-full-width">
<thead>
<tr>
<strong><td>Joke</td></strong>
</tr>
</thead>
<tbody>
<tr>
<td>This is a joke</td>
</tr>
</tbody>
</table>
I'm adding this to give a step by step procedure for beginners like me looking for this answer.
Let's say above is how our table looks
First, get a DOM reference to the table body let tbody = document.querySelector('u-full-width').getElementsByTagName('tbody')
The above statements return a HTML Collection. So, we take the zero index of that collections tbody = tbody[0]
tbody.removeChild(tbody.firstElementChild) firstElementChildignores text and comment nodes

On Click add Class to First <td> in Row and corresponding <th> in Table

I have a table which has clickable <td>'s.
When I click a Cell in the table I want to add a class to
The first <td> in the row I clicked on
The <th> which corresponds to the column that the row is in
Essentially I am trying to show which <td> is clicked on visually.
I can figure out how to add a class to the first <td> in the row but it adds them to it all and not just the one I am in. I cannot figure out how to add it to the <th>
Looking for some advice on how to do this in Jquery. My incomplete code is:
//Adding Class Needed
$('.table-bordered tr td').on('click',function(){
//Add Class to First TD in ROW
$("tr td:nth-child(1)").addClass('superStyle');
//Add Class to Header <th> Cell above
});
DEMO http://jsfiddle.net/L8s5X/
Try
$(function(){
//Hover and click colors
var table = $('table').on('click', 'td', function(){
$('.table-bordered tr td').removeClass('active');
$(this).addClass('active');
});
//Adding Class Needed
$(table).find('tr td').on('click',function(){
//Add Class to First TD in ROW
table.find('.superStyle').removeClass('superStyle');
$(this).closest('tr').find("td:nth-child(1)").addClass('superStyle');
//Add Class to Header <th> Cell above
table.find('thead th').eq($(this).index()).addClass('superStyle')
});
});
Demo: Fiddle
Of course it is, your selector is told to do that.
You need to create the selector within the context of the click
$(this).parent().find('td:nth-child(1)').addClass('superStyle');
Demo:
http://jsfiddle.net/L8s5X/7/
DEMO
$('.table-bordered tr td').on('click', function () {
var $table = $(this).closest('table'),
$tds = $(this).closest('tr').find('td');
$table.find('.superStyle').removeClass('superStyle');
//Add Class to First TD in ROW
$tds.eq(0).addClass('superStyle');
//Add Class to Header <th> Cell above
var index = $tds.index(this);
$table.find('th').eq(index).addClass('superStyle');
});
This solution seems to work as desired:
jsfiddle
// save elements before binding the event handler, to save processing time
var $table = $('table'),
$headings = $table.find('thead th'),
$fields = $table.find('td');
$table.on('click', 'td', function () {
var $this = $(this),
index = $this.index();
$fields.removeClass('active');
$this.parent().children(':first-child').addClass('active');
$headings.removeClass('superStyle').eq(index).addClass('superStyle');
});

Generate a dynamic table in a <td>

function td(id)
{
var td=document.getElementById(id+'');
var table = document.createElement('table');
var tbody=document.createElement('tbody');
var tr = document.createElement('tr');
var tdchild = document.createElement('td');
tdchild.innerHTML="<input type=text name=txt size=2>";
tr.appendChild(tdchild);
tbody.appendChild(tr);
table.appendChild(tbody);
td.appendChild(table);
}
I want to generate a table in side a td on click of a button. Its not happening this way?
Your code looks correct to me, and it seems to work as expected.
Check this fiddle.
Are you sure you are calling the td function with the right ID, and that the ID is in the td element, and not in the table element?
That works for me. Do you have a click listener defined that will run this function? Does a td exist with the specified id?

How to get a cell's location

I'm writing a script which manages a very large table. When a user clicks a table cell, I would like to know which cell they clicked.
e.g
--------------
| | |
| | Click|
--------------
should give me a cell reference of (1, 1).
Any way I could do this with javascript. The page it's running on uses jquery for other purposes, so any jquery based solutions are good aswell.
EDIT: To clarify, the top left cell is (0, 0). For performance reasons, the event needs to bound to the table, not the tds.
This is done very easily using the target property of the event object:
$('#mytable').click(function(e) {
var tr = $(e.target).parent('tr');
var x = $('tr', this).index(tr);
var y = tr.children('td').index($(e.target));
alert(x + ',' + y);
});
This approach allows you to only bind 1 event handler to the entire table and then figure out which table cell was clicked. This is known as event delegation and can be much more efficient in the right situation, and this one fits the bill. Using this you avoid binding an event to each <td>, and it does not require hard-coding coordinates. So, if your table looks like this:
<table id='mytable'>
<tr>
<td>hi</td>
<td>heya</td>
</tr>
<tr>
<td>boo</td>
<td>weee</td>
</tr>
</table>
It will alert the coordinates on click. You can do whatever with that. :)
If you find performance to be too slow (depending on just how large your table is) you would then have to resort to hardcoding or a combination of the two, maybe only hard coding the <tr> index, as that would be the slowest to get, and then getting the <td> index dynamically. Finally, if all this coordinate business is completely unnecessary and what you really just wanted was a reference to the clicked <td>, you would just do this:
$('#mytable').click(function(e) {
var td = $(e.target);
// go crazy
});
$('td').click(function(event) {
var row = $(this).parent('tr');
var horizontal = $(this).siblings().andSelf().index(this);
var vertical = row.siblings().andSelf().index(row);
alert(horizontal+','+vertical);
});
Walk the DOM hierarchy...
You should be able to do this by obtaining a reference to the DOM node for the clicked TD, then walking the previousSibling chain backwards until you reach the first column, counting as you go.
One you're at the start of that sibling chain (i.e., the first TD in the row), the parentNode should be the TR node, and with that you can perform a similar walk through previousSibling TRs to count up the number of rows.
..or tag each cell with additional attributes
Alternatively, when you create the table, add some fake rowidx="??" and colidx="??" attributes to each cell and retrieve these with getAttribute. If you want to use a legal attribute, you could put the row and column index in an axis="??,??" attribute.
You mentioned a very large table - it would be unwise to bind the click to every td. A better approach is to use the .live method, if your still on jquery 1.2.6 you can just bind a click event to the table and use event delegation. if you need code for this ask.
$("#tableId td").live('click', function () {
var $this = $(this);
var x = $this.prevAll().length;
var y = $this.parent().prevAll.length;
console.log(x + ", " + y);
});
assuming your 1st row, 1st column to be 0,0
var row = 0;
$('#tblImages > tbody > tr').each( function(){
var col = 0;
$(this).children('td').each( function(){
$(this).attr("currentRow", row).attr("currentCol", col);
col++;
});
row++;
}
);
$('#tblImages > tbody > tr > td').click(function(){
alert( $(this).attr("currentRow") + " " + $(this).attr("currentCol"));
This can certainly be improved more..but its working
window.onload = function () {
document.getElementsByTagName('table')[0].addEventListener('click', function(element) {
var rowIndex = element.target.parentElement.rowIndex;
var cellIndex = element.target.cellIndex;
document.getElementById('alert').innerHTML = ('Row index = ' + rowIndex + ', Column index = ' + cellIndex);
}, false);
}
tr, th, td {
padding: 0.6rem;
border: 1px solid black
}
table:hover {
cursor: pointer;
}
<table>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</tbody>
</table>
<p id="alert"></p>

Categories

Resources