Why is variable undefined when the function is called again - javascript

looks like a scope issue I can't get my head around not sure why the variable links is undefined when the function is called twice
<table class="list" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr class="headerRow">
<th scope="col" class="numericalColumn zen-deemphasize">Display Order</th>
<th scope="col" class=" zen-deemphasize">Message</th>
<th scope="col" class=" zen-deemphasize">Description</th>
<th scope="col" class=" zen-deemphasize">Media File Name</th>
<th scope="col" class="zen-deemphasize ">Location</th>
<th scope="col" class="zen-deemphasize ">Status</th>
<th scope="col" class=" zen-deemphasize">data</th>
</tr>
<tr class="dataRow">
<th scope="row" class="dataCell">
1
</th>
<td scope="row" class=" dataCell">
Homepage
<div class="mouseOverInfoOuter" tabindex="0">
</div>
</td>
<td class="dataCell">
Homepage
</td>
<td class="dataCell">
<a href="http://test.com/test/zip1" class="zipUrl">
test1.zip
</a>
</td>
<td scope="row" class="dataCell">
test1.zip
</td>
<td scope="row" class="dataCell">
Content Server
</td>
<td scope="row" class="dataCell">
Available for download
</td>
<td scope="row" class="dataCell">
File not available.
</td>
<td scope="row" class="dataCell">
</td>
<td class=" dataCell ">
</td>
</tr>
<tr class="dataRow">
<th scope="row" class="dataCell">
2
</th>
<td scope="row" class=" dataCell">
contact
<div class="mouseOverInfoOuter" tabindex="0"> </div>
</td>
<td class="dataCell">
contact
</td>
<td class="dataCell">
<a href="http://test.com/test/zip2" class="zipUrl">
test2.zip
</a>
</td>
<td scope="row" class="dataCell">
test2.zip
</td>
<td scope="row" class="dataCell">
Content Server
</td>
<td scope="row" class="dataCell">
Available for download
</td>
<td scope="row" class="dataCell">
File not available.
</td>
<td scope="row" class="dataCell">
</td>
<td class=" dataCell ">
</td>
</tr>
<tr class="dataRow">
<th scope="row" class="dataCell">
2
</th>
<td scope="row" class=" dataCell">
blog
<div class="mouseOverInfoOuter" tabindex="0"></div>
</td>
<td class="dataCell">
blog
</td>
<td class="dataCell">
<a href="http://test.com/test/zip3" class="zipUrl">
test3.zip
</a>
</td>
<td scope="row" class="dataCell">
test3.zip
</td>
<td scope="row" class="dataCell">
Content Server
</td>
<td scope="row" class="dataCell">
Available for download
</td>
<td scope="row" class="dataCell">
File not available.
</td>
<td scope="row" class="dataCell"></td>
<td class=" dataCell ">
</td>
</tr>
</tbody>
</table>
<script>
(function init() {
var tableRow = document.querySelectorAll('.dataRow');
var links = $('.dataCell:nth-child(4) .zipUrl');
if (tableRow.length === 0) return;
var index = 0;
function click() {
if (index < tableRow.length) {
//comment out line 14 to see console.log working normally
$(links[index++]).click();
console.log('Clicked on... ' + links[index++])
click();
}
}
click();
}());
</script>
Example
http://jsfiddle.net/Grundizer/6p60bkg9/
I'm trying to click on every link which is in the Media File Name column of the table, I don't have access to the source code to add or remove css classes, I have to work with the markup produced by the server.

Main problem was, index was incrementing two times one at $(links[index++]).click(); and another at console.log('Clicked on... ' + links[index++]); second time incrementation points at a null array element.
Do this->
$(window).load(function(){
var tableRow = document.querySelectorAll('.dataRow');
var links = $('.dataCell:nth-child(4) .zipUrl');
if (tableRow.length === 0) return;
var index = 0;
function click() {
if (index < tableRow.length) {
//comment out line 14 to see console.log working normally
$(links[index++]).click();
console.log('Clicked on... ' + links[index]);
click();
}
}
click();
}
);//]]>
by the way, there was some syntactical error, I fixed it in the solution code.

Related

How do I add enitre row of data of an table in an array of objects?

