remove parent container - javascript

I have a form with the fields inside table cells. On the last column of each line I have an image. When clicking that image I want to delete the parent <tr>. Before I tried to do it by generating a function passing as the argument the line number: onclick='delete_row(x, y)'. This is obviously not a good solution since I was deleting the row by its position. The function I'm calling has other 2 arguments since it deletes the row in the database too, so the second argument is the id in the database to delete. So basically I need a function that deletes the parent <tr> and that accept some other arguments too.
EDIT Thanks:
Thank you all guys, I tried almost all the solutions and all worked nice. I just decided for the Mike's Samuel one, it seemed the easiest :) Thanks again

To pass the grandparent of the current node use this.parentNode.parentNode:
<tr><td><img onclick="delete_row(this.parentNode.parentNode, ...)"></td></tr>

How about removing the closest <tr>? You would need to make accommodations for the selectors that are present in your code, but the general form looks like this:
$('img').click(function(){
$(this).closest('tr').remove();
});

You could easily use the HTML node method .removeChild() and traverse through the node's .parentNodes: (demo):
<td onclick="this.parentNode.parentNode.removeChild(this.parentNode);">
Remove row
</td>
this.parentNode.parentNode will be the <table> or <tbody>, while this.parentNode is the parent container <tr>.
Update: rjz provided a neat function (demonstration):
window.removeClosestRow = function(node) {
while(node = node.parentNode) {
if (node.tagName.toUpperCase() == 'TR') {
node.parentNode.removeChild(node);
break;
}
}
}

try something like
onClick='MyDeleteFunc(this, var2, var3)';
that will pass the actual object you're clicking on to javascript, and you can get pretty much all your references from there.

Related

Edit HTML Table Data cell using Jquery

I have an HTML table, and each cell of the table will have two data attributes. What I'm trying to do is set a button to switch the value being shown in the table between those two attributes.
<table class="table1">
<tbody>
<tr>
<td data-original="A" data-new="B"> A </td>
</tr>
</tbody>
</table>
I'm able to set new text and get attributes outside the table, but whenever I try to within the table I keep receiving an error:
'Uncaught -> TypeError: undefined is not a function'.
I've been receiving this error for a number of commands $('td').text(), .val(), .attr('td'), .getAttribute().
Am I missing a plugin or something for getting and setting values from tables?
ANSWER: I figured out the reason, I was an idiot and didn't mention that there would be numerous TD elements with repeating tags. I eventually used Underscore.js's each method to iterate through them and parts of the below answer to swap the values.
Just made a Fiddle:
$("button").on("click", function () {
$("td").text($.trim($("td").text()) == $("td").data("original")
? $("td").data("new") : $("td").data("original"));
});
to switch between the data-original and data-new values by checking the current text in the td and using a ternary operator.
By using trim() for the initial text issues in case of whitespace are taken care of (as I just noticed that you have whitespace in your example td).
Just in case the button isn't already in the DOM when the page is initially loaded, you have to adjust the on() to delegate the click event from a static parent element to the button, e.g. like this: $(document).on("click", "button", function () { ...
Instead of $(document) every other static parent element can be used.
And as you mentioned that the table will have multiple tds with data-attributes, I've just adjusted the Fiddle to take care of that:
$("button").on("click", function () {
$("td").each(function () {
$(this).text($.trim($(this).text()) == $(this).data("original") ?
$(this).data("new") : $(this).data("original"));
});
});
I don't know how .text() didn't work for you.
To set text inside td elements, you use .text(). To get the data inside data-current or data-new, jQuery has a handy function .data(tag), for example $(sel).data('current').
Here's a fiddle displaying usage of this on your problem.

How do you hide the first element in the first table?

I know that to hide the first element in a table is simply do (':first-child') but is there a way to specify that only the first element of the first TABLE needs to be removed?
In my situation the first element of every table is being hidden and I need to fix this.
I suppose you just target the first table, and then the first element, whatever that is ?
document.querySelector('table tr').style.display = 'none';
FIDDLE
as querySelector gets the first matching element, or in jQuery
$('table:first tr:first').hide()
FIDDLE
target the first table and the first td.
$('table:first td:first').hide()
DEMO
You can get a collection of all tables using document.getElementsByTagName("table"). Element zero of that collection ([0]) is the first table. You can then apply your first-child solution to element zero.
This does not require jQuery, nor that you assign an ID attribute to a specific table. (Assigning an ID attribute is probably more efficient if you know in advance which table is going to be first.)
Edited to add: I've tested this and it works, although it is revised from my first "it works" post. The first child element of TABLE is TBODY for a table that starts with a tr element, so what is really wanted is the first child of TBODY. It is probably better to descend the firstElementChild tree looking exspressly for a nodeName of "TR" and hide that. Look further down in this post for that approach.
Here is the simple code that works:
document.getElementsByTagName("table")[0].firstElementChild.firstElementChild.style.display = "none";
This is pure JavaScript, with no need for jQuery. Note that document.getElementsByTagName returns a live collection, so even if a table is added to the DOM, this will get the first one.
Do remember that the first element child of <table> (and then TBODY) is not necessarily <tr>. If you can be sure it is, or if you want the first element regardless, then what I've given will work for you. If you want to be sure it's a <tr> then a little more work will be needed.
This code finds and hides the first <tr> but will be less efficient because it gets two HTML collections:
document.getElementsByTagName("table")[0].getElementsByTagName("tr")[0].style.display = "none";
const tables = document.getElementsByTagName("table")
const firstTable = tables[0];
const firstRow = firstTable.rows[0];
firstRow.style.visibility = "hidden"; //hide
firstRow.style.visibility = "visible"; //visible
Here is a referrence.

