parentNode is undefined for tr - javascript

When it reaches the line this.parentNode.removeChild(this);
I get the error
this.parentNode is undefined
In the debugger I pause at the beginning of that statement and see that "this" is: Object[ tr#CMD01.selected ] which is exactly what I expect. How is parentNode undefined? I have done a lot of searching for similar problems here and keep finding cases where "this" is not correct, but in my case it is verified by the debugger.
$(document).ready(function() {
$.fn.deleteThisRow = function() {
this.parentNode.removeChild(this);
};
});
function deleteRow() {
$("#theList tr.selected").deleteThisRow();
}
.selected {
background-color: yellow
}
<body>
<center id='bg'>
<table id="cmdList">
<thead>
<tr id="hdrow">
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody id="theList">
<tr id="CMD00">
<td>A1</td>
<td>A2</td>
<td>A3</td>
</tr>
<tr id="CMD01" class="selected">
<td>B1</td>
<td>B2</td>
<td>B3</td>
</tr>
<tr id="CMD02">
<td>C1</td>
<td>C2</td>
<td>C3</td>
</tr>
</tbody>
</table>
<table id="buttons">
<tr>
<td>
<button onclick='deleteRow()'>Delete</button>
</td>
</tr>
</table>
</center>
</body>

When you implement a jQuery method, the value of this when it is called will be the jQuery object, not the DOM object. So, this.parentNode does not exist because a jQuery object does not have a property by that name.
You can either use jQuery's .parent() or you can get the actual DOM node and then use .parentNode on that.
If you only intend on ever processing a single DOM object at a time, you can do this:
$.fn.deleteThisRow = function() {
this[0].parentNode.removeChild(this[0]);
};
If your jQuery object may have multiple objects in it, then you can do this:
$.fn.deleteThisRow = function() {
this.remove();
};
Or, as you may notice, you don't even need a custom method for this. If you have a jQuery object for the row, you can just call .remove() on it directly.
function deleteRow() {
$("#theList tr.selected").remove();
}

Related

Requesting text from a table row using jquery returns ''

I started using jQuery around a week ago and I wanted to make something like a search from an existing table.
When calling text() from any row it shows and empty string '' making it impossible to compare the searched string to the existing ones in the table.
For example, the following code returns 4 instances of ''. How can I fix this?
$(document).ready(() => {
$('#test tr').filter(() => {
console.log($(this).text());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<table>
<tbody id="test">
<tr>
<td>example</td>
<td>1</td>
</tr>
<tr>
<td>example</td>
<td>2</td>
</tr>
<tr>
<td>example</td>
<td>3</td>
</tr>
<tr>
<td>example</td>
<td>4</td>
</tr>
</tbody>
</table>
There's two problems in your code. Firstly you're using an arrow function so the this keyword will point to the outer context, not the tr element within the iteration. To fix this use an anonymous function, or receive the tr as the argument to the arrow function. I've done the latter in the example below.
The second issue is that you're using filter() as an iterator, which is not correct. filter() should be used to reduce a set of elements within a jQuery object. As you want to loop in this case, you should just use each() instead.
jQuery($ => {
$('#test tr').each((i, tr) => {
console.log($(tr).text().trim());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<table>
<tbody id="test">
<tr>
<td>example</td>
<td>1</td>
</tr>
<tr>
<td>example</td>
<td>2</td>
</tr>
<tr>
<td>example</td>
<td>3</td>
</tr>
<tr>
<td>example</td>
<td>4</td>
</tr>
</tbody>
</table>

How to set style after loading a value from localStorage?

I want to load a value from localStorage and then at page load set a style='display:none' or not on a table row.
One possibility I see is:
<script>
if(localStorage.getItem('test') == 'aja')
{
document.write('<tr style="display:none">');
}else{
document.write('<tr>');
}
</script>
but that doesn't seem to be a good solution as the editor doesn't recogize this and is then complaning about the missing
I could also hide it at after page load - but then it is visible for a split second before it is hidden - not ideal.
I am somewhat missing the possiblity to directly use variables in the html code itself. Like Razor / c# is doint it
#var hiddenOrNot = 'none';
<tr style="display:#hiddenOrNot">
but that is loaded on the server side, so no possibility to get the localStorage value...
Any suggestion? jquery or javascript
Thanks a lot
Something like this perhaps.
Select the row that needs to be removed if condition true
Create a class that contains style display:none
Add class to row if condition true
let tr = document.querySelector(".testRow");
let localStorageItem = localStorage.getItem("test") || "";
tr.classList.add((localStorageItem === 'aja') ? "hideRow" : null);
.hideRow {
display: none
}
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr class="testRow">
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
Edit: error on console here is due to StackOverFlow not allowing access to localStorage, should work fine on your system
You can try to set tr to display: none by default,and if localStorage.getItem('test') != 'aja' remove it.So that it will not be visible for a split second before it is hidden.Here is a demo:
view:
<table>
<thead>
<tr class="hidden">
<td>Id</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr class="hidden">
<td>1</td>
<td>Name1</td>
</tr>
<tr class="hidden">
<td>2</td>
<td>Name2</td>
</tr>
</tbody>
</table>
css:
<style>
.hidden {
display: none
}
</style>
js:
<script>
$(document).ready(function () {
if (localStorage.getItem('test') != 'aja') {
$("tr").removeClass();
}
});
</script>

Get row elements without using "closest" selector - jquery javascript

I have a table with 4 columns . 4th column is a button (not shown in below code). When I click on the button in a row, I want to get row elements.
I have done it using closest selector. Is there any way to find table row element "Without using closest". This is the requirement for some reason.
Please assume there is a button at end of each row
<table id="food">
<thead>
<tr>
<th>Number</th>
<th>Name</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr class='details'>
<td>1</td>
<td>Apple</td>
<td>Fruit</td>
</tr>
<tr class='details'>
<td>2</td>
<td>Mango</td>
<td>Fruit</td>
</tr>
<tr class='details'>
<td>3</td>
<td>Grape</td>
<td>Fruit</td>
</tr>
</tbody>
</table>
Here is the existing code, I need to replace closest. It will be awesome if I can use class names like $(this).somethin('.details');
$('#button1').click(function(){
var row = $(this).closest('tr');
//Do some stuff
})
Thanks
Use parents() and pass a class selector like
$('#button1').click(function(){
var row = $(this).parents('.details');
//Do some stuff
})
Note, you could also use closest in this case and pass the class selector
var row = $(this).closest('.details');

How delete a html table row using javascript?

I want to delete a row when i click the glyphicon-trash. I tried many ways but still cant get row index properly.
<table class="table table-bordered" id="table_GemList">
<thead>
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
</thead>
<tbody id="GemListBody">
<tr>
<td>Oval</td>
<td>Red</td>
<td>2.23</td>
<td><span class="glyphicon glyphicon-trash"></span></td>
</tr>
<tr>
<td>Box</td>
<td>Pink</td>
<td>2.23</td>
<td><span class="glyphicon glyphicon-trash"></span></td>
</tr>
</tbody>
</table>
---------- My code
$(document).on("click", ".glyphicon-trash", function () {
var d = $(this).parentNode.parentNode.rowIndex;
document.getElementById("table_GemList").deleteRow(d);
});
$(this) returns a jQuery object. You can't directly read the properties of the collection's items that way. In fact you shouldn't wrap the element with the jQuery constructor as you don't want to use the jQuery APIs.
var d = this.parentNode.parentNode.rowIndex;
Since you are using jQuery, you can simply use the closest and remove methods.
$(this).closest('tr').remove();
You need to update
var d = $(this).parentNode.parentNode.rowIndex;
document.getElementById("table_GemList").deleteRow(d);
to
$(this).closest("tr").remove();
For reference on closest() - https://api.jquery.com/closest/
For reference on remove() - https://api.jquery.com/remove/
Maybe this helps....
$(document).on("click", ".glyphicon-trash", function ()
{
$(this).closest("tr").remove(); // remove row
});
This should works.
$(document).on("click", ".glyphicon-trash", function () {
$(this).parents('tr:first').remove();
});
you can simply delete the parent in which trash icons is there by below jquery code
$(document).on("click", ".glyphicon-trash", function (){
$(this).parent().parent().remove(); // remove row
});

why the button inside a table cell which is clicked is undefined

I can't explain why ehn i click a button inside a table cell and try to get rowID - i see that its undefined
Here is my code
#model Onion.Web.ViewModels.CategoryViewModel
<script>
function btnEdit_Click()
{
var par = this.parentNode.parentNode;
alert(par.id);
}
</script>
<table>
<tr>
<td>ID</td>
<td>Title</td>
<td>Button</td>
</tr>
#foreach (var item in Model.lstCategoryLanguages)
{
<tr id='#item.CategoryLanguagesID'>
<td>#item.Title</td>
<td>#item.ShortDescription</td>
<td><input type="button" value="Edit" onclick='btnEdit_Click()' /></td>
</tr>
}
</table>
You need to pass the function the element you want to refer to, and then in the function use that.
This works for me:
<script>
function btnEdit_Click(elem)
{
var par = elem.parentNode.parentNode;
alert(par.id);
}
</script>
<table>
<tr>
<td>ID</td>
<td>Title</td>
<td>Button</td>
</tr>
#foreach (var item in Model.lstCategoryLanguages)
{
<tr id='#item.CategoryLanguagesID'>
<td>#item.Title</td>
<td>#item.ShortDescription</td>
<td><input type="button" value="Edit" onclick='btnEdit_Click(this)' /></td>
</tr>
}
</table>
I think this returns the wrong context there.
Try passing this in the onclick event and use the parameter instead in your function:
onclick='btnEdit_Click(this)'
I think it would be even better to bind #item.CategoryLanguagesID a second time and pass that the function to get rid of the static parentNode.parentNode reference. What if your structure changes over time? You'd always have to modify the function too.

Categories