I'm trying to add entire row data of a table to my array of object whenever someone click on anchor tag named view/edit. I wrote some logic but I guess I'm missing something.
index.html file
<table class="table">
<thead>
<tr>
<th scope="col">User Name</th>
<th scope="col">Order No</th>
<th scope="col">Order Date</th>
<th scope="col">Status</th>
<th scope="col">Total Amount</th>
<th scope="col">Total Qty</th>
<th scope="col">Total Products</th>
<th scope="col">View/Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td id="user-name">Alice</td>
<td id="order-no">8536</td>
<td id="order-date">13/07/2020</td>
<td id="status" >Pending</td>
<td id="total-amount" >1800</td>
<td id="total-qty" >3</td>
<td id="total-products" >3</td>
<td>
<a id="view-data" href="#" class="text-success stretched-link">View/Edit</a>
</td>
</tr>
<tr>
<td id="user-name">Michael</td>
<td id="order-no">4354</td>
<td id="order-date">12/07/2020</td>
<td id="status" >Approved</td>
<td id="total-amount" >1500</td>
<td id="total-qty" >2</td>
<td id="total-products" >2</td>
<td>
<a id="view-data" href="#" class="text-success stretched-link">View/Edit</a>
</td>
</tr>
</tbody>
</table>
app.js file
let usersData = []; // array to store user table objects
$('#view-data').click(function(){
var row = $(this).closest("tr");
// userData object to store data from a table complete row
var userData = {
"order_no": row.find('#order-no').text(),
"order_date": row.find('#order-date').text(),
"totalproducts": row.find('#total-products').text(),
"total_amount": row.find('#total-amount').text(),
"total_qty": row.find('#total-qty').text(),
"status": row.find('#status').text(),
"user_name": row.find('#user-name').text(),
}
usersData.push(userData)
console.log(usersData)
})
Note: I should use button instead a tag but I'm using anchor tag because it'll open another tab in future for same data manipulation.
Selector need to change to class (view-data) instead of id
let usersData = []; // array to store user table objects
$('.view-data').click(function(ev){
ev.preventDefault();
ev.stopPropagation();
var row = $(ev.currentTarget).closest("tr");
// userData object to store data from a table complete row
var userData = {
"order_no": row.find('#order-no').text(),
"order_date": row.find('#order-date').text(),
"totalproducts": row.find('#total-products').text(),
"total_amount": row.find('#total-amount').text(),
"total_qty": row.find('#total-qty').text(),
"status": row.find('#status').text(),
"user_name": row.find('#user-name').text(),
}
usersData.push(userData)
console.log(userData)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">User Name</th>
<th scope="col">Order No</th>
<th scope="col">Order Date</th>
<th scope="col">Status</th>
<th scope="col">Total Amount</th>
<th scope="col">Total Qty</th>
<th scope="col">Total Products</th>
<th scope="col">View/Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td id="user-name">Alice</td>
<td id="order-no">8536</td>
<td id="order-date">13/07/2020</td>
<td id="status" >Pending</td>
<td id="total-amount" >1800</td>
<td id="total-qty" >3</td>
<td id="total-products" >3</td>
<td>
<a id="view-data" href="#" class="view-data text-success stretched-link">View/Edit</a>
</td>
</tr>
<tr>
<td id="user-name">Michael</td>
<td id="order-no">4354</td>
<td id="order-date">12/07/2020</td>
<td id="status" >Approved</td>
<td id="total-amount" >1500</td>
<td id="total-qty" >2</td>
<td id="total-products" >2</td>
<td>
<a id="view-data" href="#" class="view-data text-success stretched-link">View/Edit</a>
</td>
</tr>
</tbody>
</table>

Eliminate column from table using javascript

I need to automatically eliminate a column from a html table using javascript. The table is created automatically from a csv file using a framework so I can't modify it (ex. add an id, etc.). I managed to eliminate the column by adding a link to the column header, and on click it eliminates the column, but I can't find a way to do it automatically when the page loads. I'm new to javascript so please try to explain it for dummies.
function closestByTagName(el, tagName) {
while (el.tagName != tagName) {
el = el.parentNode;
if (!el) {
return null;
}
}
return el;
}
function delColumn(link) {
var idx = 2,
table = closestByTagName(link, "TABLE"),
rowCount = table.rows.length;
for (var i = 0; i < rowCount; i++) {
table.rows[i].deleteCell(idx);
}
return false;
}
window.onload = function() {
var th = document.querySelectorAll("th");
th[2].innerHTML += ' X';
}
<div class="table">
<table class="inline">
<tr class="row0">
<th class="col0">FullName</th>
<th class="col1">Country</th>
<th class="col2">Position</th>
<th class="col3">CellPhone</th>
<th class="col4">Email</th>
</tr>
<tr class="row1">
<td class="col0">magnus</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">22</td>
<td class="col4">magnus.gaylord#example.com</td>
</tr>
<tr class="row2">
<td class="col0">Phoebe Feest</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">23</td>
<td class="col4">ylittel#example.net</td>
</tr>
<tr class="row3">
<td class="col0">Prof. Tad Johnston</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">24</td>
<td class="col4">srau#example.org</td>
</tr>
<tr class="row4">
<td class="col0">Annabelle Ortiz</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">25</td>
<td class="col4">damore.walker#example.org</td>
</tr>
<tr class="row5">
<td class="col0">Mrs. Adella Schiller IV</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">26</td>
<td class="col4">jadyn.dibbert#example.com</td>
</tr>
</table>
</div>
The above code works but I have to press the x on the position column for it to be eliminated and I need it to happen automatically. In other words I don't want to use the code href="#" onclick="return delColumn(this)" but have it happen on load.
Since all your columns have a particular class, maybe one possible solution using ES6 is to use:
document.querySelectorAll(".col2").forEach(col => col.remove());
Or with a standard approach:
var cols = document.querySelectorAll(".col2");
for (var i = 0; i < cols.length; i++)
{
cols[i].remove();
}
Example:
window.onload = function()
{
var cols = document.querySelectorAll(".col2");
for (var i = 0; i < cols.length; i++)
{
cols[i].remove();
}
// Or with ES6:
//document.querySelectorAll(".col2").forEach(col => col.remove());
}
<div class="table">
<table class="inline">
<tr class="row0">
<th class="col0">FullName</th>
<th class="col1">Country</th>
<th class="col2">Position</th>
<th class="col3">CellPhone</th>
<th class="col4">Email</th>
</tr>
<tr class="row1">
<td class="col0">magnus</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">22</td>
<td class="col4">magnus.gaylord#example.com</td>
</tr>
<tr class="row2">
<td class="col0">Phoebe Feest</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">23</td>
<td class="col4">ylittel#example.net</td>
</tr>
<tr class="row3">
<td class="col0">Prof. Tad Johnston</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">24</td>
<td class="col4">srau#example.org</td>
</tr>
<tr class="row4">
<td class="col0">Annabelle Ortiz</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">25</td>
<td class="col4">damore.walker#example.org</td>
</tr>
<tr class="row5">
<td class="col0">Mrs. Adella Schiller IV</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">26</td>
<td class="col4">jadyn.dibbert#example.com</td>
</tr>
</table>
</div>
Shidersz's answer is fine, but it's also worth noting that you could do with with a single CSS rule instead of JavaScript:
.col2 {
display: none;
}
<div class="table">
<table class="inline">
<tr class="row0">
<th class="col0">FullName</th>
<th class="col1">Country</th>
<th class="col2">Position</th>
<th class="col3">CellPhone</th>
<th class="col4">Email</th>
</tr>
<tr class="row1">
<td class="col0">magnus</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">22</td>
<td class="col4">magnus.gaylord#example.com</td>
</tr>
<tr class="row2">
<td class="col0">Phoebe Feest</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">23</td>
<td class="col4">ylittel#example.net</td>
</tr>
<tr class="row3">
<td class="col0">Prof. Tad Johnston</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">24</td>
<td class="col4">srau#example.org</td>
</tr>
<tr class="row4">
<td class="col0">Annabelle Ortiz</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">25</td>
<td class="col4">damore.walker#example.org</td>
</tr>
<tr class="row5">
<td class="col0">Mrs. Adella Schiller IV</td>
<td class="col1">Guatemala</td>
<td class="col2">Lacayo</td>
<td class="col3">26</td>
<td class="col4">jadyn.dibbert#example.com</td>
</tr>
</table>
</div>

Javascript Select anchors with attributes that contain word

I am trying to only select a specific set of links in a table. I figure that the best way to do it is by selecting them by the title attribute that contains all contain the word 'ULD'.
Here is my code the allowed me to narrow it down to all links in a table but no further. I tried querySelectorAll() and selectElementsbyTitle but had no luck. Also keep in mind this needs to work in IE11 and no JQuery.
var tabl = document.getElementById("Func15543_tblMissedBagReport");var anchors = tabl.getElementsByTagName("a");
Here are the links I want to select out of the following table:
<A
CLASS="ESR-Ajax"
TITLE="View ULD B1769SELAZ5 detail"
HREF="Javascript:void(0)"
AJAX-FUNCTION="Shared_ULDDetail"
intMasterReferenceNumber="5433550294352748012"
intULDReferenceNumber="-5893118207572745590"
strULDTypeCode="01"
dtmReportDate="2018-12-14"
intPageNumber="1">
B1769SELAZ5
</A>
Here is a sample of the table:
Missed Bag Report
<img src="../Content/images/icons/excel.gif" border="0" alt="Click to export to excel." title="Click to export to excel." height="13" width="13">
</a>
</SPAN>
<SPAN CLASS="CaptionRight">
<SPAN ID="Func15543_PagingControlOne"></SPAN>
</SPAN>
</CAPTION>
<THEAD>
<TR>
<TH ROWSPAN="2">#</TH>
<TH COLSPAN="5">Destination</TH>
<TH ROWSPAN="2">Load<BR>Create<BR>Sort</TH>
<TH ROWSPAN="2">Bag Close Time</TH>
<TH ROWSPAN="2">Age > 90 min (Red)</TH>
<TH ROWSPAN="2">Bag Tag #</TH>
<TH ROWSPAN="2">Pkgs<BR>in<BR>Bag</TH>
</TR>
<TR>
<TH>Cntry<BR>Code</TH>
<TH>SLIC</TH>
<TH>Sort</TH>
<TH>Serv Lvl</TH>
<TH>Location</TH>
</TR>
</THEAD>
<TBODY>
<TR>
<TD CLASS="CenterText ">1</TD>
<TD CLASS="CenterText ">US</TD>
<TD CLASS="CenterText ">4009 </TD>
<TD CLASS="CenterText ">D</TD>
<TD CLASS="CenterText ">2DA</TD>
<TD CLASS="CenterText ">GRADE LANE HUB </TD>
<TD CLASS="CenterText ">T</TD>
<TD CLASS="CenterText ">
12/14/18 4:12 PM
</TD>
<TD CLASS="WhiteText CenterText G_CLR_Green5 ">
56 Mins. Old
</TD>
<TD CLASS="CenterText ">
<A
CLASS="ESR-Ajax"
TITLE="View ULD B1769SELAZ5 detail"
HREF="Javascript:void(0)"
AJAX-FUNCTION="Shared_ULDDetail"
intMasterReferenceNumber="5433550294352748012"
intULDReferenceNumber="-5893118207572745590"
strULDTypeCode="01"
dtmReportDate="2018-12-14"
intPageNumber="1">
B1769SELAZ5
</A>
</TD>
<TD class="CenterText "> 6</TD>
</TR>
<TR>
<TD CLASS="CenterText G_CLR_6">2</TD>
<TD CLASS="CenterText G_CLR_6">US</TD>
<TD CLASS="CenterText G_CLR_6">0759 </TD>
<TD CLASS="CenterText G_CLR_6">N</TD>
<TD CLASS="CenterText G_CLR_6">GRD</TD>
<TD CLASS="CenterText G_CLR_6">SADDLEBROOK </TD>
<TD CLASS="CenterText G_CLR_6">T</TD>
<TD CLASS="CenterText G_CLR_6">
12/14/18 4:15 PM
</TD>
<TD CLASS="WhiteText CenterText G_CLR_Green5">
53 Mins. Old
</TD>
<TD CLASS="CenterText G_CLR_6">
<A
CLASS="ESR-Ajax"
TITLE="View ULD B1769SEL3I0 detail"
HREF="Javascript:void(0)"
AJAX-FUNCTION="Shared_ULDDetail"
intMasterReferenceNumber="5433550294352748012"
intULDReferenceNumber="8922482455613715109"
strULDTypeCode="01"
dtmReportDate="2018-12-14"
intPageNumber="1">
B1769SEL3I0
</A>
</TD>
<TD class="CenterText G_CLR_6"> 6</TD>
</TR>
You can use querySelectorAll with an attribute selector [attr] and a contains flag *=:
var table = document.querySelector('table');
var links = table.querySelectorAll('a[title*="ULD"]');
console.log(links);
<table>
<tr>
<td>One</td>
<td>Two</td>
<td>Three</td>
</tr>
</table>

How to get back deleted rows from datatable

I'm using datatable and deleting multiple rows on the click of button now I'm trying to get back deleted rows from the datatable, below are the code I have written to reset the table but its not working, kindly help on this.
<html>
<head>
<script>
$(document).ready(function() {
var table = $('#scmJobs').DataTable({
"paging": false,
"bFilter": false,
"info": false
});
$('#scmJobs tbody').on( 'click', 'tr', function () {
$(this).toggleClass('selected');
} );
$('#deleteButton').click( function () {
// alert( table.rows('.selected').data().length +' row(s) selected' );
table.rows('.selected').cache();
table.rows('.selected').remove().draw( false );
} );
$('#resetButton').click( function () {
$.fn.dataTable.ext.search.pop();
table.draw();
} );
} );
</script>
</head>
<body>
<input type="button" id="deleteButton" value="Delete"/>
<input type="button" id="resetButton" value="Reset"/>
<table id="scmJobs" border="0" cellspacing="0" cellpadding="0"
class="grid" width="100%">
<thead>
<tr style="background-color: silver;" >
<th style="text-align:left;" width="183px" >Attribute</th>
<th width="76px">DQ</th>
<th width="76px">QTY</th>
<th width="77px"> DQ</th>
<th width="77px">QTY </th>
<th width="77px">DQ</th>
<th width="77px">QTY</th>
<th width="77px">DQ</th>
<th width="77px">QTY</th>
<th width="77px">DQ</th>
<th width="77px">QTY</th>
<th width="74px">DQ</th>
<th width="74px" >QTY </th>
</tr>
</thead>
<tbody>
<tr data-user="End of new attach date">
<td style="text-align:left;">End of new attach date</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
</tr>
<tr data-user="Contract bill-to">
<td style="text-align:left;">Contract bill-to</td>
<td style="text-align:right;">0.999907</td>
<td style="text-align:right;">89139</td>
<td style="text-align:right;">0.999907</td>
<td style="text-align:right;">89139</td>
<td style="text-align:right;">0.999907</td>
<td style="text-align:right;">89139</td>
<td style="text-align:right;">0.999907</td>
<td style="text-align:right;">89139</td>
<td style="text-align:right;">0.999907</td>
<td style="text-align:right;">89139</td>
<td style="text-align:right;">0.9999072</td>
<td style="text-align:right;">89139</td>
</tr>
<tr>
<td style="text-align:left;">Configuration</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
<td style="text-align:right;">100.000</td>
<td style="text-align:right;">9000000000</td>
</tr>
</tbody>
</table>
</body>
</html>
From DataTables row().remove() API: "This method (and its plural counterpart, rows().remove()) will remove the selected row from the DataTable completely, deleting the allocated memory for data and node from the browser."
Solution A) Refresh the page on reset and make sure the server serves up the original version.
Solution B) Create a Recycle Bin array or a hidden table and move the rows there instead of remove(). Then on $('#resetButton').click() move them or add them back. Make sure to clear the recycle bin when reset is clicked.