jquery - get the position number of clicked td in a table

<table>
<tr>
<td>me</td>
<td>you</td>
<td>we</td>
</tr>
</table>
Using Jquery i want to know which childrin was clicked and get the number of this childrin. like, if I click you, i want to get 2 and if we, then 3.. if me, then 1.
is there something like .nthchild(); in Jquery?
here is my fiddle to test: http://jsfiddle.net/vfp9x/
Simply use $(this).index(), you also have wrong id for table in live demo, it should be table1
Remember the index is zero based so you will get zero 0 for first element and 1 for second element and so on.
Live Demo
$('#table1').on('click', 'td', function () {
$('#out').text($(this).index()+1);
});
.index()
If no argument is passed to the .index() method, the return value is
an integer indicating the position of the first element within the
jQuery object relative to its sibling elements.
Try,
$('#table1').on('click','td',function(){
var child_number = $(this).closest('tr').find('td').index(this);
$('#out').text(child_number);
});
DEMO
Simply use .index() as per the other answer provider suggested, and also keep this way of getting the index also. it would helpful for you in some other contexts, like getting the index of the current element from a collection of elements (not siblings to each other)
Try Like
$("#ul").on('click', 'td', function () {
debugger;
alert(this.id);
});
Demo

jquery select multiple while traversing DOM

I am trying to select all elements with the "findme" class, and from those get the selects that are nearby them.
http://jsfiddle.net/R93md/1/
Specifically I have tried
$(".findme").parent().prev().first();
then once I have all selects I plan on doing a
.each(function (){doSomething(this);})
to each select. I am stuck getting the selects because it seems that I am never going down and retrieving the contents of the span.
$(".findme").closest("td").find("select").each(function() {
doSomething(this);
});
I think you should follow this:
$('.findme').each(function(){
var el = $(this).closest('td').find('select');
dosomething(el);
});
I would first grab the parent <td> element and then use find() like so
$('.findme').parents('td').find('select').each(function(){
...
});
http://jsfiddle.net/JYGK3/
Edit:
In review of the other answers here, I've concluded that you probably should use closest() rather than parents(). If the table is nested, it could produce unwanted results.
http://jsfiddle.net/JYGK3/1
You can use .closest() to go up to the common <td> and then .find() to go down from there to find the neighboring <select>:
$(".findme").each(function() {
var select = $(this).closest("td").find("select");
// now do what you want to with the neighboring select object
// here you have access to both this which is the findme object
// and select which is the select object
});

Is there a jQuery selector/method to find a specific parent element n levels up?

Consider the following HTML. If I have a JSON reference to the <button> element, how can I get a reference to the outer <tr> element in both cases
<table id="my-table">
<tr>
<td>
<button>Foo</button>
</td>
<td>
<div>
<button>Bar</button>
</div>
</td>
</tr>
</table>
<script type="text/js">
$('#table button').click(function(){
//$(this).parent().parent() will work for the first row
//$(this).parent().parent().parent() will work for the second row
//is there a selector or some magic json one liner that will climb
//the DOM tree until it hits a TR, or do I have to code this myself
//each time?
//$(this).????
});
</script>
I know I could special case each condition, but I'm more interested "however deep you happen to be, climb the tree until you find element X" style solution. Something like this, but more jQuery like/less-verbose
var climb = function(node, str_rule){
if($(node).is(str_rule)){
return node;
}
else if($(node).is('body')){
return false;
}
else{
return climb(node.parentNode, str_rule);
}
};
I know about the parent(expr) method, but from what I've seen is allows you filter parents one level up and NOT climb the tree until you find expr (I'd love code example proving me wrong)
The parents function does what you want:
$(this).parents("tr:first");
Also, if you are using jQuery 1.3+ you can use the closest method
$(this).closest("tr");
not jQuery but this options works much better
node.contains( otherNode )
The Node.contains() method returns a Boolean value indicating whether
a node is a descendant of a given node or not
https://developer.mozilla.org/en/docs/Web/API/Node/contains

Categories