Delete the parent row not the child row in jQuery - javascript

This is the result of a datatable on a specific screen size. If all the columns are displayed, there is no problem deleting the row using
$(this).closest('tr').remove();
But when screen size became smaller, this will be the result. I cannot use the above code anymore. Now if I hit the button with the class deleteRow, I want to delete the tr with the class parent and its child (though the child row is not inside the parent row), not just the closest row. There could be many rows that have class parent so I just want to delete the row associates to the childs' row.

I want to delete the tr with the class parent, not just the closest row.
Then include that extra info .parent in the selector like so:
$(this).closest('tr.parent').remove();

Try
$(this).closest('tr.child')

You can have a look at the samples I've put together here, I've tried to split into many cases that you can reference and re-apply to your project.
Let me know which's suitable for you and I can explain it clearer.
$(document).ready(function() {
$('.delete-single-parent').each(function(index) {
var $this = $(this);
$this.click(function() {
// $(this) = the element button clicked
// Try row 1,3,5
$(this).closest('tr.parent').remove();
// Try row 2,4,6. Assuming "parent" is always a sibling of current `child`
$(this).closest('tr.child').prev().remove();
})
});
// This queries to the top (table), and find all parent rows to remove
// Will remove row 1,3,5 only
$('.delete-all-parents').click(function() {
$(this)
.closest('table')
.find('tr.parent')
.remove();
})
})
table {
border: 1px solid grey;
}
table tr:nth-child(odd) {
background-color: #f3f3f3;
}
table tr td {
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="parent">
<td>
<div>1</div>
<button class="delete-single-parent">Delete Direct parent</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="child">
<td>
<div>2</div>
<button class="delete-single-parent">Delete Parent (row 1)</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="parent">
<td>
<div>3</div>
<button class="delete-single-parent">Delete Direct parent</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="child">
<td>
<div>4</div>
<button class="delete-single-parent">Delete Parent (row 3)</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="parent">
<td>
<div>5</div>
<button class="delete-single-parent">Delete Direct parent</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
<tr class="child">
<td>
<div>6</div>
<button class="delete-single-parent">Delete Parent (row 5)</button>
<button class="delete-all-parents">Delete row 1,3,5</button>
</td>
</tr>
</table>

Just fixed my own issue. I added attribute to the parent row upon page loading.
<tr data_id = {{ $item->id }}>
this will make the tr unique so that I can call this later to delete the parent as well as the child row.
to delete the child where the button is placed
$(this).closest('tr.child').remove();
and added code to delete the parent row through attribute as selector.
$('[data_id="'+ row_id +'"]').remove();
so upon ajax success, I will call these two.
$tr.find('td').fadeOut(1000,function(){
$(this).closest('tr.child').remove();
$('[data_id="'+ row_id +'"]').remove();
});

Related

How to use same function on same element multiple times

I am using a button in a table and my button is a single element but on top, I am changing the row of the table based on some condition, so when my final table created is I see button in all rows, which is fine and as per the requirement.
Now I need to use a function on button click which I want to perform the same action in each row to remove the row where the button is placed. when I am using a single function it's working only for first time and not after that, how can I use the same function for all buttons?
here is my code:
function AddValueinrow() {
if(anotherTeamname=='DEV'){
if(selectedValue=="dummy value1"){
row = document.getElementById("DEVFirstrow");
}
if(selectedValue=="dummy value2"){
row = document.getElementById("DEVSecondrow");
}
var w = row.insertCell(6);
w.innerHTML = '<button onclick="Releaseentry()" type="button" id="show" class="btn btn-primary">Release</button>';
}
function Releaseentry() {
if(anotherTeamname=='DEV'){
if(selectedValue=="dummy value1"){
$('#DEVmyTable > tr').eq(0).children('td').remove();
}
if(selectedValue=="dummy value 2"){
$('#DEVmyTable > tr').eq(1).children('td').remove();
}
}
}
Find the parent row by using .closest(), and remove it.
Note: Instead of using inline onclick calls, use event delegation to attach a single event handler to the container, and react to button clicks.
$('#table').on('click', 'button', function() {
$(this)
.closest('tr')
.children('td:not(:last-child)')
.remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table">
<tbody>
<tr>
<td>td11</td><td>td12</td>
<td>
<button type="button" class="btn btn-primary">Release</button>
</td>
</tr>
<tr>
<td>td21</td><td>td22</td>
<td>
<button type="button" class="btn btn-primary">Release</button>
</td>
</tr>
<tr>
<td>td31</td><td>td32</td>
<td class="button">
<button type="button" class="btn btn-primary">Release</button>
</td>
</tr>
</tbody>
</table>

How to apply CSS to children of TR based on TD content?

I'd like to hide a <div> or <td> inside the <tr> based on the content inside that <tr>.
If Stackoverflow is found inside a <tr>, hide .buttons from that <tr>.
This is what I've got so far.
<table class="sites">
<tbody>
<tr>
<td>
<div class="name">Stackoverflow</div>
</td>
<td>
<div class="buttons">
buttons
</div>
</td>
</tr>
<tr>
<td>
<class name="">Stackexchange</class>
</td>
<td>
<div class="buttons">
buttons
</div>
</td>
</tr>
</tbody>
</table>
var t = $(".sites tr .name:contains('Stackoverflow')");
var d = t.parent('tr').children('.buttons');
d.css( "display", "none" );
I've made a fiddle: https://jsfiddle.net/3jk8e3b2/3/
Your traverses are not going to appropriate levels.
parent() is only immediate parent element, children() are only immediate child nodes
In your case parent of .name is a <td> not <tr> and the buttons are not immediate children of <tr> either.
Use closest() or parents() to allow going up more than one level. Use find() to allow going deeper than children()
Try:
var t = $(".sites tr .name:contains('Stackoverflow')");
t.closest('tr').find('.buttons').hide();
DEMO

jQuery select all children of closest

I want to add the .red-border class to a #container div and all <td>s in the closest <tr>.
But by using .closest() I only get the elements immediate parent <td>.
Is there a way I can target all children of the closest <tr>?
My code is below.
My current erroneous JS:
$('#myelement').closest('.container, tr td').addClass('red-border');
Obviously, this only targets 1 td. I want to encompass all of them.
My HTML:
<div id="container">
<span class="myelement">element</span>
</div>
<table>
<tr>
<td></td>
<td><span class="myelement">element</span></td>
<td></td>
</tr>
</table>
Edit: normally I might use the .find() function but this wouldnt work with the or operator.
I hope this is what you are expecting. You need to iterate through each tr and add red-border class to its first td with td:first selector as below
$(document).ready(function() {
$('#container').addClass('red-border');
$('tr').each(function(){
$(this).find('td:first').addClass('red-border');
})
})
.red-border{
border:red 2px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<span class="myelement">element</span>
</div>
<table>
<tr>
<td>First row First TD</td>
<td><span class="myelement">element</span>
</td>
<td></td>
</tr>
<tr>
<td>Second row First TD</td>
<td><span class="myelement">element</span>
</td>
<td></td>
</tr>
</table>
According to your structure you can go for this:
$(".myelement").parents("#container").addClass('red-border').siblings("table").find("tr").eq(0).children().addClass('red-border');
target the parent #container using parents(). This will give nothing for the span inside td. Then target its sibling table and the first tr by using eq(0).
why do you want it in a single line? just split it to two, it will be simpler.
$('.myelement').closest('#container').addClass('red-border');
$('.myelement').closest('tr').find('td').addClass('red-border');
by the way, you called #myelement when your tag had a class myelement. It should be called using .myelement. And the container is an id so #container
Call class element using .myelement instead of #myelement
$('.myelement').closest('.container, tr td').css({"color": "red", "border": "2px solid red"});
or
$('.myelement').closest('.container, tr td').addClass('red-border');

How to add table rows when button clicked: jquery

I have a template which contains two add buttons and two tables. When user clicks add button rows should append to the respective table.
Example:
<div class="reports">
<div class="panel">
<table class="A">
<thead>
<td>A</td>
<td>B</td>
<td>C</td>
</thead>
<tbody></tbody>
</table>
</div>
<button class="add" type="button">Add</button>
</div>
Am using same code for creating table and add button with different ids report.js is
$('.reports').on('click','.add',function(){
//do something
});
I want rows to be appended to the respective table.
Use append()
$('.reports').on('click','.add',function(){
$(this).closest('.reports').find('table').append('<tr/>');
});
Assuming you have different ids at parent divs
$('.reports').on('click','.add',function(){
$(this) //button that was clicked
.parent() //div around the button
.siblings(".A") //sibling element that has the table
.find("table tbody") //the table
.append(tableRow);
The vanilla Js approach:
var button = document.getElementsByClassName('add');
var table = document.getElementsByClassName('A');
button.addEventListener('click', function(){
var tr = document.createElement('tr');
table.appendChild(tr);
});

What are HTML DOM #text elements?

I'm learning knockout.js and trying to use an afterRender callback to apply behaviour to elements.
I don't understand what these #text elements are that show up in my console.log().
So UI looks like this:
Knockout binding like this:
<div id='categoriesTree' style="color:black">
<table class='categoriesEditor'>
<tbody data-bind="template: { name: 'itemTmpl', foreach:children, afterRender: myPostProcessingLogic2 }"></tbody>
</table>
</div>
Template:
<script id="itemTmpl" type="text/html">
<tr>
<td>
<div class="input-group cat-block" style="margin-left: 3px; margin-bottom: 12px;">
<label id="may-search-tags-lbl" style="background-color:beige;visibility:hidden;margin:0;">Category Name</label>
<input data-bind='value: Name' id="maynavsearchphrase" type="text" class="form-control"
placeholder="Category name" name="maynavsearchphrase"
value="" />
<div class="input-group-btn btn-grp-70 cat-meth-off">
<button id="may-nav-tags-search-btn" class="btn btn-default btnIcon may-tipped"
type="button" data-toggle="tooltip" title="Delete Category">
<i class="glyphicon glyphicon-remove"></i>
</button>
<button id="may-nav-search-search-btn" class="btn btn-default btnIcon may-tipped"
data-toggle="tooltip" title="Add subcategories"
data-bind='click: $root.addCategory'
type="button">
<i class="glyphicon glyphicon-expand"></i>
</button>
</div>
</div>
</td>
<td data-bind="visible: children().length">
<table>
<tbody data-bind="template: { name: 'itemTmpl', foreach: children }"></tbody>
</table>
</td>
</tr>
</script>
Callback function:
self.myPostProcessingLogic2 = function (elements) {
console.log(elements);
}
And then chrome dev tools console output:
What are the "text" elements in text, tr, text? There is no text element that is a sibling of tr. tbody can only contain tr's right?
If I drill into text I can see that it has an attribute of cells : HtmlCollection[2] both nodes of which are td. So it's almost like text = tr but if thats the case then why am I getting 3 sibling nodes to represent one row?
"What are the "text" elements in text, tr, text? There is no text element that is a sibling of tr..."
Everything in the DOM is represented by a node. Including plain text.
In your case, the text nodes are coming from the whitespace you have around your elements for formatting. That text is counted just like any other text.
<table>
<tbody>
<tr>
<td>foo</td>
</tr>
</tbody>
</table>
All that empty whitespace around the opening/closing tags gets represented as text nodes. This is true for all elements in the DOM, not just tables.
Table elements have special collections for you to use, which allow you to access just the table elements.
table.tBodies[] // to get the tbody elements of a table
table.rows[] // to get the rows of a table
tbody.rows[] // to get the rows of a tbody
row.cells[] // to get the cells of a row
Or you can use the generic .children to avoid text nodes.
tbody.children[]
The text nodes are the ones you write with "" inside your HTML.
Run this in your console, then scroll to the bottom, right-click and click inspect element:
document.body.appendChild(document.createTextNode("Some text node"))
Please print the value of #text in the console if it is node console.log(nodes.item(i).nodeValue)
This may occur due a space between the html element assign value.

Categories