Value of selector is undefined in a loop

<table class="list" border="0" cellspacing="0" cellpadding="0">
<tr class="dataRow">
<td scope="row" class="dataCell">
1
</td>
<td scope="row" class="dataCell">
2
</td>
<td scope="row" class="dataCell">
3
</td>
<td scope="row" class="dataCell">
Homepage
</td>
</tr>
<tr class="dataRow">
<td scope="row" class="dataCell">
1
</td>
<td scope="row" class="dataCell">
2
</td>
<td scope="row" class="dataCell">
3
</td>
<td scope="row" class="dataCell">
Blog
</td>
</tr>
<tr class="dataRow">
<td scope="row" class="dataCell">
1
</td>
<td scope="row" class="dataCell">
2
</td>
<td scope="row" class="dataCell">
3
</td>
<td scope="row" class="dataCell">
Contact
</td>
</tr>
</table>
var tableRow = document.querySelectorAll('.dataRow');
var links = $('.dataCell:nth-child(4) .ng-binding');
for(var i=0; i<tableRow.length; i++){
console.log(links[i]);
}
don't understand why the value of links is undefined
I've tried having the links variable created inside the loop as well but I get the same result - I think its because links is not an array? if thats the case how would I do that?
I've added the markup to explain my question better...I'm trying to get links from the table cell and do a .click() on them
This is the jQuery solution, but if that is a angular app you should use directives
var links = $('.dataCell:nth-child(4) .ng-binding');
This object length will be 0. See how nth-child works https://api.jquery.com/nth-child-selector/
I guess you want to click on last links in each cell.
var dataRow = $('.dataRow');
dataRow.each(function(ind, elem){
console.log($(this).find('.ng-binding').eq(3));
$(this).find('.ng-binding').eq(3).click();
});

Categories

Resources